首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

netsh trace ETL 文件轉 PCAP:TDH 解析與 Libpcap 寫入完整方案

     編輯:程式設計綜合問答

問題背景

使用 `netsh trace start capture=yes tracefile=test.etl` 抓取網絡數據,生成 `.etl` (ETW) 文件。需離線解析 ETL,提取數據包與進程 ID,生成標準 `.pcap` 供 Wireshark 分析。

核心技術棧

  • TDH (Trace Data Helper) API:Windows 官方 ETW 事件解析庫 (`tdh.h`, `tdh.lib`),支持實時/離線解析 `.etl`。
  • Libpcap / WinPcap / Npcap:標準數據包捕獲/寫入庫,保證 PCAP 格式合規。
  • 目標提供者:`Microsoft-Windows-TCPIP` (GUID: `{9A280AC0-C8E0-11D1-84E2-00C04FB998A2}`) 及 `Microsoft-Windows-NDIS`。

完整工程步驟

  1. 打開 ETL:`TdhOpenTrace(&trace, L"test.etl", NULL, NULL, NULL)`。
  2. 枚舉事件:循環 `TdhEnumerateTraces` / `ProcessTrace` 獲取 `EVENT_RECORD*`。
  3. 過濾網絡事件:檢查 `EventHeader.ProviderId` 是否為 TCPIP/NDIS,`EventHeader.EventId` 為 Send/Receive (具體 ID 需查詢 manifest 或實驗確定)。
  4. 提取負載:使用 `TdhGetEventInformation` 獲取事件結構描述,再 `TdhGetProperty` 提取 `Payload` (原始幀數據)、`PID` (`EventHeader.ProcessId`)、時間戳 (`EventHeader.TimeStamp`)。
  5. 按 PID 分文件寫入:為每個 PID 創建 `pcap_dump_open`,調用 `pcap_dump` 寫入包頭與數據(參考 文章 32739、文章 32752)。
  6. 進程名稱解析:ETL 僅含 PID。方案:
    • 同步調用 `OpenProcess` + `GetModuleFileNameEx` (需 `Psapi.h`)。
    • 或記錄 PID,事後用 `Task Manager` / `wmic process get ProcessId,Name` 導出映射表,離線關聯。

關鍵代碼骨架

// 參考文章 32752 的 PcapWriter 結構與 write_packet 函數

void process_etl(const wchar_t* etl_path) {
    TRACEHANDLE trace = 0;
    EVENT_TRACE_LOGFILE log = {0};
    log.LogFileName = (LPWSTR)etl_path;
    log.ProcessTraceMode = PROCESS_TRACE_MODE_EVENT_RECORD;
    log.EventRecordCallback = on_event_record;
    
    trace = OpenTrace(&log);
    if (trace == INVALID_PROCESSTRACE_HANDLE) return;
    
    ProcessTrace(&trace, 1);
    CloseTrace(trace);
}

void WINAPI on_event_record(PEVENT_RECORD record) {
    // 1. 過濾 Provider
    if (!IsEqualGUID(record->EventHeader.ProviderId, TCPIP_GUID)) return;
    
    // 2. 提取 Payload (簡化:假設 UserData 直接是幀數據)
    // 實際需用 TdhGetProperty 解析結構化負載
    PBYTE payload = (PBYTE)record->UserData;
    ULONG payload_len = record->UserDataLength;
    if (payload_len == 0) return;
    
    // 3. 獲取 PID 和時間戳
    DWORD pid = record->EventHeader.ProcessId;
    ULONGLONG timestamp = record->EventHeader.TimeStamp.QuadPart;
    
    // 4. 寫入對應 PID 的 PCAP
    PcapWriter* writer = get_writer(pid);
    write_packet(writer, payload, payload_len, timestamp);
}

避坑指南

現成工具推薦(避免重複造輪子)

  • etl2pcap (Microsoft 官方開源):C# 實現,直接將 `.etl` 轉 `.pcap`,支持 PID 映射,生產可用。
  • tshark:Wireshark 命令行工具,新版本支持 `tshark -r test.etl -w out.pcap` 直接轉換 (需 Npcap 支持)。
  • WinPcap/Npcap:包含 `Packet.dll` 可直接讀取 ETW 會話。

「如果你已經獲取十六進制或者二進制數據,那麼請看:https://ask.csdn.net/questions/199693」—— 指向同一完整解決方案,避免分散碎片化知識。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
坑點現象對策
ETL 事件結構複雜`UserData` 非直接幀數據,而是結構體嵌套必須用 `TdhGetEventInformation` + `TdhGetProperty` 按名稱提取字段,不可硬編碼偏移
TDH API 需 Manifest解析失敗,提示找不到事件結構確保系統安裝了對應 Provider 的 Manifest (通常在 `C:\Windows\System32\winevt\Manifests\`),或動態加載
大量事件性能差逐個 `TdhGetProperty` 極慢批量處理、複用 `TRACE_EVENT_INFO`、考慮 C# `Microsoft.Diagnostics.Tracing.TraceEvent` 庫 (性能更好)
權限不足`OpenProcess` 失敗以管理員運行,或啟用 `SeDebugPrivilege`