在使用 Detours 劫持之前必須得擁有這兩個東西:detours.h 和 detours.lib。
為了這兩個東西我真的是弄了大半天,本着自己動手豐衣足食的思想:
我去 GitHub 克隆了一份來自己編譯,對着網上的教程弄,在編譯的時候就是各種 bug。
試了一次又一次,算了還是找別人編譯好了的用吧!目前最新版本是 Detours 4.01 版。
拿到編譯好的頭文件和庫后,我放到 VC6.0 相應的文件中去,結果在編程時發現頭文件出錯!
這時我就懵逼了,最后發現是因為 VC6.0版本太低導致的。因此最后便放到 VS2017 中去了。
說到這里,如果你不想自己動手嘗試的話,這里給你編譯好的 Detours 庫。請點擊下載
關於 Detours 里的函數發現網上並沒有比較詳細的介紹:這里就借鑒一下別人的博客吧!
這里我們同樣來攔截兩個函數:通常情況下代碼是這樣的:
#include "stdafx.h" #include<detours.h> #include<Windows.h> #pragma comment(lib,"detours.lib") void HookOn(); void HookOff(); static int (WINAPI *OldMesssageBoxA) ( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType ) = MessageBoxA; static int (WINAPI *OldMesssageBoxW) ( HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType ) = MessageBoxW;
// 注意了,自定義函數得和被 HOOK 的函數一樣,否則會發生異常。 int WINAPI MyFunction0 ( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType ); int WINAPI MyFunction1 ( HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType ); BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: HookOn(); break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: HookOff(); break; } return TRUE; } void HookOn() { //開始事務 DetourTransactionBegin(); //更新線程信息 DetourUpdateThread(GetCurrentThread()); //將攔截的函數附加到原函數的地址上,這里可以攔截多個函數。 DetourAttach(&(PVOID&)OldMesssageBoxA, MyFunction0); DetourAttach(&(PVOID&)OldMesssageBoxW, MyFunction1); //結束事務 DetourTransactionCommit(); } void HookOff() { //開始事務 DetourTransactionBegin(); //更新線程信息 DetourUpdateThread(GetCurrentThread()); //將攔截的函數從原函數的地址上解除,這里可以解除多個函數。 DetourDetach(&(PVOID&)OldMesssageBoxA, MyFunction0); DetourDetach(&(PVOID&)OldMesssageBoxW, MyFunction1); //結束事務 DetourTransactionCommit(); }
// 調用被 HOOK 的函數可以用被 HOOK 函數的指針,不能用原函數。 int WINAPI MyFunction0(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT uType) { return OldMesssageBoxA(NULL, "Hooking your MessageBoxA!", "Warming", MB_OKCANCEL); } int WINAPI MyFunction1(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCaption,UINT uType) { return OldMesssageBoxW(NULL, L"Hooking your MessageBoxW!", L"Warming", MB_OKCANCEL); }
這段代碼是在 VS2017 上生成的,我一般都是在虛擬機里運行的,所以需要進行一些設置:
調試 ---> Dll 屬性 ---> C/C++ ---> 代碼生成 ---> 運行庫---多線程/MT,這樣設置完后就可以了。
我們將生成的 dll 文件注入到記事本后,會看到這樣:
鏈接:https://pan.baidu.com/s/1VMIO068JBYPl7v7inWfGvw
提取碼:t7kf