EtwSuite—面向检测工程的一站式ETW检视套件

admin 2026-08-22 04:49:25 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: EtwSuite是一款面向蓝队检测工程的开源ETW检视GUI工具,整合了Provider浏览、Schema解析、实时消费与ETL录制回放全流程。其独门能力是静态TraceLoggingPE扫描器,无需运行目标程序即可从二进制中剥离未文档化的TLG事件与字段,对盘点EDR遥测面极具价值。工程上采用三层分离与有界队列等严格规范,安全可靠。建议蓝队利用其离线研究安全产品遥测盲区,但需注意其缺乏跨Provider关联及内核会话支持的局限。 综合评分: 93 文章分类: 安全工具,二进制安全,应急响应,安全建设


EtwSuite — 面向检测工程的一站式 ETW 检视套件

原创

GLM-5.3 GLM-5.3

赛博生存指南

2026年8月21日 08:18 浙江

在小说阅读器读本章

去阅读

仓库地址:https://github.com/Idov31/EtwSuite

本文是对开源 ETW 检视工具 EtwSuite(v1.1.0)的源码级架构梳理与实用性评估,阅读对象为蓝队/检测工程师、DFIR 分析者与 Windows 遥测研究者。EtwSuite 用 WinUI 3 + .NET 8 把「浏览 Provider → 查看事件 schema → 实时消费 → 过滤 → 录制 ETL → 离线回放」整条检测工程工作流装进了一个本地 GUI。它最独特的能力是一个静态 TraceLogging PE 扫描器:不运行目标程序,直接从 .exe/.dll/.sys 里剥出 TraceLogging Provider 的 GUID、事件名与字段表——这在 GUI 工具里是独一份,对盘点 EDR/AV 自身遥测面极有价值。本文侧重源码实现、工程优缺点与蓝队适用性评估,不构成使用指引。


目录

  • EtwSuite — 面向检测工程的一站式 ETW 检视套件

  • 5.1 TraceLogging 为什么拿不到 schema

  • 5.2 ETW0 blob 解析

  • 5.3 x64 代码引用启发式:把事件归属给 Provider

  • 5.4 蓝队用法与边界

  • 目录

  • 1. 整体概览

  • 2. 背景问题:ETW 检视为什么值得再做一个工具

  • 3. 架构解剖:三层分离与工程纪律

  • 4. Provider 目录:一条四级 schema 解析链

  • 5. 独门能力:静态 TraceLogging PE 扫描器

  • 6. 实时消费:一条有节制的事件管线

  • 7. SQL 风格过滤器:手写的安全子集

  • 8. 横向对比与适用场景

  • 9. 局限与风险

    1. 评估结论
  • 参考资源


1. 整体概览

几个量化事实先放在前面:

  • v1.1.0.0,GPL-3.0 协议,C# / WinUI 3 / Windows App SDK 2.2 / .NET 8,目标 Windows 10 1809+,提供 x64 与 ARM64 两种 MSI 安装包(WiX 打包)。
  • 开发窗口 2026-06-11 立项至 2026-07-27 最后提交,约六周。后端(Core/Etw/ViewModels 共 30 个文件)约 7,500 行,UI code-behind 约 1,100 行,另有 13 个测试文件约 1,750 行——对一个六周项目,测试覆盖相当扎实(过滤器编译器、Provider 目录、会话命名、krabs 消费、批处理读取、TLG PE 扫描器、TDH 类型映射全部有独立测试)。
  • 依赖面刻意收窄:TraceEvent 2.0.56(ETL 读取/清单获取)、Microsoft.O365.Security.Native.ETW 4.4.9(即 krabsetw,实时消费)、Microsoft.Data.Sqlite 9.0.5(会话模板存储)、System.Management(WMI/MOF 元数据)。没有日志上传、没有遥测、没有云依赖——AGENTS.md 里明文禁止未经批准添加。
  • 作者在 README 披露了 AI 辅助开发(Codex + GitHub Copilot,人工审查修改),仓库附带的 AGENTS.md 与 .agents/instructions/ 目录本身就是一套给 AI 的工程规范——这个仓库对研究「如何用规范约束 AI 辅助开发」也有样本价值。
  • 权限模型诚实:浏览 Provider、看缓存元数据、离线打开录制文件都不需要管理员;实时消费部分 Provider 需要管理员或 Performance Log Users 组;README 明确指出 Microsoft-Windows-Threat-Intelligence 的实时消费需要 PPL 签名者,管理员权限都不够。

一句话定位:这是 Zodiacon 的 EtwExplorer 的「现代继任者 + 全流程一体化」尝试——EtwExplorer 解决了「看 Provider 与 schema」,EtwSuite 把消费、过滤、录制、回放、TLG 静态发现全部接了上去。它不是 C2、不是加载器、不做任何绕过,是一个纯粹的 防御侧遥测工程工具


2. 背景问题:ETW 检视为什么值得再做一个工具

Windows 检测工程的主食是 ETW:进程创建、映像加载、.NET Assembly、PowerShell、DNS 客户端、内核回调……上千个 Provider 构成了 EDR 与 SIEM 之外最丰富的本机遥测源。但「用上」这批遥测的前置成本出奇地高:

| 现有工具 | 短板 | | — | — | | logman / wevtutil | 命令行能开会话,但看不到事件 schema,更看不到字段 | | EtwExplorer | 经典的 Provider 浏览器,但多年未大更新,消费/录制/过滤能力有限 | | WPA / PerfView | 面向性能分析专家,trace 中心而非 Provider 中心,上手陡 | | SilkETW / 自写 krabs 脚本 | 灵活但是 CLI/代码形态,探索阶段的「翻一翻有哪些事件、字段长什么样」效率低 |

检测工程师的真实迭代循环是:找到 Provider → 看懂事件与字段 → 起会话实时验证 → 用条件收窄 → 存 ETL 留证 → 离线复查。这个循环目前要在三四个工具之间来回切换。EtwSuite 的立项目标就是把这条循环收进一个窗口——从源码看,它基本做到了,并且在两处(下文 §5、§6)超出了预期。


3. 架构解剖:三层分离与工程纪律

EtwSuite/
├── Core/           领域模型与接口:EtwProviderInfo、EtwLiveEventRecord、
│                   EtwFilterCompiler、IEtwLiveEventConsumer…
├── Etw/            后端实现:
│   ├── EtwProviderCatalog.cs        TDH 枚举 + 清单/WMI schema 解析
│   ├── KrabsEtwLiveEventConsumer.cs krabsetw 实时消费
│   ├── TraceEventEtlRecorder.cs     ETL 录制
│   ├── EtwTraceSessionNameResolver  会话命名与系统会话特判
│   ├── Native/TdhNative.cs          tdh.dll P/Invoke
│   └── TraceLogging/StaticTraceLoggingPeScanner.cs   ← 独门
└── ViewModels/     MVVM 状态与命令,WinUI code-behind 保持纤薄

几条贯穿全库的工程纪律值得点名:

  1. UI 永不直接绑定 TraceEvent/XML 节点/native 结构。所有事件先映射进项目自有的 EtwLiveEventRecord 领域模型,ETW 实现层的变化不污染 UI。
  2. 全链路 CancellationToken,阻塞、枚举、解析、导出全部可取消;全库 grep 不到 .Result/.Wait()
  3. ETW 会话被当作系统资源对待:启动失败会清理,停止有 5 秒超时兜底,对系统自有会话有显式「不许停」标记(见 §6)。
  4. XML 清单解析禁 DTD、禁外部实体解析——manifest 是从系统注册表拉回来的半可信输入,这个防御是必要的。

这套纪律不是摆设:高频 Provider(如内核事件)下,消费管线的有界队列 + 批量 UI 刷新(§6)决定了工具在事件风暴里活不活得下来。


