網站首頁 編程語言 正文
何為Etw
ETW(Event Tracing for Windows)提供了一種對用戶層應用程序和內核層驅動創建的事件對象的跟蹤記錄機制。為開發者提供了一套快速、可靠、通用的一系列事件跟蹤特性。
前言
一直想研究一種監控進程的方法,但wmi/枚舉進程的方法,要么反應太慢,要么占用高。最近看到有人用易語言易語言完成了Etw對進程變動監控的實現。
但是一直沒看到C++的實現,于是決定將易語言易語言翻譯為C++。
代碼
直接上翻譯的代碼
#include <iostream>
#include <string>
#include <cstring>
#include <windows.h>
#include <evntrace.h>
#include <psapi.h>
#include <direct.h>
#include <evntcons.h>
using namespace std;
char SESSION_NAME_FILE[] = "Sample_Process";
const UCHAR _Flag[] = { 173, 74, 129, 158, 4, 50, 210, 17, 154, 130, 0, 96, 8, 168, 105, 57 };
EVENT_TRACE_PROPERTIES m_TraceConfig;
UCHAR m_pTraceConfig[2048];
char m_File[256];
BOOL m_DoWhile;
TRACEHANDLE m_hTraceHandle;
ULONG64 m_hTraceHandle_econt[1];
TRACEHANDLE m_hSessionHandle;
string Unicode_To_Ansi(wstring strValue)
{
static CHAR sBuff[1024] = { 0 };
int iRet = WideCharToMultiByte(CP_ACP, 0, strValue.c_str(), -1, sBuff, sizeof(sBuff), NULL, NULL);
if (iRet > 0) {
return string(sBuff);
}
return "";
}
VOID WINAPI MyProcessRecordEvents(PEVENT_RECORD EventRecord)
{
switch (EventRecord->EventHeader.EventDescriptor.Id)
{
case 1://創建進程
cout << "創建進程!進行創建進行的進程ID:" <<
EventRecord->EventHeader.ProcessId <<
",線程ID:" <<
EventRecord->EventHeader.ThreadId <<
",進程SessionID:" <<
*(ULONG*)(((PUCHAR)EventRecord->UserData)+32)<<
",創建的進程ID:"<<
*(ULONG*)(((PUCHAR)EventRecord->UserData) + 0) <<
",創建的進程路徑:"<<
Unicode_To_Ansi( wstring((wchar_t*)(((PUCHAR)EventRecord->UserData) + 60)))
<<endl;
break;
case 2://進程退出
cout << "進程退出!進程ID:" <<
EventRecord->EventHeader.ProcessId <<
",線程ID:" <<
EventRecord->EventHeader.ThreadId <<
", 進程名:"<<
((LPSTR)EventRecord->UserData) + 84
<<endl;
break;
cout << "進程ID:" << EventRecord->EventHeader.ProcessId << ",未知的行為:0x"<<hex<<EventRecord->EventHeader.EventDescriptor.Id << endl;
default:
break;
}
}
void CloseEtw()
{
ULONG l_result = StopTraceA(m_hSessionHandle, SESSION_NAME_FILE, (PEVENT_TRACE_PROPERTIES)(m_pTraceConfig + 8));
if (m_hTraceHandle != NULL)
{
CloseTrace(m_hTraceHandle);
}
}
DWORD WINAPI OpenEtw(LPVOID lpThreadParameter)
{
m_DoWhile = TRUE;
_getcwd(m_File, sizeof(m_File));
strcat(m_File, "\\MyFile.etl");
m_TraceConfig.Wnode.BufferSize = 1024;
m_TraceConfig.Wnode.Flags = WNODE_FLAG_TRACED_GUID;
m_TraceConfig.Wnode.ClientContext = 3;
m_TraceConfig.BufferSize = 1;
m_TraceConfig.MinimumBuffers = 16;
m_TraceConfig.LogFileMode = EVENT_TRACE_REAL_TIME_MODE;
m_TraceConfig.LoggerNameOffset = 120;
m_TraceConfig.FlushTimer = 1;
RtlMoveMemory(m_pTraceConfig + 8, &m_TraceConfig, 120);
RtlCopyMemory(m_pTraceConfig + 128, SESSION_NAME_FILE, sizeof(SESSION_NAME_FILE));
RtlCopyMemory(m_pTraceConfig + 128 + sizeof(SESSION_NAME_FILE), m_File, strlen(m_File));
RtlCopyMemory(m_pTraceConfig + 28, _Flag, sizeof(_Flag));
ULONG l_result = StartTraceA(&m_hSessionHandle, SESSION_NAME_FILE, (PEVENT_TRACE_PROPERTIES)(m_pTraceConfig + 8));
if (m_hSessionHandle == NULL && l_result == ERROR_ACCESS_DENIED)
{
cout << "StartTraceA失敗!原因:無管理員權限!" << endl;
return 0;
}
else if (m_hSessionHandle == NULL && l_result == ERROR_ALREADY_EXISTS)
{
m_hSessionHandle = 44;//輸入上一次終止時候的句柄
CloseEtw();
cout << "StartTraceA失敗!原因:已經有Etw事件進行數據跟蹤!請使用上方屏蔽代碼關閉事件或者使用 計算機管理 停用事件:Sample_Process" << endl;
ControlTraceA(m_hSessionHandle, SESSION_NAME_FILE, (PEVENT_TRACE_PROPERTIES)(m_pTraceConfig + 8), 1);
return 0;
}
cout << "hSessionHandle: " << m_hSessionHandle << endl;
const UCHAR m_ProcessGUID[] = { 214, 44, 251, 34, 123, 14, 43, 66, 160, 199, 47, 173, 31, 208, 231, 22 }; // PsProvGuid
l_result = EnableTraceEx((LPCGUID)(m_ProcessGUID), 0, m_hSessionHandle, 1, 0, 16, 0, 0, 0); //這里MatchAnyKeyword的64其實是0x40,表示 #KERNEL_KEYWORDS_IMAGE
EVENT_TRACE_LOGFILEA m_Logfile;
ZeroMemory(&m_Logfile, sizeof(m_Logfile));
m_Logfile.LoggerName = SESSION_NAME_FILE;
*((ULONG*)((PUCHAR)&m_Logfile + 20)) = 268439808;
m_Logfile.EventRecordCallback = MyProcessRecordEvents;
m_Logfile.Context = (PVOID)0x114514;//隨便輸入一個數就好了
SetLastError(0);
m_hTraceHandle = OpenTraceA(&m_Logfile);
cout << "開始監視!" << endl;
m_hTraceHandle_econt[0] = m_hTraceHandle;
ULONG rc = ProcessTrace(m_hTraceHandle_econt, 1, 0, 0);
return 0;
}
int main()
{
CreateThread(NULL, NULL, OpenEtw, NULL, NULL, NULL);
//Sleep(10000);
system("pause");
CloseEtw();
return 0;
}
注意事項
必須給管理員權限
請正常退出(按任意鍵),否則Trace不會自己關
原文鏈接:https://www.cnblogs.com/Icys/p/EtwProcess.html
相關推薦
- 2022-11-02 python函數和python匿名函數lambda詳解_python
- 2022-09-09 python定義函數如何判斷年份是否為閏年_python
- 2022-12-24 Docker自定義網絡詳解_docker
- 2022-07-08 python?動態規劃問題解析(背包問題和最長公共子串)_python
- 2022-04-04 Element ui NavMenu 導航菜單 template中的內容不顯示
- 2023-03-27 python,pycharm的環境變量設置方式_python
- 2022-06-17 C#多線程死鎖介紹與案例代碼_C#教程
- 2022-04-09 一起來了解python的運算符_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支