Windows ETW: StartTrace failing with error 87 (ERROR_INVALID_PARAMETER)

不打扰是莪最后的温柔 提交于 2019-12-06 09:01:55

Oh i see what the comments from Luke's comments are saying.

It's not that the structure is misaligned is any way. The content after the structure must be 8-byte aligned. In other words:

000| Wnode.BufferSize:          9A 00 00 00 (154)
004| Wnode.ProviderID:          00 00 00 00
     ...snip...
108| LogFileNameOffset:   85 00 00 00 (133)
112| LoggerNameOffset:    74 00 00 00 (116)
116| 00 00 00 00 (4 bytes padding)
120| NT Kernel Logger\0
136| 00 00 00 00 00 00 00 (7 bytes padding)
144| C:\Users\Ian\foo.etl\0

Looks like data needs to be aligned on 8-byte boundries in Windows (7 (Professional (64-bit)))

To help the padding, i wrote a Pad function, which rounds a number up to the nearest multiple of 8:

function Pad(length: Cardinal): Cardinal;
var
    m: Integer;
const
    DataAlignment = 8; //align data on 8-byte boundaries
begin
    Result := length;

    m := length mod DataAlignment;
    if (m > 0) then
        Result := result + DataAlignment-m;
end;

Then i changed some of the code from the original question to use it.

  • calculate the total buffserSize required:

    loggerName := KERNEL_LOGGER_NAME;
    logFilePath := 'C:\Users\Ian\foo.etl';
    
    bufferSize := sizeof(EVENT_TRACE_PROPERTIES)
            + Pad(Length(loggerName)+1)
            + Pad(Length(logFilePath)+1);
    
  • then i need to push my offsets on an 8-byte boundary:

    sessionProperties.LoggerNameOffset := Pad(sizeof(EVENT_TRACE_PROPERTIES));
    sessionProperties.LogFileNameOffset := Pad(sizeof(EVENT_TRACE_PROPERTIES)) + Pad(Length(loggerName)+1);
    
  • and as long as i copy the strings to the offsets declared in the structure i'm fine:

    //Copy LoggerName to the offset address
    MoveMemory(
          Pointer(Cardinal(sessionProperties)+sessionProperties.LoggerNameOffset),
          PAnsiChar(loggerName), Length(loggerName)+1);
    
    //Copy LogFilePath to the offset address
    MoveMemory(
          Pointer(Cardinal(sessionProperties)+sessionProperties.LogFileNameOffset),
          PAnsiChar(logFilePath), Length(logFilePath)+1);
    

And blingo-blango, it works.

Note: Any code is released into the public domain. No attribution required.

Not an answer, but something interesting I found: If you replace the line:

hr := EventTrace.StartTrace({var}th, PChar(loggerName), sessionProperties);

with

hr := EventTrace.StartTrace({var}th, KERNEL_LOGGER_NAME, sessionProperties);

then the error code becomes ERROR_BAD_LENGTH (24). I think I'm using a different set of units for the trace APIs, and in my case, StartTrace wants a PWideChar, but loggerName is an AnsiString. Since I don't know your EventTrace unit looks like, it's hard to say if this is also the case for you or not though. And regardless, it does not make the StartTrace() call succeed.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!