我试图确定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;
Run Code Online (Sandbox Code Playgroud)
我可以使用以下代码拉出第一个看起来像源代码的块,但它肯定不是预期的方法:
memcpy(&strings, pRecord+sizeof(EVENTLOGRECORD), tmpLog->UserSidOffset);
Run Code Online (Sandbox Code Playgroud)
但是从Winnt.h中的评论中,我也得到了计算机名称.
那么有人可以解释如何从EVENTLOGRECORD结构中确定"SourceName"长度,并解释StringOffset,DataLength和DataOffset是什么?
谢谢.
注意:在整个答案中,我会假设您有一个指向该结构的指针,如下所示:
EVENTLOGRECORD * elr;
Run Code Online (Sandbox Code Playgroud)
缩短代码片段.
那么有人可以解释如何从EVENTLOGRECORD结构中确定"SourceName"长度
没有字段指定它的长度,但您可以很容易地确定它:它是明确定义的字段之后的记录的第一个字段,因此您可以简单地执行:
WCHAR * SourceName=(WCHAR *)((unsigned char *)elr + sizeof(*elr));
Run Code Online (Sandbox Code Playgroud)
现在,SourceName你有一个指向该字符串的指针; 您可以使用常用的字符串函数轻松确定其长度.
顺便说一句,在终结器之后SourceName应该有ComputerName字符串.
并解释一下StringLength
没有StringLength会员,你在说什么?
DataLength和DataOffset是?
事件日志也由嵌入在记录中的任意二进制数据组成.
该DataOffset成员指定从记录的开始偏移这样的数据,并DataLength指定有多长数据.如果您要将该数据复制到缓冲区(假设它足够大),您可以:
memcpy(targetBuffer,(unsigned char *)elr + elr->DataOffset,elr->DataLength);
Run Code Online (Sandbox Code Playgroud)
顺便说一下,您应该阅读文档,而不是直接阅读包含文件,它更容易理解.
StringOffset该StringOffset字段指定与记录开头的事件关联的字符串的偏移量.
该StringOffset字段与上述DataOffset字段非常相似,但没有相应的StringLength字段,因为每个字符串的长度可以使用普通的字符串函数轻松确定(实际上字符串部分只是由几个NUL终止的字符串组成一个后面的字符串其他).
此外,可以容易地确定检查该DataOffset成员的字符串部分结束的位置,事实上,字符串部分在数据块开始处结束.该EVENTLOGRECORD结构还提供了NumStrings字段来确定字符串部分中包含的字符串数量(感谢Remy Lebeau).
如果你把这些字符串放在一个vector<wstring>你做这样的事情(仔细的,未经测试的代码):
vector<wstring> strings;
for(
wchar_t * ptr=(wchar_t *)((unsigned char *)elr + elr->StringOffset);
strings.size()<elr->NumStrings;
ptr+=strings.back().length() + 1
)
strings.push_back(wstring(ptr));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1504 次 |
| 最近记录: |