4. Provider 目录:一条四级 schema 解析链

Provider 列表本身来自 TdhEnumerateProviders(tdh.dll P/Invoke,非托管内存手工 Marshal),每个 Provider 带一个 SchemaSource 标签,标注它的 schema 来自哪里。EtwSuite 按「四级回退链」取 schema:

| 级别 | 来源 | 实现方式 | | — | — | — | | 1 | XML 清单 | RegisteredTraceEventParser.GetManifestForRegisteredProvider 拉回注册清单,自解析 tasks/opcodes/levels/templates 映射,事件名优先 symbol,退而求 message/task | | 2 | WMI/MOF | 遍历 root\WMI 里继承 EventTrace 的类三层结构(Provider → Category → Template),读 eventtype/eventversion/wmidataid 限定符还原事件与字段顺序 | | 3 | TDH 清单事件 | TdhEnumerateManifestProviderEventsTdhGetManifestEventInformation 逐事件取名字段 | | 4 | 静态缓存 | TLG Provider:清单拿不到时,回退到 §5 扫描器缓存的静态 schema |

对 WPP 与无缓存的 TLG,工具不会硬编一个假 schema,而是给出诚实诊断信息(「TraceLogging Provider 通常没有注册的 XML 清单,静态元数据仅当 EtwSuite 已从 PE 映像发现并缓存时可用」)。把「元数据不完整、Provider 特定、版本依赖、可能受访问限制」当作第一性约束,是整个目录层的设计基调——这在文档与代码里都写得很明白,也是同类工具里少见的成熟度。


5. 独门能力:静态 TraceLogging PE 扫描器

这是全项目技术含量最高的 1,254 行,也是我认为最能构成「装这个工具的理由」的功能。

5.1 TraceLogging 为什么拿不到 schema

传统清单式 Provider 的 schema 存在注册表/XML 清单里,TDH 能直接回答「你有哪些事件、字段是什么」。TraceLogging(自 Windows 10 起的新式 API)反其道而行:schema 内嵌在二进制里,随事件自描述,注册表里只有一个名字。这意味着:

  • 你在 Provider 列表里看到一个 TLG Provider,选中它,却查不到任何静态事件清单;
  • 想知道「这个 EDR 的这个 Provider 到底会发什么事件、带什么字段」,传统做法只有跑起来抓包碰运气,或者逆手工分析。

EtwSuite 的答案是不运行程序、直接扫文件:给它一个目录(比如 C:\Program Files\你的EDR),它递归扫 .exe/.dll/.sys,把里面所有 TLG Provider 的 GUID、名字、事件名、字段类型全部剥出来,并合并进 Provider 列表。README 资源区列有 AsuNa-jp 的 TLGMapper——这条技术路线的先行工具。

5.2 ETW0 blob 解析

扫描器在 PE 每个节的原始字节里找 TLG 元数据块的签名:

// "ETW0" + 版本长度字 0x10 + 编译器签名 GUID 片段
bytes.AsSpan(offset, 4).SequenceEqual("ETW0"u8) &&
BitConverter.ToUInt16(bytes, offset + 4) == 16 &&
BitConverter.ToUInt64(bytes, offset + 8) == 0xBB8A052B88040E86UL

找到 ETW0 头之后,按 TLG trait blob 语法逐条解析:类型 0 是填充、1 是结束符、2/4 是 Provider 描述(4 带显式 GUID)、3/5/6 是事件元数据(不同版本编译器的字节布局差异)。事件字段解析覆盖了完整的 inType 表(UnicodeString/Int32/SID/FileTime…)与 outType 扩展(PID/TID/IPv4/Win32Error/NTStatus…)、数组后缀([]/[N]),以及 type 5 事件固定 channel=0x0B(TraceLogging 通道 11)这类边角。

5.3 x64 代码引用启发式:把事件归属给 Provider

