如何从Microsoft-Windows-NDIS-PacketCapture提供程序中消费实时ETW事件?

11
较大的问题是如何在一般情况下消耗实时ETW网络堆栈事件,但我特别关注Microsoft-Windows-NDIS-PacketCapture提供程序。所有其他网络堆栈提供程序部分工作,但NDIS-PacketCapture (NDIS-PC)根本不起作用,所以这可能是我可以在这里问的最简单的问题。
我使用以下代码作为基础,并进行了非常少量的修改,使其能够实时工作: http://msdn.microsoft.com/en-us/library/windows/desktop/ee441325(v=vs.85).aspx 我所做的更改是:
  1. 在执行任何其他操作之前,调用StartTrace来启动NDIS-PC会话。在属性结构EVENT_TRACE_PROPERTIES中,设置LogFileMode = EVENT_TRACE_REAL_TIME_MODE,LogFileModeOffset = 0,并将Wnode.Guid设置为我随意编造的某个GUID。

  2. 调用EnableTraceEx2(hSession, &Current_Guid, EVENT_CONTROL_CODE_ENABLE_PROVIDER, TRACE_LEVEL_VERBOSE, 0, 0, 0, NULL); 其中hSession是使用StartTrace启动的会话,Current_Guid是{0x2ED6006E,0x4729,0x4609,{0xB4,0x23,0x3E,0xE7,0xBC,0xD6,0x78,0xEF}};

  3. 然后使用LoggerName =一些宽字符串、LogFileName = NULL和LogFileMode = EVENT_TRACE_REAL_TIME_MODE调用OpenTrace;

  4. 最后对刚刚打开的跟踪句柄调用ProcessTrace。

  5. 同样,保留MSDN示例中提供的其他所有内容。

使用相同的代码,只需将提供程序更改为其他任何东西,例如Microsoft-Windows-Winsock-AFD或Microsoft-Windows-TCPIP,就能让我调用所定义的记录回调(但是,我仍然无法检索属性,但为了让这个问题尽可能简单,我不会深入研究)。当我使用NDIS-PC时,我得到0个回调。我尝试手动使用ControlTrace刷新,但没有成功。我还尝试定义“EventCallback”而不是“EventRecordCallback”,但也没有成功。
我查看了此过程中涉及的所有数据结构,并在每个提供程序之间进行了比较,它们都看起来正确且相同。我查看了所有函数的返回值和返回的数据结构,并且它们在我尝试的提供程序之间看起来也是相同的。
我通过调用“logman“ My Trace Session 04”-ets”查看了会话属性,并且对于NDIS-PC和TCPIP,它们看起来完全相同:

C:\windows\system32>logman "My Trace Session 04" -ets

名称: My Trace Session 04 状态:
运行 根路径: %systemdrive%\PerfLogs\Admin Segment:
关闭 计划: 开启

名称: My Trace Session 04\My Trace Session 04 类型:
跟踪 追加: 关闭 循环: 关闭 覆盖:
关闭 缓存大小: 64 缓存丢失: 0 缓存写入: 0 缓存刷新计时器: 1 时钟类型: 性能 文件模式: 实时

提供程序: 名称: Microsoft-Windows-NDIS-PacketCapture 提供程序 GUID: {2ED6006E-4729-4609-B423-3EE7BCD678EF} 级别:
5 (win:Verbose) 关键字全部: 0x0 关键字任意:
0xffffffffffffffff (Ethernet802.3,WirelessWAN,Tunnel,Nativ e802.11,PacketStart,PacketEnd,ut:SendPath,ut:ReceivePath,ut:L3ConnectPath,ut:L2C onnectPath,ut:ClosePath,ut:Authentication,ut:Configuration,ut:Global,ut:Dropped, ut:PiiPresent,ut:Packet,ut:Address,ut:StdTemplateHint,ut:StateTransition,win:Res ponseTime,Microsoft-Windows-NDIS-PacketCapture/Diagnostic,0x2,0x4,0x8,0x10,0x20, 0x40,0x80,0x100,0x400,0x800,0x1000,0x2000,0x4000,0x20000,0x40000,0x80000,0x10000 0,0x200000,0x400000,0x800000,0x1000000,0x2000000,0x4000000,0x8000000,0x10000000, 0x20000000,0x400000000000,0x800000000000,0x2000000000000,0x4000000000000,0x80000 00000000,0x10000000000000,0x20000000000000,0x40000000000000,0x80000000000000,0x1 00000000000000,0x200000000000000,0x400000000000000,0x800000000000000,0x100000000 0000000,0x2000000000000000,0x4000000000000000) 属性: 0 过滤器类型: 0

命令已成功完成。

我还尝试了使用logman手动启动会话并在代码中打开它进行处理,但这对我也没有用。我还尝试只写入ETL文件,但也不起作用。我尝试了很多其他方法,但没有任何效果。
我已经阅读了与实时ETW消费有关的所有内容(MSDN、Google搜索、Stackoverflow等),但我没有看到一个完整的实时ETW事件消费示例。所有示例都显示从ETL文件中消费事件或将记录的事件导出到ETL文件,然后只需进行一些参数更改即可使实时消费正常工作。我相信我总结的代码更改反映了这些更改。
我正在使用Win7 Ultimate,在VS2010 SP1中创建32位控制台应用程序。我还尝试创建64位应用程序,但没有改进。
以下两篇文章与此相关,但在我尝试/强制执行时没有任何区别。在实时模式下,代码将会话名称复制到属性结构的末尾,并且日志文件偏移量需要为0。我认为我没有任何对齐问题,因为所有其他提供程序都可以正常工作:

Windows ETW:内核使用者未收到EventCallback或BufferCallback事件 Windows ETW:StartTrace失败,错误代码为87(ERROR_INVALID_PARAMETER)

我觉得我可能遗漏了一些微小且琐碎的东西,这应该是很简单的。 我会非常感谢任何帮助。

4个回答

10
如果您深入研究“netsh trace”命令的内部操作,您会发现它们会将一个NDIS轻型过滤驱动程序附加到各种网络接口。只有在此附加和激活了过滤器后,您才能从此提供程序获取事件。这个工具的详细信息未经记录并可能会有所更改。所有“netsh trace”命令的逻辑均是由nettrace.dll实现的,您可以通过Microsoft的公共符号进行反向工程分析。具体来说,“CInboxCapture”类中的代码确定驱动程序是否已启动,将其绑定到适当的网络接口并启动它。如果您以nettrace.dll的方式启动捕获过滤驱动程序,则会获得数据包捕获事件。

祝您好运。


1
嗨,我通过运行“netsh trace start capture = yes”命令来验证这个问题,然后运行了我的程序。现在我收到了NDIS-PC事件!但是,在我的EventRecordCallback函数中,对传入的PEVENT_RECORD结构体调用TdhGetEventInformation函数总是失败并显示ERROR_NOT_FOUND错误...我想写更多关于它的内容,但是评论字符限制已经到了,所以可能意味着我应该创建一个新的帖子来提问。感谢您的帮助! - Computer Software Guy
我也是通过这篇帖子才弄明白的:http://social.msdn.microsoft.com/Forums/en-US/etw/thread/473ac036-b4a6-464a-9b49-96e11b88c01c/ - Computer Software Guy
还有什么其他的想法吗?(使用Microsoft-NDIS-PacketCapture提供程序时没有事件回调)我正在尝试使用这段代码https://blogs.msdn.microsoft.com/vancem/2013/03/09/using-traceevent-to-mine-information-in-os-registered-etw-providers/。已经尝试了外部启动netsh跟踪,但仍然没有输出? - M.K

2

2

0

你可以尝试这个方法,而不是运行 netsh trace start 等命令:

net start ndiscap

当运行netsh trace等命令时,它会为您执行此操作,我认为这是缺失的部分,即注入到ndis中以捕获数据包(即etw提供程序)的轻量级过滤驱动程序未运行和发出事件。

完成后,您可以使用以下命令停止:

net stop ndiscap

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接