在使用 Detours 劫持以前必須得擁有這兩個東西:detours.h 和 detours.lib。html
爲了這兩個東西我真的是弄了大半天,本着本身動手豐衣足食的思想:編程
我去 GitHub 克隆了一份來本身編譯,對着網上的教程弄,在編譯的時候就是各類 bug。多線程
試了一次又一次,算了仍是找別人編譯好了的用吧!目前最新版本是 Detours 4.01 版。函數
拿到編譯好的頭文件和庫後,我放到 VC6.0 相應的文件中去,結果在編程時發現頭文件出錯!spa
這時我就懵逼了,最後發現是由於 VC6.0版本過低致使的。所以最後便放到 VS2017 中去了。.net
說到這裏,若是你不想本身動手嘗試的話,這裏給你編譯好的 Detours 庫。 請點擊下載!線程
關於 Detours 裏的函數發現網上並無比較詳細的介紹:這裏就借鑑一下別人的博客吧!指針
我覺的這兩個博客仍是挺不錯的:心夢無痕,吹成狗的攻城獅。調試
這裏咱們一樣來攔截兩個函數:一般狀況下代碼是這樣的:code
#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 文件注入到記事本後,會看到這樣: