未从实时 ETW 消费者接收 Microsoft-Windows-Kernel-Process 事件
Posted
技术标签:
【中文标题】未从实时 ETW 消费者接收 Microsoft-Windows-Kernel-Process 事件【英文标题】:not receiving Microsoft-Windows-Kernel-Process events from real time ETW consumer 【发布时间】:2020-07-26 13:23:21 【问题描述】:我正在尝试使用 Windows 事件跟踪 (ETW) 构建一个使用者,它将接收来自 Microsoft-Windows-Kernel-Process 的事件。消费者启动,ProcessTrace 没有错误。我可以在“logman query -ets”的结果中看到我的会话名称。但是,我的事件回调函数永远不会被调用。我无法弄清楚为什么我没有看到任何事件。我以管理员身份运行我的应用程序。任何人都可以在我的代码中看到问题吗?谢谢...
注意:我尝试只将事件写入文件...我的事件回调被调用了两次,BufferCallback 被调用了一次,在生成的 etl 文件中,我得到了一个错误代码为 15003 的事件,即 ERROR_EVT_EVENT_TEMPLATE_NOT_FOUND(在资源中找不到事件定义的模板(错误 = %1)。)我不确定这意味着什么。我不认为消费者需要对清单做任何事情。
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <strsafe.h>
#include <wbemidl.h>
#include <wmistr.h>
#include <evntrace.h>
#include <Evntcons.h>
using namespace std;
#pragma comment(lib, "Advapi32.lib")
#define LOGSESSION_GUID "b2bcc945-9eb9-4231-883c-d6455cf4d86b"
#define LOGSESSION_NAME L"Testing ETW Consumer"
static const GUID SessionGuid =
0xb2bcc945, 0x9eb9, 0x4231, 0x88, 0x3c, 0xd6, 0x45, 0x5c, 0xf4, 0xd8, 0x6b ;
TRACEHANDLE sessionHandle;
TRACEHANDLE traceHandle;
GUID guid;
int bufferSize = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(LOGSESSION_NAME) + sizeof(WCHAR);
auto pSessionProperties = static_cast<PEVENT_TRACE_PROPERTIES>(malloc(bufferSize));
// Microsoft-Windows-Kernel-Process
// 22FB2CD6-0E7B-422B-A0C7-2FAD1FD0E716
static const GUID MSKRNL_PROVIDER_GUID =
0x22fb2cd6, 0x0e7b, 0x422b, 0xa0, 0xc7, 0x2f, 0xad, 0x1f, 0xd0, 0xe7, 0x16 ;
VOID WINAPI EventRecordCallback(EVENT_RECORD* pEventRecord)
fprintf(stdout, "Event Record Received\n");
return;
ULONG WINAPI BufferCallback(EVENT_TRACE_LOGFILE* pLogFile)
fprintf(stdout, "in BufferCallback...\n");
return TRUE;
static DWORD WINAPI Win32TracingThread(LPVOID Parameter)
fprintf(stdout, "processing trace...\n");
auto ptStatus = ProcessTrace(&traceHandle, 1, NULL, NULL);
if (ptStatus != ERROR_SUCCESS && ptStatus != ERROR_CANCELLED)
wprintf(L"ProcessTrace exit status: %lu\n", ptStatus);
return(0);
int main(void)
fprintf(stdout, "entering main program...\n");
// Set the session properties. You only append the log file name
// to the properties structure; the StartTrace function appends
// the session name for you.
ZeroMemory(pSessionProperties, bufferSize);
pSessionProperties->Wnode.BufferSize = bufferSize;
pSessionProperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
pSessionProperties->Wnode.ClientContext = 1; //QPC clock resolution
pSessionProperties->Wnode.Guid = SessionGuid;
pSessionProperties->FlushTimer = 0;
pSessionProperties->EnableFlags = EVENT_TRACE_FLAG_PROCESS | EVENT_TRACE_FLAG_PROCESS_COUNTERS;
pSessionProperties->LogFileMode = EVENT_TRACE_REAL_TIME_MODE;
pSessionProperties->LogFileNameOffset = 0;
pSessionProperties->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
StringCbCopy((STRSAFE_LPWSTR)((char*)pSessionProperties + pSessionProperties->LoggerNameOffset), sizeof(LOGSESSION_NAME), LOGSESSION_NAME);
// stop any previous session
auto stopStatus = ControlTrace(0, LOGSESSION_NAME, pSessionProperties, EVENT_TRACE_CONTROL_STOP);
fprintf(stdout, "starting trace...\n");
auto sTrStatus = StartTrace(static_cast<PTRACEHANDLE>(&sessionHandle), LOGSESSION_NAME, pSessionProperties);
fprintf(stdout, "enabling trace...\n");
auto eTrExstatus = EnableTraceEx2(sessionHandle, &MSKRNL_PROVIDER_GUID, EVENT_CONTROL_CODE_ENABLE_PROVIDER, TRACE_LEVEL_VERBOSE, 1, 0, 0, nullptr);
EVENT_TRACE_LOGFILE loggerInfo = 0;
loggerInfo.ProcessTraceMode = EVENT_TRACE_REAL_TIME_MODE | PROCESS_TRACE_MODE_EVENT_RECORD;
loggerInfo.BufferCallback = BufferCallback;
// provide a callback whenever we get an event record
loggerInfo.EventRecordCallback = (PEVENT_RECORD_CALLBACK) EventRecordCallback;
loggerInfo.Context = nullptr;
// LoggerName is the sessionName that we had provided in StartTrace
// For consuming events from ETL file we will provide path to ETL file.
loggerInfo.LoggerName = LOGSESSION_NAME;
loggerInfo.LogFileName = NULL;
loggerInfo.LogFileMode = EVENT_TRACE_REAL_TIME_MODE;
fprintf(stdout, "opening trace...\n");
traceHandle = OpenTrace(&loggerInfo);
// calling thread will be blocked until BufferCallback returns FALSE or all events are delivered or CloseTrace is called
DWORD ThreadID;
HANDLE ThreadHandle = CreateThread(0, 0, Win32TracingThread, 0, 0, &ThreadID);
bool exit2 = false;
while (exit2 == false)
if (GetAsyncKeyState(VK_ESCAPE))
exit2 = true;
fprintf(stdout, "escape pressed, exiting loop...\n");
CloseHandle(ThreadHandle);
if ((TRACEHANDLE)INVALID_HANDLE_VALUE != traceHandle)
fprintf(stdout, "in cleanup...\n");
fprintf(stdout, "closing trace...\n");
auto ctStatus = CloseTrace(traceHandle);
auto cTrStatus = ControlTrace(sessionHandle, nullptr, pSessionProperties, EVENT_TRACE_CONTROL_STOP);
auto eTrStatus = EnableTraceEx2(sessionHandle, &MSKRNL_PROVIDER_GUID, EVENT_CONTROL_CODE_DISABLE_PROVIDER, 0, 0, 0, 0, nullptr);
free(pSessionProperties);
【问题讨论】:
【参考方案1】:我自己可能已经想出了很多...这就是我改变的...
首先,我必须在所有包含语句之前包含“#define INITGUID”,我没有意识到需要这样......
然后,对于会话属性和记录器属性中的 logfilemode,我将它们设置为此...
EVENT_TRACE_REAL_TIME_MODE | EVENT_TRACE_SYSTEM_LOGGER_MODE
我现在将事件返回给我的回调,现在我需要解析它们并找出其中的内容...
【讨论】:
以上是关于未从实时 ETW 消费者接收 Microsoft-Windows-Kernel-Process 事件的主要内容,如果未能解决你的问题,请参考以下文章
如何为 TraceLogging 提供者(内核)创建实时 etw 消费者?