Detours學習1
Using Detours
要繞過目標函式,必須具備兩個條件:一個是包含目標函式地址的目標指標,另一個是繞過函式。為了正確攔截目標函式、detour函式和目標指標必須具有完全相同的呼叫簽名,包括引數數和呼叫約定。使用相同的呼叫約定可以確保適當地保留暫存器,並確保堆疊在detour函式和目標函式之間正確對齊。
使用者程式碼必須包含detours.h
標頭檔案並與detours連結detorus.lib
庫。
// dllmain.cpp : 定義 DLL 應用程式的入口點。 #include "pch.h" #pragma comment(lib, "detours.lib") static VOID(WINAPI* TureSleep)(DWORD dwMilliseconds) = Sleep; VOID WINAPI hkSleep(DWORD dwMilliseconds) { ULONGLONG dwBeg = GetTickCount64(); TureSleep(dwMilliseconds); ULONGLONG dwEnd = GetTickCount64(); TCHAR buffer[512]; _stprintf_s(buffer, sizeof(buffer) / sizeof(TCHAR), _T("Sleeped %llu milli sec"), dwEnd - dwBeg); MessageBox(NULL, buffer, _T(""), MB_OK); } BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { if (DetourIsHelperProcess()) { return TRUE; } switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: DetourRestoreAfterWith(); DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourAttach(&(PVOID&)TureSleep, hkSleep); DetourTransactionCommit(); break; case DLL_PROCESS_DETACH: DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourDetach(&(PVOID&)TureSleep, hkSleep); DetourTransactionCommit(); break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: break; } return TRUE; }
通過DetourAttach
在Hook事務中呼叫可以攔截目標函式。通過對DetourTransactionBegin
和DetourTransactionCommit
的呼叫來標記Hook事務。該DetourAttach
帶有兩個引數:目標函式指標的地址和指向DetourFunction
函式的指標。目標函式未作為引數提供,因為它必須已經儲存在目標指標中。
該DetourUpdateThread
提供在目標執行緒中宣告,以便在事務提交時更新指令指標。
該DetourAttach
分配和準備跳轉呼叫目標函式。Hook事務提交時,將重寫目標函式和跳轉函式Trampoline
,並更新目標指標以指向跳轉函式
一旦Hook目標函式,對目標函式的任何呼叫都將通過DetourFunction
函式重新路由。通過Trampoline
呼叫目標函式時,DetourFunction
函式負責複製引數。這很明確,因為目標函式是DetourFunction
函式的內部呼叫函式。
通過DetourDetach
在Hook事件中的呼叫,可以刪除對目標函式的攔截。與DetourAttach
一樣,DetourDetach
也有兩個引數:目標指標的地址和指向DetourFunction
函式的指標。當Hook事務提交時,目標函式將被重寫並恢復為其原始程式碼,Trampline
函式將被刪除,目標指標將恢復為指向原始目標函式。
如果需要將Hook的API注入到目標程式中,則Hook需要編譯成Dll。可以使用遠端執行緒注入、Dll劫持等技術。也可以使用
DetourCreateProcessWithDllEx
或DetourCreateProcessWithDlls
將Dll注入到目標程序中。如果使用DetourCreateProcessWithDllEx
或DetourCreateProcessWithDlls
,則DllMain函式必須呼叫DetourRestoreAfterWith
。如果Dll可以在x86和x64混合環境中使用,則DllMain函式必須呼叫DetourIsHelperProcess
匯出為序號1,rundll32.exe
以執行幫助任務來呼叫該API。
下面來注入一個剛剛到的Dll到一個程序中,測試一下效果
安裝Detours庫
VcPkg install detours:x86-windows VcPkg install detours:x64-windows