我试图确定EVENTLOGRECORD数据的可变长度部分是如何工作的,但收效甚微。

Winnt.h定义结构和以下数据,如下所示:

typedef struct _EVENTLOGRECORD {
DWORD  Length;        // Length of full record
DWORD  Reserved;      // Used by the service
DWORD  RecordNumber;  // Absolute record number
DWORD  TimeGenerated; // Seconds since 1-1-1970
DWORD  TimeWritten;   // Seconds since 1-1-1970
DWORD  EventID;
WORD   EventType;
WORD   NumStrings;
WORD   EventCategory;
WORD   ReservedFlags; // For use with paired events (auditing)
DWORD  ClosingRecordNumber; // For use with paired events (auditing)
DWORD  StringOffset;  // Offset from beginning of record
DWORD  UserSidLength;
DWORD  UserSidOffset;
DWORD  DataLength;
DWORD  DataOffset;    // Offset from beginning of record
//
// Then follow:
//
// WCHAR SourceName[]
// WCHAR Computername[]
// SID   UserSid
// WCHAR Strings[]
// BYTE  Data[]
// CHAR  Pad[]
// DWORD Length;

    //
} EVENTLOGRECORD, *PEVENTLOGRECORD;

我可以使用以下代码提取似乎是源代码的第一个块,但肯定不是预期的方法:
memcpy(&strings, pRecord+sizeof(EVENTLOGRECORD), tmpLog->UserSidOffset);

但是从Winnt.h中的注释中,我也得到了计算机名称。

因此,有人可以说明如何从EVENTLOGRECORD结构确定“SourceName”长度,并说明StringOffset,DataLength和DataOffset是什么吗?

谢谢。

最佳答案



从我的看到,SourceName[]Computername[]彼此后面,由'\0'隔开,第一个开始在DataOffset之后,第二个开始在第一个'\0'之后,并且在UserSidOffset之前最多两个字节,用'\0'尾随。



我找不到的StringLength(而StringOffsetStrings[]的起始位置),DataLengthData[]中的字节数,而DataOffsetData[]的起始位置。

要读取字符串,您可以执行以下操作:

// Beware, brain-compiled code ahead!
void f(EVENTLOGRECORD* rec)
{
  std::wstring source_name(
    reinterpret_cast<const wchar_t*>(
      reinterpret_cast<const unsigned char*>( rec
                                            + sizeof(EVENTLOGRECORD ) ) ) );
  std::wstring computer_name(
    reinterpret_cast<const wchar_t*>(
      reinterpret_cast<const unsigned char*>( rec
                                            + sizeof(EVENTLOGRECORD )
                                            + source_name.length()+1 ) ) );
  // ...
}

09-27 17:29