难点在:一个二进制里往往有 多个 Provider、几十个事件,元数据 blob 本身不记录「哪个事件属于哪个 Provider」。EtwSuite 的解法是一个轻量 x64 指令扫描(不完整反汇编,只认两种模式):

mov r64, imm64          ; REX.W + B8-BF —— 把 64 位地址直接装进寄存器
mov/lea r64, [rip+disp32]  ; 8B/8D + ModRM(mod=00, rm=101) —— RIP 相对寻址

这两条恰好覆盖了编译器物化「事件元数据地址」「Provider 句柄地址」的全部主流姿势。归属算法:

  1. 先扫数据节里的 qword,把指向 Provider 注册块的指针串成 Provider 句柄地址表(句柄结构按 64 字节展开);
  2. 在可执行节里找所有指向「事件元数据区间」与「Provider 句柄」的代码引用;
  3. 每个事件引用,归属到 指令序上最近的前置 Provider 引用(DirectPreceding 置信度),否则 0x200 字节窗口内最近者(DirectNearest);
  4. 二进制只有一个带 GUID 的 Provider 时直接短路归属(SingleProvider)。

这个顺序模拟的正是 EventWrite 调用点的代码生成:先装 Provider 句柄,再装事件描述符数组。置信度分级、多条引用竞争时取高置信、归属失败的事件计数进诊断而不是硬塞——启发式的诚实边界处理得不错。

5.4 蓝队用法与边界

蓝队视角的典型用法:

  • 遥测盘点:扫 System32 看系统组件有哪些未文档化的 TLG 通道、字段里有没有值得做检测的数据;
  • EDR/AV 遥测面研究:离线扫安全产品目录,拿到它全部 TLG Provider 的 GUID 与事件 schema——不用把 EDR 跑起来,不用触发任何告警。对「我的 EDR 到底看得到什么」这种黑盒问题,这是少有的白盒化手段。

必须说明这是一把双刃剑:红队同样可以离线做这件事来评估 EDR 的遥测覆盖(找它不看的角落)。技术本身是静态文件解析,无任何运行时足迹,不存在「用了就留痕」的问题——防御者应当假设对手已经这么做了。

边界同样清楚:事件归属启发式仅支持 x64(ARM64/x86 只解析元数据、不做归属);编译器优化、内联、混淆都可能造成归属错位或漏报;扫描结果带版本号缓存(文件大小 + 修改时间 + ScannerVersion 三重失效),扫描过一次后增量成本极低。


6. 实时消费:一条有节制的事件管线

实时消费基于微软的 krabsetw(Microsoft.O365.Security.Native.ETW,O365 安全团队的同款库)。管线的克制程度值得细看:

  • 有界队列:事件从 krabs 回调进入一个容量 100,000 的 Channel,满时丢最旧(DropOldest)——高频 Provider 下宁可丢事件也不无界吃内存,回调里连异常都不允许抛回 krabs 处理线程;
  • 批量 UI 刷新:UI 侧不是每事件刷新一次集合,而是「攒批 + 截止时间」双条件合并刷新,这是 AGENTS.md 明文要求的「高频 trace 中禁止逐事件更新可观察集合」的落地;
  • 解码补丁:payload 解码覆盖全类型表,并专门修了 Wbem(MOF)类 Provider 的 反向计数字符串(ReverseCountedWideString)解析——这类事件(典型如老式内核遥测)的字符串长度前缀是大端序,naive 解码会吐乱码,开源工具里把这个 quirk 处理对的并不多。

两个会话治理细节最能体现作者对系统资源的敬畏:

  1. Security-Auditing 特判:消费 Microsoft-Windows-Security-Auditing(GUID 54849625-…)时不新建会话,而是 挂到系统已有的 EventLog-Security 会话 上——你可以在 GUI 里实时看 4688 进程创建这类安全审计事件,且工具被标记为 永不停止该会话,不存在「工具退出顺手把安全日志通道掐了」的事故面。
  2. 会话命名指纹:自建会话名固定为 EtwSuite-<Provider名>-<随机GUID>(截断到 64 字符)。对蓝队这是个顺手的资产盘点特征——logman query 里看到这个前缀,就知道是这台机器上有人在用 EtwSuite 做合法检视,而不是未知进程私建 ETW 会话。

