VC++实时ETW消费者:如何从PEVENT_RECORD的UserData获取文件名?
从PEVENT_RECORD的UserData获取文件名的实现方法
完全可以从PEVENT_RECORD的UserData字段提取文件名,ETW的Microsoft-Windows-Kernel-File事件会把文件操作的详细数据(包括文件名)封装在UserData中。具体实现需要以下步骤:
1. 确定目标事件ID
Microsoft-Windows-Kernel-File包含多个文件操作事件,常用的有:
- 文件创建:EventID 256 (
FileCreate) - 文件打开:EventID 257 (
FileOpen) - 文件关闭:EventID 261 (
FileClose)
不同事件的UserData结构略有差异,但核心的文件名字段逻辑一致。
2. 声明对应事件的结构体
根据微软公开的ETW事件定义,以FileCreate(EventID 256)为例,对应的UserData结构体可按如下声明:
// 对应FileCreate事件的UserData结构体 typedef struct _FILE_CREATE_DATA { UINT32 FileNameLength; // 文件名的字节长度(宽字符,所以实际字符数是长度/2) UINT32 FileNameOffset; // 相对于UserData起始地址的偏移量,指向文件名起始位置 // 其他可选字段:FileAttributes、CreationTime、FileSize等,可按需添加 } FILE_CREATE_DATA, *PFILE_CREATE_DATA;
3. 在ProcessEvent中解析UserData
在你的ProcessEvent函数中,先判断事件ID,再将UserData转换为对应结构体,最后通过EventRecordGetString安全提取文件名(避免直接指针访问的内存风险):
#include <Evntcons.h> VOID WINAPI ProcessEvent(PEVENT_RECORD pEvent) { wprintf(L"ProcessEvent: processID: %d\n", pEvent->EventHeader.ProcessId); // 处理FileCreate事件(EventID 256) if (pEvent->EventHeader.EventDescriptor.Id == 256) { PFILE_CREATE_DATA pData = (PFILE_CREATE_DATA)pEvent->UserData; PWSTR pFileName = NULL; // 调用API提取文件名 if (EventRecordGetString(pEvent, pData->FileNameOffset, pData->FileNameLength, NULL, &pFileName) == ERROR_SUCCESS) { wprintf(L"File Created: %s\n", pFileName); // 释放API分配的内存 LocalFree(pFileName); } } // 扩展处理FileOpen事件(EventID 257) else if (pEvent->EventHeader.EventDescriptor.Id == 257) { typedef struct _FILE_OPEN_DATA { UINT32 FileNameLength; UINT32 FileNameOffset; // 其他字段如OpenOptions等可按需添加 } FILE_OPEN_DATA, *PFILE_OPEN_DATA; PFILE_OPEN_DATA pOpenData = (PFILE_OPEN_DATA)pEvent->UserData; PWSTR pFileName = NULL; if (EventRecordGetString(pEvent, pOpenData->FileNameOffset, pOpenData->FileNameLength, NULL, &pFileName) == ERROR_SUCCESS) { wprintf(L"File Opened: %s\n", pFileName); LocalFree(pFileName); } } }
关键注意事项
- 不同事件ID的
UserData结构体字段可能存在差异,需对照微软官方ETW事件定义调整结构体声明。 - 必须保证结构体的内存对齐与ETW事件数据结构一致,否则会出现解析错误。
- 优先使用
EventRecordGetString而非直接指针访问,因为ETW事件可能包含可变长度字段,该函数会自动处理内存偏移和字符串提取逻辑。
内容的提问来源于stack exchange,提问作者user846940
相关产品推荐
相关产品推荐

