前言
项目需要用到ETW,学习记录一下1
ETW的简介
Event Trace for Windows
(ETW)是内核级别的事件追踪机制。
ETW由三部分组成
- Controllers(事件控制器),用来开关event trace 会话 和 Providers。
- Providers(事件提供器), 用来提供事件。
- Consumers(事件消耗器),用来处理事件。
ETW 工具
简介
Windows中存在一个工具-Logam,可以用来查看Provider以及Session状态,还能够建立Session
使用
1 2
| #查看事件提供器 logman query providers
|
这里查询Microsoft-Windows-Kernel-Process
1
| logman query Microsoft-Windows-Kernel-Process
|
- 第一个表格:GUID以及Provider的信息
- 第二个表格:Provider的Flag
- 第三个表格:安全等级
使用session
- 建立 Session,
logman create trace <session name> -p <provider name / GUID> <flags> <security level> -o <path to log file>
- 启用 Session,
logman start <session name>
- 停用 Session,
logman stop <session name>
- 刪除 Session,
logman delete <session name>
以Microsoft-Windows-Kernel-Process为例子
1 2 3 4 5 6 7 8 9 10 11
| 1. 建立 Session logman create trace example -p Microsoft-Windows-Kernel-Process 0x10 0x4 -o C:\example.etl
2. 啟用 Session logman start example
3. 停用 Session logman stop example
4. 刪除 Session logman delete example
|
需要以管理员身份启动cmd.exe,创建session
启动session
输入whoami命令
停止session
删除session
在指定路径留存了日志
将etl格式文件转化为xml
1
| tracerpt.exe C:\example_000001.etl -o d:\text.xml
|
得到的xml文件如下
KrabsETW
KrabsETWs是微软开发的用于与ETW交互的框架。能够更方便的追踪内核事件。
环境配置
vcpkg
1 2 3 4 5 6
| #克隆项目 git clone https://github.com/microsoft/vcpkg.git #下载 .\vcpkg\bootstrap-vcpkg.bat #集成到 Visual Studio .\vcpkg\vcpkg integrate install
|
安装库
1 2 3 4
| #json库 vcpkg.exe install nlohmann-json:x64-windows #krabsetw库 vcpkg.exe install krabsetw:x64-windows
|
例子
使用KrabsETW捕获事件需要经过以下流程
- 建立Session
- 选择Provider
- 设置事件处理函数
- 关联Session与Provider
- 启动Session
例子来源
https://github.com/zeze-zeze/2021iThome/tree/master/%E4%B8%8A%E7%99%BE%E7%A8%AEProvider%E4%BB%BB%E6%84%8F%E9%81%B8%E9%80%99%E6%A8%A3%E7%9A%84ETW%E4%BD%A0%E5%96%9C%E6%AD%A1%E5%97%8E
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| #include <krabs.hpp> #include <nlohmann/json.hpp> #include <iostream> #include <vector>
std::string ws2s(const std::wstring& wstr) { const std::string str(wstr.begin(), wstr.end()); return str; }
uint32_t byte2uint32(std::vector<BYTE> v) { uint32_t res = 0; for (int i = (int)v.size() - 1; i >= 0; i--) { res <<= 8; res += (uint32_t)v[i]; } return res; }
uint64_t byte2uint64(std::vector<BYTE> v) { uint64_t res = 0; for (int i = 7; i >= 0; i--) { res <<= 8; res += (uint64_t)v[i]; } return res; }
void callback(const EVENT_RECORD& record, const krabs::trace_context& trace_context) { krabs::schema schema(record, trace_context.schema_locator); krabs::parser parser(schema); if (schema.event_id() == 1) { nlohmann::json data; data["ProcessID"] = byte2uint32(parser.parse<krabs::binary>(L"ProcessID").bytes()); data["CreateTime"] = byte2uint64(parser.parse<krabs::binary>(L"CreateTime").bytes()); data["ParentProcessID"] = byte2uint32(parser.parse<krabs::binary>(L"ParentProcessID").bytes()); data["SessionID"] = byte2uint32(parser.parse<krabs::binary>(L"SessionID").bytes()); data["ImageName"] = ws2s(parser.parse<std::wstring>(L"ImageName")); std::cout << data.dump(4) << std::endl; } }
int main(int argc, const char* argv[]) { krabs::user_trace session(L"ETW_example"); krabs::provider<> provider(L"Microsoft-Windows-Kernel-Process"); provider.any(0x10); provider.add_on_event_callback(callback);
session.enable(provider);
session.start(); }
|
秉承着能用其他人都就不自己写的原则,学会了简单的ETW的使用。这里需要通过事件ID去捕获相应的事件。事件ID有大佬已经统计出来了,并且更新到最新的Windows11的版本了
https://github.com/jdu2600/Windows10EtwEvents/blob/master/manifest/Microsoft-Windows-Kernel-Process.tsv
效果
需要以管理员身份运行
参考链接
https://ithelp.ithome.com.tw/articles/10279093
https://ithelp.ithome.com.tw/articles/10279511
https://renyili.org/post/etw_study/