C++實(shí)現(xiàn)ETW進(jìn)行進(jìn)程變動(dòng)監(jiān)控詳解
何為Etw
ETW(Event Tracing for Windows)提供了一種對用戶層應(yīng)用程序和內(nèi)核層驅(qū)動(dòng)創(chuàng)建的事件對象的跟蹤記錄機(jī)制。為開發(fā)者提供了一套快速、可靠、通用的一系列事件跟蹤特性。
前言
一直想研究一種監(jiān)控進(jìn)程的方法,但wmi/枚舉進(jìn)程的方法,要么反應(yīng)太慢,要么占用高。最近看到有人用易語言易語言完成了Etw對進(jìn)程變動(dòng)監(jiān)控的實(shí)現(xiàn)。
但是一直沒看到C++的實(shí)現(xiàn),于是決定將易語言易語言翻譯為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://創(chuàng)建進(jìn)程 cout << "創(chuàng)建進(jìn)程!進(jìn)行創(chuàng)建進(jìn)行的進(jìn)程ID:" << EventRecord->EventHeader.ProcessId << ",線程ID:" << EventRecord->EventHeader.ThreadId << ",進(jìn)程SessionID:" << *(ULONG*)(((PUCHAR)EventRecord->UserData)+32)<< ",創(chuàng)建的進(jìn)程ID:"<< *(ULONG*)(((PUCHAR)EventRecord->UserData) + 0) << ",創(chuàng)建的進(jìn)程路徑:"<< Unicode_To_Ansi( wstring((wchar_t*)(((PUCHAR)EventRecord->UserData) + 60))) <<endl; break; case 2://進(jìn)程退出 cout << "進(jìn)程退出!進(jìn)程ID:" << EventRecord->EventHeader.ProcessId << ",線程ID:" << EventRecord->EventHeader.ThreadId << ", 進(jìn)程名:"<< ((LPSTR)EventRecord->UserData) + 84 <<endl; break; cout << "進(jìn)程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失敗!原因:無管理員權(quán)限!" << endl; return 0; } else if (m_hSessionHandle == NULL && l_result == ERROR_ALREADY_EXISTS) { m_hSessionHandle = 44;//輸入上一次終止時(shí)候的句柄 CloseEtw(); cout << "StartTraceA失??!原因:已經(jīng)有Etw事件進(jìn)行數(shù)據(jù)跟蹤!請使用上方屏蔽代碼關(guān)閉事件或者使用 計(jì)算機(jī)管理 停用事件: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其實(shí)是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;//隨便輸入一個(gè)數(shù)就好了 SetLastError(0); m_hTraceHandle = OpenTraceA(&m_Logfile); cout << "開始監(jiān)視!" << 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; }
注意事項(xiàng)
必須給管理員權(quán)限
請正常退出(按任意鍵),否則Trace不會(huì)自己關(guān)
以上就是C++實(shí)現(xiàn)ETW進(jìn)行進(jìn)程變動(dòng)監(jiān)控詳解的詳細(xì)內(nèi)容,更多關(guān)于C++進(jìn)程監(jiān)控的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
opencv3/C++視頻中疊加透明圖片的實(shí)現(xiàn)
今天小編就為大家分享一篇opencv3/C++視頻中疊加透明圖片的實(shí)現(xiàn),具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-12-12C++使用智能指針實(shí)現(xiàn)模板形式的單例類
這篇文章主要為大家詳細(xì)介紹了C++使用了智能指針實(shí)現(xiàn)模板形式的單例類,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06如何將C語言代碼轉(zhuǎn)換為應(yīng)用程序(也就是編譯)
有時(shí)候我們將讓我們的c語言代碼保存為一個(gè)exe方便,方便使用,實(shí)際就是我們俗說的編譯2013-07-07OpenCV實(shí)現(xiàn)輪廓的發(fā)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了OpenCV如何實(shí)現(xiàn)輪廓的發(fā)現(xiàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-05-05Windows下ncnn環(huán)境配置教程詳解(VS2019)
這篇文章主要介紹了Windows下ncnn環(huán)境配置(VS2019),本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03C語言中時(shí)間戳轉(zhuǎn)換成時(shí)間字符串的方法
在PE格式里有個(gè)字段是文件的創(chuàng)建時(shí)間戳,我想把轉(zhuǎn)成字符串,今天小編給大家分享一段代碼,可以比較直觀的看出,需要的的朋友參考下2017-02-02