录制用 TraceEvent 另起 EtwSuite-Etl- 会话写原生 .etl,StopOnDispose + 显式 flush;对系统自有会话直接拒绝录制并说明原因。离线侧可打开 .etl(Etl 回放)、.json、.csv(EtwSuite 自己导出的格式),导出支持 JSON 与 CSV——留证、复查、给同事分发的闭环是完整的。


7. SQL 风格过滤器:手写的安全子集

过滤器有两档:Basic(大小写不敏感文本 + */? 通配)和 SQL。SQL 档不是嵌了什么数据库,而是一个 手写的 tokenizer + 递归下降解析器(约 300 行),支持:

event_id&nbsp;=1
process_name&nbsp;LIKE'powershell*'
WHERE&nbsp;provider&nbsp;LIKE'Microsoft-Windows-*'AND&nbsp;pid&nbsp;=4242
NOT&nbsp;(level&nbsp;>3OR&nbsp;opcode&nbsp;=2)
payload.ImageName&nbsp;LIKE'*cmd.exe'

安全设计是教科书式的:字段走白名单(provider/event/id/version/opcode/level/pid/process/tid/payload.*),未知字段直接报错;不支持函数调用、不支持任意成员访问,不存在表达式注入面;LIKE 的 %/_ 编译成正则并施加 100ms 匹配超时(防 ReDoS);数值比较走 decimal 而非 double。解析失败返回带位置的错误信息,编译成委托后在事件流上原位求值——这条过滤器同样作用于离线打开的录制文件。

对一个「本地 GUI 工具里的过滤器」来说,这套实现的安全投入超出了功能必需——但考虑到过滤的是不可信遥测内容,这个谨慎是对的。


8. 横向对比与适用场景

| 能力 | EtwSuite | EtwExplorer | WPA/PerfView | SilkETW/CLI | | — | — | — | — | — | | Provider 浏览 + schema 查看 | 完整(四级链) | 完整 | 弱(非 Provider 中心) | 无 | | TLG 静态 schema 发现 | 有(PE 扫描) | 无 | 无 | 无 | | 实时消费 + 过滤 | 有(SQL 表达式) | 有限 | 复杂 | 有(无浏览) | | ETL 录制/回放 | 有 | 部分 | 强 | 部分 | | JSON/CSV 导出 | 有 | 无 | 部分 | 部分 | | 会话模板持久化 | 有(SQLite) | 无 | 有(另形态) | 无 |

对检测工程的典型场景适配度:

| 场景 | 适配度 | 说明 | | — | — | — | | 开发检测规则前摸清某 Provider 的事件与字段 | 高 | 浏览 → schema → 消费一气呵成,SQL 过滤收窄验证 | | 研究未文档化遥测(系统组件/EDR 的 TLG 通道) | 最高 | 静态扫描器是独门,离线、无 footprint | | 安全审计事件抽查(4688 等) | 高 | 挂 EventLog-Security 会话实时看,不动审计策略 | | 取证留证与复查 | 中高 | ETL 录制 + 回放 + 导出;但不吃 .evtx | | 大规模长期采集 | 低 | 定位是交互式检视,不是常驻采集器 |

结论方向已经清楚:它填补的正是「EtwExplorer 停更留下的空档 + 检测工程全流程一体化」,且在 TLG 静态发现这一点上没有同型竞品。


9. 局限与风险

