c++實現(xiàn)dll框架

這是一段可以實現(xiàn)監(jiān)控Windows事件的dll代碼,使用VS2022選擇C++ 應用程序擴展創(chuàng)建之后只需要修改 dllmain.cpp 的代碼即可,無需其它任何配置,使用 release x64 build之后就可以被其它應用程序調(diào)用


#include "pch.h"

#include <windows.h>

#include <string>

//基礎C++的dll代碼框架

// 共享內(nèi)存區(qū)定義

//將 g_hMainWnd 和 g_hEventHook 放在共享內(nèi)存區(qū)

//RWS 標志表示該段具有 Read/Write/Shared 屬性,確保多進程可訪問同一內(nèi)存區(qū)域

//g_hMainWnd 是主窗口的句柄,用于接收事件通知

//g_hEventHook 是事件鉤子的句柄,用于監(jiān)聽窗口事件

#pragma data_seg(".SHARED")

HWND g_hMainWnd = NULL;

HWINEVENTHOOK g_hEventHook = NULL;

#pragma data_seg()

#pragma comment(linker, "/SECTION:.SHARED,RWS")

//事件處理函數(shù),是一個回調(diào)函數(shù),在事件發(fā)生時被調(diào)用,需要導出為C風格的函數(shù)

//參數(shù)說明:

// hWinEventHook: 事件鉤子的句柄

// event: 事件類型

// hwnd: 事件發(fā)生的窗口句柄

// idObject: 事件對象的ID

// idChild: 事件子對象的ID

// dwEventThread: 事件發(fā)生的線程ID

// dwmsEventTime: 事件發(fā)生的時間戳

extern "C" __declspec(dllexport)

void CALLBACK WinEventProc(

? ? HWINEVENTHOOK hWinEventHook,

? ? DWORD event,

? ? HWND hwnd,

? ? LONG idObject,

? ? LONG idChild,

? ? DWORD dwEventThread,

? ? DWORD dwmsEventTime)

{

//IsWindow是一個API函數(shù),用于檢查指定的窗口句柄是否有效,必須在調(diào)用startMonitoring函數(shù)中傳遞窗口句柄,否則就直接返回

? ? if (!IsWindow(g_hMainWnd)) {

? ? ? ? return;

? ? }

? ? //如果沒有標題就直接退出...

? ? wchar_t buf[256] = { 0 };

? ? if (!GetWindowTextW(hwnd, buf, _countof(buf))) {

? ? ? ? return;

? ? }

//這里創(chuàng)建一個 COPYDATASTRUCT 結(jié)構體,用于發(fā)送窗口標題到主程序

//這個結(jié)構體包含三個成員:

// dwData: 用于標識數(shù)據(jù)類型,這里使用事件類型

// cbData: 數(shù)據(jù)的大小,這里使用窗口標題的長度

// lpData: 指向數(shù)據(jù)的指針,這里使用窗口標題的緩沖區(qū)

? ? COPYDATASTRUCT cds = { 0 };

? ? cds.dwData = event;

? ? cds.cbData = (wcslen(buf) + 1) * sizeof(wchar_t);

? ? cds.lpData = buf;

? ? // 調(diào)試輸出標題(可選)

? ? //OutputDebugStringW(L"窗口標題: ");

? ? //OutputDebugStringW(buf);

? ? //發(fā)送窗口標題到主程序(有些事件并沒有)

? ? if (!SendMessageW(g_hMainWnd, WM_COPYDATA, 0, (LPARAM)&cds)) {

? ? ? ? DWORD err = GetLastError();

? ? ? ? wchar_t msg[64];

? ? ? ? swprintf(msg, _countof(msg), L"消息發(fā)送失敗: %d", err);

? ? ? ? //OutputDebugStringW(msg);

? ? }

}

//導出函數(shù),用于開始監(jiān)控窗口事件

//參數(shù)說明:

// hCallbackWnd: 主窗口的句柄,用于接收事件通知,如果不需要接收事件通知,可以傳NULL

//將 hcallbackWnd 存儲在共享內(nèi)存區(qū) g_hMainWnd 中,用于在事件處理函數(shù)中發(fā)送消息到主窗口

//setWinEventHook 函數(shù)用于設置事件鉤子,監(jiān)聽指定范圍的窗口事件,在這里監(jiān)聽所有事件,WINEVENT_OUTOFCONTEXT 標志表示事件處理函數(shù)在非鉤子線程中調(diào)用,

//而是位于獨立線程中,被系統(tǒng)自行調(diào)度使用,無需注入到目標進程中.這是區(qū)別于消息hook的地方,消息鉤子需要注入到目標進程中,而事件鉤子不需要.

//setwineventhook 函數(shù)的參數(shù)說明:

// eventMin: 監(jiān)聽的最小事件類型,這里設置為 EVENT_MIN,表示監(jiān)聽所有事件

// eventMax: 監(jiān)聽的最大事件類型,這里設置為 EVENT_MAX,表示監(jiān)聽所有事件

// hmodWinEventProc: 事件處理函數(shù)所在的模塊句柄,這里設置為 NULL,表示使用當前進程的模塊

// pfnWinEventProc: 事件處理函數(shù)的指針,這里設置為 WinEventProc,表示使用上面定義的事件處理函數(shù)

// idProcess: 監(jiān)聽的進程ID,這里設置為 0,表示監(jiān)聽所有進程

// idThread: 監(jiān)聽的線程ID,這里設置為 0,表示監(jiān)聽所有線程

// dwFlags: 監(jiān)聽標志,這里設置為 WINEVENT_OUTOFCONTEXT,表示事件處理函數(shù)在非鉤子線程中調(diào)用

extern "C" __declspec(dllexport)

BOOL APIENTRY StartMonitoring(HWND hCallbackWnd) {

? ? g_hMainWnd = hCallbackWnd;

? ? g_hEventHook = SetWinEventHook(

? ? ? ? EVENT_MIN, EVENT_MAX,

? ? ? ? NULL, WinEventProc,

? ? ? ? 0, 0,

? ? ? ? WINEVENT_OUTOFCONTEXT);

? ? return g_hEventHook != NULL;

}

//導出函數(shù),用于停止監(jiān)控窗口事件

//該函數(shù)會取消之前設置的事件鉤子,釋放資源

//unhookwinevent 函數(shù)用于取消事件鉤子,釋放資源

extern "C" __declspec(dllexport)

BOOL APIENTRY StopMonitoring() {

? ? return UnhookWinEvent(g_hEventHook);

}

// DLL入口點函數(shù),用于處理DLL的加載和卸載事件

// 當DLL被加載或卸載時,系統(tǒng)會調(diào)用這個函數(shù)

// 參數(shù)說明:

// hModule: DLL模塊的句柄

// ul_reason: 卸載原因,可以是 DLL_PROCESS_ATTACH, DLL_THREAD_ATTACH, DLL_THREAD_DETACH, DLL_PROCESS_DETACH

// lpReserved: 保留參數(shù),通常為NULL

// 在這里處理 DLL_PROCESS_DETACH 事件,即當DLL被卸載時,取消事件鉤子

//dll卸載過程是在所有線程都結(jié)束后,才會調(diào)用 DllMain 函數(shù),因此可以安全地取消事件鉤子

// 其他事件可以忽略,因為我們只關心 DLL_PROCESS_DETACH 事件

//返回值是固定的 TRUE,表示 DLL 的入口點函數(shù)執(zhí)行成功

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason, LPVOID lpReserved) {

? ? switch (ul_reason) {

? ? case DLL_PROCESS_DETACH:

? ? ? ? if (g_hEventHook) UnhookWinEvent(g_hEventHook);

? ? ? ? break;

? ? }

? ? return TRUE;

}

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容