日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

消息钩子学习工程

發布時間:2023/12/2 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 消息钩子学习工程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
  • 前奏
近來一直在自學Windows Hook相關的知識,已經嘗試多種注入方式。尤其對消息鉤子方式很感興趣,因為看到Spy++能夠截獲系統中絕大多數應用的消息流,就很想知道它的工作原理,打算制作屬于自己的Spy++。
  • 消息鉤子簡介:
消息鉤子簡言之就是Windows處理消息的一個平臺,用戶可以在此平臺獲取或過濾所需應用的消息(例如某鼠標位置,鍵盤擊下等),這些被監控的消息都會在目標窗口處理函數之前被截獲。系統在拿到消息后會問你:這是不是你想要的消息?如果是,則恭喜你,你可以在回調函數里做相應操作了。
  • 消息鉤子函數背景
消息鉤子主要由三部分組成:
  • 鉤子安裝函數
  • 鉤子回調函數
  • 鉤子卸載函數
    • 鉤子安裝函數原型:
    HHOOK WINAPI SetWindowsHookEx(_In_ int idHook,_In_ HOOKPROC lpfn,_In_ HINSTANCE hMod,_In_ DWORD dwThreadId );SetWindowsHookExx1HHOOK WINAPI SetWindowsHookEx(2 ?_In_ ?int idHook,3 ?_In_ ?HOOKPROC lpfn,4 ?_In_ ?HINSTANCE hMod,5 ?_In_ ?DWORD dwThreadId6);參數1-idHook:這個函數代表了你要安裝鉤子的種類,比如鍵盤鉤子,鼠標鉤子,窗體鉤子等等。以下我列了一張表,結合MSDN供大家參考。
    鉤子類型釋義
    WH_CALLWNDPROC(4)此類型的鉤子,可以讓你監控發送到窗口過程的消息。
    WH_CALLWNDPROCRET(12)此類型的鉤子,可以讓你監控到已被目標窗體處理的消息。
    WH_CBT(5)此類型的鉤子十分繁雜,可監控的消息很多。例如窗口創立,銷毀,最大最小化,移動等。
    WH_DEBUG(9)
    此類型鉤子,可以決定能否讓系統調用與其他Hook關聯的子程序。說白了,這就是個調試鉤子,可以用來調試其他安裝好的鉤子。
    WH_FOREGROUNDIDLE(11)此類型鉤子,可以在前臺線程空閑時執行低優先級的任務,當然了,線程空閑是由系統決定的。
    WH_GETMESSAGE(3)此類型的鉤子,可以截獲消息隊列中的所有消息。例如GetMessage,PeekMessage函數的返回消息。
    WH_JOURNALPLAYBACK
    (1)
    此類型的鉤子,可以插入消息到消息隊列。除此,這個鉤子可以記錄下來連續的鼠標及鍵盤事件,以用來回放。
    WH_JOURNALRECORD(0)
    此類型的鉤子,用以監視發往系統隊列的輸入事件,這是個全局鉤子,不可用于線程。
    WH_KEYBOARD(2)此類型的鉤子,顧名思義,用于監視鍵盤擊下,彈起消息。通過GetMessage,PeekMessage函數返回。(請注意,根據我的實驗結果,這個鉤子僅對本程序有效)
    WH_KEYBOARD_LL(13)
    此類型的鉤子,是底層設備鉤子,除具備WH_KEYBOARD的功能,可以記錄所有的鍵盤輸入,包括熱鍵。
    WH_MOUSE(7)
    此類型的鉤子,顧名思義,用于監視輸入到消息隊列的鼠標消息。通過GetMessage,PeekMessage函數返回。(只能獲得鉤子所在模塊的消息)
    WH_MOUSE_LL(14)
    此類型的鉤子,是底層設備鉤子,除具備WH_KEYBOARD的功能,可以記錄系統中所有的鼠標消息。
    WH_MSGFILTER(-1)
    此類型的鉤子,可監視由對話框、消息框、菜單條、或滾動條中的輸入事件引發的消息。
    WH_SHELL(10)
    此類型的鉤子,可以監視各種Shell事件信息,例如應用程序的啟動,關閉等等。
    WH_SYSMSGFILTER(6)
    此類型的鉤子,是強化版的WH_MSGFILTER,可以監視系統中所有應用程序的此類消息。
    參數2-HOOKPROC lpfn:此參數是鉤子回調函數的地址,對應上述不同種類的鉤子類型,其鉤子回調函數原型基本是一致的。請見下(需要注意的是,wParam和lParam針對不同類型的鉤子,傳遞參數所代表意義不同,因種類繁多,請各位查閱MSDN):LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam ) {// process event...return CallNextHookEx(NULL, nCode, wParam, lParam); }121LRESULT CALLBACK HookProc(2 ?int nCode, 3 ?WPARAM wParam, 4 ?LPARAM lParam5)6{7 ? // process event8 ? ...910 ? return CallNextHookEx(NULL, nCode, wParam, lParam);11}nCode:int,此參數指示Hook例程是否需要處理消息,如果nCode為HC_ACTION,則需要處理;如果小于0,不予處理,須調用CallNextHookEx函數返回。wParam與lParam:針對不同類型的鉤子,代表的意義不同,但總體是針對當前類型鉤子的消息。后面以例子做出驗證。參數3-HINSTANCE hMod:包含Hook例程的Dll所在模塊基址。參數4-DWORD dwThreadId:所要注入程序的主線程ID。如果此項填0,則代表鉤子為系統鉤子,基本所有在運行的進程都會被注入。如果此項指定線程ID,則是有針對性的線程鉤子。返回值:HHOOK類型的句柄。
    • 鉤子回調函數
    請見上。
    • 鉤子卸載函數
    BOOL WINAPI UnhookWindowsHookEx(_In_ HHOOK hhk );1BOOL WINAPI UnhookWindowsHookEx(2 ?_In_ ?HHOOK hhk3);參數:SetWindowsHookEx的返回值。
    • 鍵盤消息鉤子及CBT鉤子程序代碼
    首先我們要明確下,鉤子從安裝到回顯的流程
  • 編寫Dll,在Dll中實現我們所需要的鉤子回調函數及安裝函數。
  • Dll中除了要編寫與鉤子相關的處理函數,也要編寫與顯示程序通信的模塊,以便驗證鉤子消息的正確性。
  • Dll需要導出鉤子啟動函數與卸載函數。
  • 回顯程序處理已安裝鉤子發送的信息。
  • 至此,框架已經明了,我們分步拆解完成這個小項目。(整體代碼請見附件,VS2013編譯)
    • 結構體及枚舉的定義
    typedef struct COMMPACK {int nType;//Hook類型WPARAM wParam;//參數1LPARAM lParam;//參數2TCHAR szMsg[16];//額外的字符串信息,取決于具體鉤子 } COMMPACK, *PCOMMPACK;//與回顯程序通訊的包結構typedef struct HOOKSTC {int nType;//Hook類型HOOKPROC hkproc;//Hook回調HHOOK hhook;//Hook句柄 } HOOKSTC, *PHOOKSTC;HOOKSTC m_Array4Hooks[NHOOKNUMS] = { 0 };//創建多鉤子類型的結構體數組enum { M_CALLWNDPROC, M_CBT, M_DEBUG, M_GETMESSAGE, M_KEYBOARD, M_MOUSE, M_MSGFILTER };//鉤子類型枚舉enum { IDHCBT_ACTIVATE, IDHCBT_CLICKSKIPPED, IDHCBT_CREATEWND, IDHCBT_DESTROYWND, IDHCBT_KEYSKIPPED,IDHCBT_MINMAX, IDHCBT_MOVESIZE, IDHCBT_QS, IDHCBT_SETFOCUS, IDHCBT_SYSCOMMAND, IDUnknown };//CBT鉤子的消息群221typedef struct COMMPACK2{3 int nType;//Hook類型4 WPARAM wParam;//參數15 LPARAM lParam;//參數26 TCHAR szMsg[16];//額外的字符串信息,取決于具體鉤子7} COMMPACK, *PCOMMPACK;//與回顯程序通訊的包結構89typedef struct HOOKSTC10{11 int nType;//Hook類型12 HOOKPROC hkproc;//Hook回調13 HHOOK hhook;//Hook句柄14} HOOKSTC, *PHOOKSTC;1516HOOKSTC m_Array4Hooks[NHOOKNUMS] = { 0 };//創建多鉤子類型的結構體數組1718enum { M_CALLWNDPROC, M_CBT, M_DEBUG, M_GETMESSAGE, M_KEYBOARD, M_MOUSE, M_MSGFILTER };//鉤子類型枚舉1920enum { IDHCBT_ACTIVATE, IDHCBT_CLICKSKIPPED, IDHCBT_CREATEWND, IDHCBT_DESTROYWND, IDHCBT_KEYSKIPPED,21 IDHCBT_MINMAX, IDHCBT_MOVESIZE, IDHCBT_QS, IDHCBT_SETFOCUS, IDHCBT_SYSCOMMAND, IDUnknown22};//CBT鉤子的消息群
    • CBT鉤子的回調函數
    LRESULT WINAPI m_CBTProc(int nCode, WPARAM wParam, LPARAM lParam) {if (nCode < 0)return CallNextHookEx(m_Array4Hooks[M_CBT].hhook, nCode, wParam, lParam);CHAR szCode[16] = { 0 };PCOMMPACK pCP = new COMMPACK;pCP->nType = M_CBT;switch (nCode){case HCBT_ACTIVATE://系統要激活一個窗口pCP->lParam = (LPARAM)IDHCBT_ACTIVATE;pCP->wParam = IDHCBT_ACTIVATE;break;case HCBT_CLICKSKIPPED://系統已經從系統消息隊列中刪除了一個鼠標消息pCP->lParam = (LPARAM)IDHCBT_CLICKSKIPPED;pCP->wParam = IDHCBT_CLICKSKIPPED;break;case HCBT_CREATEWND://一個窗口將要被創建pCP->lParam = (LPARAM)IDHCBT_CREATEWND;pCP->wParam = IDHCBT_CREATEWND;break;case HCBT_DESTROYWND://一個窗口將要被銷毀pCP->lParam = (LPARAM)IDHCBT_DESTROYWND;pCP->wParam = IDHCBT_DESTROYWND;break;case HCBT_KEYSKIPPED://系統已從系統消息隊列中刪除了一個鍵盤消息pCP->lParam = (LPARAM)IDHCBT_KEYSKIPPED;pCP->wParam = IDHCBT_KEYSKIPPED;break;case HCBT_MINMAX://一個窗口將被最小化或最大化pCP->lParam = (LPARAM)IDHCBT_MINMAX;pCP->wParam = IDHCBT_MINMAX;break;case HCBT_MOVESIZE://一個窗口將被移動或改變尺寸pCP->lParam = (LPARAM)IDHCBT_MOVESIZE;pCP->wParam = IDHCBT_MOVESIZE;break;case HCBT_QS://系統已從系統消息隊列中取到一個WM_QUEUESYNC 消息pCP->lParam = (LPARAM)IDHCBT_QS;pCP->wParam = IDHCBT_QS;break;case HCBT_SETFOCUS://一個窗口將要獲得鍵盤焦點pCP->lParam = (LPARAM)IDHCBT_SETFOCUS;pCP->wParam = IDHCBT_SETFOCUS;break;case HCBT_SYSCOMMAND://一個系統命令將被執行pCP->lParam = (LPARAM)IDHCBT_SYSCOMMAND;pCP->wParam = IDHCBT_SYSCOMMAND;break;default://其他pCP->lParam = (LPARAM)IDUnknown;pCP->wParam = IDUnknown;break;}m_Com(pCP);//與回顯程序通信delete pCP;return CallNextHookEx(m_Array4Hooks[M_CBT].hhook, nCode, wParam, lParam); }561571LRESULT WINAPI m_CBTProc(int nCode, WPARAM wParam, LPARAM lParam)2{3 if (nCode < 0)return CallNextHookEx(m_Array4Hooks[M_CBT].hhook, nCode, wParam, lParam);4 CHAR szCode[16] = { 0 };5 PCOMMPACK pCP = new COMMPACK;6 pCP->nType = M_CBT;7 switch (nCode)8 {9 case HCBT_ACTIVATE://系統要激活一個窗口10 pCP->lParam = (LPARAM)IDHCBT_ACTIVATE;11 pCP->wParam = IDHCBT_ACTIVATE;12 break;13 case HCBT_CLICKSKIPPED://系統已經從系統消息隊列中刪除了一個鼠標消息14 pCP->lParam = (LPARAM)IDHCBT_CLICKSKIPPED;15 pCP->wParam = IDHCBT_CLICKSKIPPED;16 break;17 case HCBT_CREATEWND://一個窗口將要被創建18 pCP->lParam = (LPARAM)IDHCBT_CREATEWND;19 pCP->wParam = IDHCBT_CREATEWND;20 break;21 case HCBT_DESTROYWND://一個窗口將要被銷毀22 pCP->lParam = (LPARAM)IDHCBT_DESTROYWND;23 pCP->wParam = IDHCBT_DESTROYWND;24 break;25 case HCBT_KEYSKIPPED://系統已從系統消息隊列中刪除了一個鍵盤消息26 pCP->lParam = (LPARAM)IDHCBT_KEYSKIPPED;27 pCP->wParam = IDHCBT_KEYSKIPPED;28 break;29 case HCBT_MINMAX://一個窗口將被最小化或最大化30 pCP->lParam = (LPARAM)IDHCBT_MINMAX;31 pCP->wParam = IDHCBT_MINMAX;32 break;33 case HCBT_MOVESIZE://一個窗口將被移動或改變尺寸34 pCP->lParam = (LPARAM)IDHCBT_MOVESIZE;35 pCP->wParam = IDHCBT_MOVESIZE;36 break;37 case HCBT_QS://系統已從系統消息隊列中取到一個WM_QUEUESYNC 消息38 pCP->lParam = (LPARAM)IDHCBT_QS;39 pCP->wParam = IDHCBT_QS;40 break;41 case HCBT_SETFOCUS://一個窗口將要獲得鍵盤焦點42 pCP->lParam = (LPARAM)IDHCBT_SETFOCUS;43 pCP->wParam = IDHCBT_SETFOCUS;44 break;45 case HCBT_SYSCOMMAND://一個系統命令將被執行46 pCP->lParam = (LPARAM)IDHCBT_SYSCOMMAND;47 pCP->wParam = IDHCBT_SYSCOMMAND;48 break;49 default://其他50 pCP->lParam = (LPARAM)IDUnknown;51 pCP->wParam = IDUnknown;52 break;53 }54 m_Com(pCP);//與回顯程序通信55 delete pCP;56 return CallNextHookEx(m_Array4Hooks[M_CBT].hhook, nCode, wParam, lParam);57}
    • 鍵盤鉤子的回調函數
    LRESULT WINAPI m_KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {if ((nCode < 0 || !((DWORD)lParam & 0x40000000)))return CallNextHookEx(m_Array4Hooks[M_KEYBOARD].hhook, nCode, wParam, lParam);PCOMMPACK pCP = new COMMPACK;pCP->lParam = lParam;pCP->wParam = wParam;//這個值就是按鍵的VirtualKeypCP->nType = M_KEYBOARD;m_Com(pCP);//與回顯程序通訊delete pCP;return CallNextHookEx(m_Array4Hooks[M_KEYBOARD].hhook, nCode, wParam, lParam); }111LRESULT WINAPI m_KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)2{3 if ((nCode < 0 || !((DWORD)lParam & 0x40000000)))return CallNextHookEx(m_Array4Hooks[M_KEYBOARD].hhook, nCode, wParam, lParam);4 PCOMMPACK pCP = new COMMPACK;5 pCP->lParam = lParam;6 pCP->wParam = wParam;//這個值就是按鍵的VirtualKey7 pCP->nType = M_KEYBOARD;8 m_Com(pCP);//與回顯程序通訊9 delete pCP;10 return CallNextHookEx(m_Array4Hooks[M_KEYBOARD].hhook, nCode, wParam, lParam);11}
    • 與回顯程序通訊的函數
    void m_Com(PCOMMPACK& pCP, int addi) {hTarget = ::FindWindow(NULL, L"HookApp");//尋找回顯程序窗口標題COPYDATASTRUCT stcCDS;//采用WM_COPYDATA消息方式進程間通訊stcCDS.cbData = sizeof(COMMPACK);stcCDS.dwData = addi;stcCDS.lpData = pCP;//打包消息結構體::SendMessage(hTarget, WM_COPYDATA, 0, (LPARAM)&stcCDS); }1void m_Com(PCOMMPACK& pCP, int addi)2{3 hTarget = ::FindWindow(NULL, L"HookApp");//尋找回顯程序窗口標題4 COPYDATASTRUCT stcCDS;//采用WM_COPYDATA消息方式進程間通訊5 stcCDS.cbData = sizeof(COMMPACK);6 stcCDS.dwData = addi;7 stcCDS.lpData = pCP;//打包消息結構體8 ::SendMessage(hTarget, WM_COPYDATA, 0, (LPARAM)&stcCDS);9}
    • 鉤子初始化函數
    void InitHooks() {hTarget = ::FindWindow(NULL, L"HookApp");m_Array4Hooks[M_CALLWNDPROC].hkproc = m_CallWndProc;m_Array4Hooks[M_CALLWNDPROC].nType = WH_CALLWNDPROC;m_Array4Hooks[M_CBT].hkproc = m_CBTProc;m_Array4Hooks[M_CBT].nType = WH_CBT;//m_Array4Hooks[M_DEBUG]->hkproc = m_DebugProc;//m_Array4Hooks[M_DEBUG]->nType = WH_DEBUG;//m_Array4Hooks[M_GETMESSAGE]->hkproc = m_GetMsgProc;//m_Array4Hooks[M_GETMESSAGE]->nType = WH_GETMESSAGE;m_Array4Hooks[M_KEYBOARD].hkproc = m_KeyboardProc;m_Array4Hooks[M_KEYBOARD].nType = WH_KEYBOARD;m_Array4Hooks[M_MOUSE].hkproc = m_MouseProc;m_Array4Hooks[M_MOUSE].nType = WH_MOUSE;//m_Array4Hooks[M_MSGFILTER]->hkproc = m_MessageFilterProc;//m_Array4Hooks[M_MSGFILTER]->nType = WH_MSGFILTER;for (int i = 0; i < NHOOKNUMS; ++i){m_Array4Hooks[i].hhook = 0;} }x1void InitHooks()2{3 hTarget = ::FindWindow(NULL, L"HookApp");4 m_Array4Hooks[M_CALLWNDPROC].hkproc = m_CallWndProc;5 m_Array4Hooks[M_CALLWNDPROC].nType = WH_CALLWNDPROC;6 m_Array4Hooks[M_CBT].hkproc = m_CBTProc;7 m_Array4Hooks[M_CBT].nType = WH_CBT;8 //m_Array4Hooks[M_DEBUG]->hkproc = m_DebugProc;9 //m_Array4Hooks[M_DEBUG]->nType = WH_DEBUG;10 //m_Array4Hooks[M_GETMESSAGE]->hkproc = m_GetMsgProc;11 //m_Array4Hooks[M_GETMESSAGE]->nType = WH_GETMESSAGE;12 m_Array4Hooks[M_KEYBOARD].hkproc = m_KeyboardProc;13 m_Array4Hooks[M_KEYBOARD].nType = WH_KEYBOARD;14 m_Array4Hooks[M_MOUSE].hkproc = m_MouseProc;15 m_Array4Hooks[M_MOUSE].nType = WH_MOUSE;16 //m_Array4Hooks[M_MSGFILTER]->hkproc = m_MessageFilterProc;17 //m_Array4Hooks[M_MSGFILTER]->nType = WH_MSGFILTER;18 for (int i = 0; i < NHOOKNUMS; ++i)19 {20 m_Array4Hooks[i].hhook = 0;21 }22}
    • 鉤子安裝及卸載函數
    void InstallHook(DWORD dwProcessID) {g_dwThreadID = GetThreadInfo(dwProcessID);//由注入器傳入指定注入進程ID,遍歷獲得主線程IDInitHooks();//初始化鉤子for (int i = 0; i < NHOOKNUMS; ++i){if (m_Array4Hooks[i].hkproc == NULL)continue;m_Array4Hooks[i].hhook = SetWindowsHookEx(m_Array4Hooks[i].nType, m_Array4Hooks[i].hkproc, g_Module, g_dwThreadID);} }void UnInstallHook() {for (int i = 0; i < NHOOKNUMS; ++i){UnhookWindowsHookEx(m_Array4Hooks[i].hhook);} }121void InstallHook(DWORD dwProcessID)2{3 g_dwThreadID = GetThreadInfo(dwProcessID);//由注入器傳入指定注入進程ID,遍歷獲得主線程ID45 InitHooks();//初始化鉤子67 for (int i = 0; i < NHOOKNUMS; ++i)8 {9 if (m_Array4Hooks[i].hkproc == NULL)continue;10 m_Array4Hooks[i].hhook = SetWindowsHookEx(m_Array4Hooks[i].nType, m_Array4Hooks[i].hkproc, g_Module, g_dwThreadID);11 }12}1314void UnInstallHook()15{16 for (int i = 0; i < NHOOKNUMS; ++i)17 {18 UnhookWindowsHookEx(m_Array4Hooks[i].hhook);19 }20}
    • 線程遍歷函數
    DWORD GetThreadInfo(DWORD dwProcessID) {HANDLE hSnThread = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);if (hSnThread == INVALID_HANDLE_VALUE) {return 0;}// 開始遍歷線程THREADENTRY32 threadEntry = { sizeof(THREADENTRY32) };// 獲取快照中的第一個線程的信息Thread32First(hSnThread, &threadEntry);DWORD dwSuspendCount = 0;do {// 判斷遍歷到的線程是否屬于這個進程的.if (threadEntry.th32OwnerProcessID == dwProcessID) {return threadEntry.th32ThreadID;}// 獲取快照中的下一個線程信息} while (Thread32Next(hSnThread, &threadEntry));return 1; }251DWORD GetThreadInfo(DWORD dwProcessID)2{3 HANDLE hSnThread = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);4 if (hSnThread == INVALID_HANDLE_VALUE) {5 return 0;6 }78 // 開始遍歷線程9 THREADENTRY32 threadEntry = { sizeof(THREADENTRY32) };1011 // 獲取快照中的第一個線程的信息12 Thread32First(hSnThread, &threadEntry);1314 DWORD dwSuspendCount = 0;15 do {1617 // 判斷遍歷到的線程是否屬于這個進程的.18 if (threadEntry.th32OwnerProcessID == dwProcessID) {19 return threadEntry.th32ThreadID;20 }21 // 獲取快照中的下一個線程信息22 } while (Thread32Next(hSnThread, &threadEntry));23 return 1;24}
    • 函數導出
    EXTERN_C _declspec(dllexport) void InstallHook(DWORD dwProcessID); EXTERN_C _declspec(dllexport) void UnInstallHook();1EXTERN_C _declspec(dllexport) void InstallHook(DWORD dwProcessID);2EXTERN_C _declspec(dllexport) void UnInstallHook();
    至此DLL部分結束,開始回顯程序的消息處理BOOL CHookAppDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) {// TODO: 在此添加消息處理程序代碼和/或調用默認值static int nIndex = 0;PCOMMPACK pCP = new COMMPACK;pCP = (PCOMMPACK)pCopyDataStruct->lpData;switch (pCP->nType)//根據消息的類型進行定義{case M_CALLWNDPROC:{}break;case M_CBT:{static int nIndex = 0;CString strCallWndProc;switch (pCP->wParam){case IDHCBT_ACTIVATE:{strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_ACTIVATE", pCP->wParam);strCallWndProc += L"\r\n";m_StrCBT += strCallWndProc;UpdateData(FALSE);++nIndex;}break;case IDHCBT_CLICKSKIPPED:{strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_CLICKSKIPPED", pCP->wParam);strCallWndProc += L"\r\n";m_StrCBT += strCallWndProc;UpdateData(FALSE);++nIndex;}break;case IDHCBT_CREATEWND:{strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_CLICKSKIPPED", pCP->wParam);strCallWndProc += L"\r\n";m_StrCBT += strCallWndProc;UpdateData(FALSE);++nIndex;}break;case IDHCBT_DESTROYWND:{strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_DESTROYWND", pCP->wParam);strCallWndProc += L"\r\n";m_StrCBT += strCallWndProc;UpdateData(FALSE);++nIndex;}break;case IDHCBT_KEYSKIPPED:{strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_KEYSKIPPED", pCP->wParam);strCallWndProc += L"\r\n";m_StrCBT += strCallWndProc;UpdateData(FALSE);++nIndex;}break;case IDHCBT_MINMAX:{strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_MINMAX", pCP->wParam);strCallWndProc += L"\r\n";m_StrCBT += strCallWndProc;UpdateData(FALSE);++nIndex;}break;case IDHCBT_MOVESIZE:{strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_MOVESIZE", pCP->wParam);strCallWndProc += L"\r\n";m_StrCBT += strCallWndProc;UpdateData(FALSE);++nIndex;}break;case IDHCBT_QS:{strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_QS", pCP->wParam);strCallWndProc += L"\r\n";m_StrCBT += strCallWndProc;UpdateData(FALSE);++nIndex;}break;case IDHCBT_SETFOCUS:{strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_SETFOCUS", pCP->wParam);strCallWndProc += L"\r\n";m_StrCBT += strCallWndProc;UpdateData(FALSE);++nIndex;}break;case IDHCBT_SYSCOMMAND:{strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_SYSCOMMAND", pCP->wParam);strCallWndProc += L"\r\n";m_StrCBT += strCallWndProc;UpdateData(FALSE);++nIndex;}break;case IDUnknown:{strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"Unknown", pCP->wParam);strCallWndProc += L"\r\n";m_StrCBT += strCallWndProc;UpdateData(FALSE);++nIndex;}break;default:break;}}break;case M_DEBUG:{}break;case M_GETMESSAGE:{}break;case M_KEYBOARD:{static int nIndex = 0;CString strCallWndProc;strCallWndProc.Format(L"KEYBOARD [%d] - VK: %c ", nIndex, char(pCP->wParam));strCallWndProc += L"\r\n";m_StrKeyBoard += strCallWndProc;UpdateData(FALSE);++nIndex;}break;case M_MOUSE:{}break;case M_MSGFILTER:{}break;default:break;}return CDialogEx::OnCopyData(pWnd, pCopyDataStruct); } x1BOOL CHookAppDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)2{3 // TODO: 在此添加消息處理程序代碼和/或調用默認值4 static int nIndex = 0;5 PCOMMPACK pCP = new COMMPACK;6 pCP = (PCOMMPACK)pCopyDataStruct->lpData;78 switch (pCP->nType)//根據消息的類型進行定義9 {10 case M_CALLWNDPROC:11 {1213 }break;1415 case M_CBT:16 {17 static int nIndex = 0;18 CString strCallWndProc;19 switch (pCP->wParam)20 {21 case IDHCBT_ACTIVATE:22 {23 strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_ACTIVATE", pCP->wParam);24 strCallWndProc += L"\r\n";25 m_StrCBT += strCallWndProc;26 UpdateData(FALSE);27 ++nIndex;28 }break;29 case IDHCBT_CLICKSKIPPED:30 {31 strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_CLICKSKIPPED", pCP->wParam);32 strCallWndProc += L"\r\n";33 m_StrCBT += strCallWndProc;34 UpdateData(FALSE);35 ++nIndex;36 }break;37 case IDHCBT_CREATEWND:38 {39 strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_CLICKSKIPPED", pCP->wParam);40 strCallWndProc += L"\r\n";41 m_StrCBT += strCallWndProc;42 UpdateData(FALSE);43 ++nIndex;44 }break;45 case IDHCBT_DESTROYWND:46 {47 strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_DESTROYWND", pCP->wParam);48 strCallWndProc += L"\r\n";49 m_StrCBT += strCallWndProc;50 UpdateData(FALSE);51 ++nIndex;52 }break;53 case IDHCBT_KEYSKIPPED:54 {55 strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_KEYSKIPPED", pCP->wParam);56 strCallWndProc += L"\r\n";57 m_StrCBT += strCallWndProc;58 UpdateData(FALSE);59 ++nIndex;60 }break;61 case IDHCBT_MINMAX:62 {63 strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_MINMAX", pCP->wParam);64 strCallWndProc += L"\r\n";65 m_StrCBT += strCallWndProc;66 UpdateData(FALSE);67 ++nIndex;68 }break;69 case IDHCBT_MOVESIZE:70 {71 strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_MOVESIZE", pCP->wParam);72 strCallWndProc += L"\r\n";73 m_StrCBT += strCallWndProc;74 UpdateData(FALSE);75 ++nIndex;76 }break;77 case IDHCBT_QS:78 {79 strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_QS", pCP->wParam);80 strCallWndProc += L"\r\n";81 m_StrCBT += strCallWndProc;82 UpdateData(FALSE);83 ++nIndex;84 }break;85 case IDHCBT_SETFOCUS:86 {87 strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_SETFOCUS", pCP->wParam);88 strCallWndProc += L"\r\n";89 m_StrCBT += strCallWndProc;90 UpdateData(FALSE);91 ++nIndex;92 }break;93 case IDHCBT_SYSCOMMAND:94 {95 strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"HCBT_SYSCOMMAND", pCP->wParam);96 strCallWndProc += L"\r\n";97 m_StrCBT += strCallWndProc;98 UpdateData(FALSE);99 ++nIndex;100 }break;101 case IDUnknown:102 {103 strCallWndProc.Format(L"CBT [%d] - nCode: %s, tsk: %ld ", nIndex, L"Unknown", pCP->wParam);104 strCallWndProc += L"\r\n";105 m_StrCBT += strCallWndProc;106 UpdateData(FALSE);107 ++nIndex;108 }break;109 default:110 break;111 }112 }break;113 case M_DEBUG:114 {115116 }break;117 case M_GETMESSAGE:118 {119120 }break;121 case M_KEYBOARD:122 {123 static int nIndex = 0;124 CString strCallWndProc;125 strCallWndProc.Format(L"KEYBOARD [%d] - VK: %c ", nIndex, char(pCP->wParam));126 strCallWndProc += L"\r\n";127 m_StrKeyBoard += strCallWndProc;128 UpdateData(FALSE);129 ++nIndex;130 131 }break;132 case M_MOUSE:133 {134 ? ? ? ?135 }break;136 case M_MSGFILTER:137 {138139 }break;140141 default:142 break;143 }144145 return CDialogEx::OnCopyData(pWnd, pCopyDataStruct);146}147
    注入器部分代碼:BOOL _Inject_::m_WindowsHook(PWCHAR pszDllName, LPCSTR pszDllProc, DWORD dwPID) {typedef void* (*HookOnProto)(DWORD);//聲明導出函數原型HookOnProto HookOn;hInstDll = LoadLibrary(pszDllName);if (hInstDll == NULL)return FALSE;HookOn = (HookOnProto)GetProcAddress(hInstDll, pszDllProc);//從指定Dll導出所需函數if (HookOn == NULL)return FALSE;HookOn(dwPID);//鉤子安裝return TRUE; }BOOL _Inject_::m_UnWinHook(PWCHAR pszDllName, LPCSTR pszDllProc) {typedef void* (*HookOffProto)(void);HookOffProto HookOff;HookOff = (HookOffProto)GetProcAddress(hInstDll, pszDllProc);if (HookOff == NULL)return FALSE;HookOff(); }241BOOL _Inject_::m_WindowsHook(PWCHAR pszDllName, LPCSTR pszDllProc, DWORD dwPID)2{3 typedef void* (*HookOnProto)(DWORD);//聲明導出函數原型4 HookOnProto HookOn;5 hInstDll = LoadLibrary(pszDllName);6 if (hInstDll == NULL)return FALSE;78 HookOn = (HookOnProto)GetProcAddress(hInstDll, pszDllProc);//從指定Dll導出所需函數9 if (HookOn == NULL)return FALSE;1011 HookOn(dwPID);//鉤子安裝1213 return TRUE;14}1516BOOL _Inject_::m_UnWinHook(PWCHAR pszDllName, LPCSTR pszDllProc)17{18 typedef void* (*HookOffProto)(void);19 HookOffProto HookOff;2021 HookOff = (HookOffProto)GetProcAddress(hInstDll, pszDllProc);22 if (HookOff == NULL)return FALSE;23 HookOff();24}
    效果演示:(以注入notepad++為例)安裝消息鉤子前
    安裝消息鉤子后
    由于鉤子種類繁多,我暫時沒有全部實現,有興趣的各位可以在我的基礎上試試其他的,代碼寫的不好,讓各位見笑了,如有錯誤,也懇請各位指正。

    來自為知筆記(Wiz)

    轉載于:https://www.cnblogs.com/B166ER/p/7839870.html

    總結

    以上是生活随笔為你收集整理的消息钩子学习工程的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。