按影响排序:

  • 单 Provider 会话:一次消费只挂一个 Provider(会话名里就嵌着 Provider 名)。跨 Provider 关联(比如进程创建 + 映像加载对照)只能开两个窗口肉眼对,或者录 ETL 离线看。对检测验证场景这是最常撞到的墙。
  • 无内核会话支持:消费走 krabsetw 的 UserTrace,没有 kernel trace 会话形态,映像加载/线程/磁盘/网络内核 Provider 的采集做不了。这类遥测仍需 WPR/logman 补位。

  • TLG 归属仅 x64:ARM64 版本能跑(项目宣称 ARM64 兼容),但事件归属启发式只实现了 Amd64,ARM64/x86 二进制只出 Provider 与事件列表、不出归属关系。
  • 不吃 .evtx、不支持 WPP/TMF:安全事件日志文件与老式 WPP Provider 不在射程内,README 已如实声明;ETL payload 解码是 best-effort,读文件机器上没有对应 Provider 元数据时字段会缺失。
  • 实时消费需提权:管理员或 Performance Log Users 组成员才能起会话;Threat-Intelligence Provider 更是需要 PPL——这是 Windows 的权限模型,不是工具的锅,但部署时要知道。

  • GPL-3.0 传染性:想把它当后端库嵌进自研商用工具的企业需要想清楚,GPL 对二次分发的约束是硬的;内部使用不受影响。
  • 年轻项目:六周开发窗、v1.1.0、单一作者(AI 辅助 + 人工审查),API 与行为都可能有变动;好在有 MSI 安装器与测试托底。
  • WinUI 3 unpackaged 形态:免安装拥趸会喜欢自包含发布,但企业软件分发体系里 MSI 之外的形态总要额外解释。

10. 评估结论

回答标题里的问题:有用,而且是「装进检测工具箱主力位」级别的有用

三个理由:

  1. 工作流完整度。检测工程「找 → 看 → 验 → 滤 → 录 → 放」的循环第一次在一个本地 GUI 里闭环,且每一环的工程质量都经得起读源码(有界队列、批量刷新、会话治理、防 ReDoS、安全 XML 解析)。它不惊艳在任何单点,而是完整地尊重了 ETW 这个系统资源的每一个坑。
  2. TLG 静态扫描器是独门武器。离线把 EDR/AV/系统组件的 TraceLogging 遥测面白盒化,这个能力此前只存在于研究脚本与 TLGMapper 这类专用工具里,被集成进一个带 GUI、带缓存、带归属启发式的桌面工具是第一次。蓝队拿它做遥测盘点,红队拿它做覆盖评估——这个双刃性本身就是「值得认真对待」的证据。
  3. 边界诚实。做不到的事(内核会话、.evtx、WPP、ARM64 归属)在 README 与诊断信息里逐条写明,不装、不糊弄。对一个 AI 辅助开发的年轻项目,这种诚实比功能列表更稀缺。

给蓝队的落位建议:作为检测工程师的日常 ETW 检视主力工具候选装机;TLG 扫描器优先用来盘点一次自家 EDR 与关键系统组件的遥测面(结果值得进 wiki);同时记住 §6 那个 EtwSuite- 会话名前缀——它在 logman query 里区分「合法检视」与「未知采集」,是你资产盘点里免费的特征。

一句话收尾:Windows 检测的上限由遥测理解深度决定,而理解遥测的第一步是能「看见」它——EtwSuite 目前是把 ETW 看得最全的那个本地窗口。


参考资源

EtwSuite 仓库:https://github.com/Idov31/EtwSuite

TLGMapper(静态 TLG 扫描的上游思路):https://github.com/AsuNa-jp/TLGMapper

EtwExplorer:https://github.com/zodiacon/EtwExplorer

krabsetw:https://github.com/microsoft/krabsetw

TraceEvent:https://github.com/microsoft/perfview/tree/main/src/TraceEvent

Event Tracing for Windows 官方文档:https://learn.microsoft.com/windows/win32/etw/event-tracing-portal


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:赛博生存指南 GLM-5.3 GLM-5.3《EtwSuite — 面向检测工程的一站式 ETW 检视套件》

评论:0   参与:  0