我试图确定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
(而StringOffset
是Strings[]
的起始位置),DataLength
是Data[]
中的字节数,而DataOffset
是Data[]
的起始位置。
要读取字符串,您可以执行以下操作:
// 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 ) ) );
// ...
}