Detours HOOK 庫 Hook 過濾LoadLibraryExW
一丶簡介
1.1 Detours庫簡介
Detours是微軟提供的HOOK庫.為我們Hook提供了方便.再也不用手擼 HOOK了.當然手擼比較好.可以鍛煉.不過工作中要求效率.所以使用這個庫.
這個庫很強大.對於初學者來說也很簡單.
1.2 使用Detours需要注意的問題
為什么說我們需要注意.很多博客也有說.但是往往都不太注意.比如我.一開始使用這個Hook庫的時候各種崩潰.最后調試一下.發現了問題.
所以這里列舉出來
1. 如果HOOK API 一定要注意調用約定
比如我們如果HOOK一個API.一定要注意它的調用約定.否則最后平棧的時候返回地址不對.就會引發錯誤.當時我就犯了這個錯誤.不過調試之后解決了.
比如你HOOK 自定義函數.的時候,如果是自己寫的.沒加調用約定的時候,那么就是C調用約定
2. 不要使用typedef 重新定義函數指針
為什么說不要使用.也不是不要使用.主要是當時比較急.解決棘手問題.
用了typedef. 導致函數地址不一樣就出錯了.所以能使用但是你需要了解一下.因為我工作原因.並沒有深究.
二丶使用Detours的步驟
2.1下載Detours.以及使用
說到使用,我們必須要下載Detours.當然我會上傳.你可以去CSDN下載.或者自己下載源碼編譯.我下了好多.也編譯好了.會上傳.直接下載即可.
首先使用Detours.
Detours有兩個頭文件.我們都包含即可.
#include "detours.h"
#include "detver.h"
還需要一個lib庫.我們放在VS工程中即可.
#pragma comment(lib,"Detours.lib")
2.2使用Detours步驟很簡單.都是固定API
如下:
void DetoursHook()
{
DetourRestoreAfterWith();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(LPVOID&)PFnLoadLibraryExW, MyLoadLibraryExw);
DetourTransactionCommit();
}
總共五步
1.AfterWith()避免重復HOOK
2.TransactionBegin();開始HOOK
3.UpdateThread();更新到當前線程
4.DetourAttch();你要HOOK的函數的函數的地址,以及你自定義的函數的函數地址.
5.TransactionCommit();提交HOOK 這一步才是最終進行HOOK.
看一下第4步,DetourAttch();
這一個函數指針我們需要定義為下面這樣.比如
LoadLibraryExW
static HMODULE(WINAPI *PFnLoadLibraryExW)(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) = (HMODULE(WINAPI *)(LPCWSTR, HANDLE, DWORD))DetourFindFunction("KernelBase.dll", "LoadLibraryExW");
前邊是LoadLibraryExW的函數指針定義. 后面的 = 是對他進行賦值.不過需要強轉.
DetourFindFunction函數就是尋找函數地址.給一個模塊名,給一個函數名他就去找.然后找到就返回.不過你需要強轉進行賦值即可.
我們上面說了,既然要進行綁定.那么需要提供一個我們自己的函數才可以.
自己定義的函數如下:
HMODULE WINAPI MyLoadLibraryExw(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
{
if( wcscmp(lpLibFileName,TEXT("XXX) == 0)
{
return NULL; //return NULL的意思就是loadlibrary直接返回NULL就是沒有加載,這一步就相當於攔截了.
}
return PFnLoadLibraryExW(lpLibFileName, hFile, dwFlags); //調用原函數,就是不做處理
}
2.2 HOOK 自定義 函數
上面說我們使用DetourFindFunction尋找API,其實我們HOOK自己的我們也可以寫一個跟它一樣的函數. 原理就是返回一個地址.
你知道你的函數地址在哪你都可以寫成如下;
static HMODULE(WINAPI *PFnLoadLibraryExW)(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) = (HMODULE(WINAPI *)(LPCWSTR, HANDLE, DWORD))0x40001200
假設你的函數地址是0x40001200,那么Detours就會去HOOK這個地方.
3.UnHOOK
有了HOOK,那么自然有UnHOOK(卸載HOOK).也很簡單.不一一說了.直接貼完整代碼.
#include "detours.h"
#include "detver.h"
#include <winnt.h>
using namespace std;
#pragma comment(lib,"Detours.lib")
static HMODULE(WINAPI *PFnLoadLibraryExW)(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) = (HMODULE(WINAPI *)(LPCWSTR, HANDLE, DWORD))DetourFindFunction("KernelBase.dll", "LoadLibraryExW");
void DetoursUnHook();
void DetoursHook();
HMODULE WINAPI MyLoadLibraryExw(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
{
return PFnLoadLibraryExW(lpLibFileName, hFile, dwFlags);
}
void DetoursHook()
{
DetourRestoreAfterWith();
DetourTransactionBegin(); //開始
DetourUpdateThread(GetCurrentThread());//初始化當前線程
DetourAttach(&(LPVOID&)PFnLoadLibraryExW, MyLoadLibraryExw);//進行附加
DetourTransactionCommit();//進行HOOK
}
void DetoursUnHook()
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach((void **)&PFnLoadLibraryExW, MyLoadLibraryExw);//撤銷攔截函數
DetourDetach(&(LPVOID&)PfnFreeLibrary, NewFreeLibrary);
DetourTransactionCommit();//
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hModule);
DetoursHook();
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
//DetoursUnHook();
break;
case DLL_PROCESS_DETACH:
//DeleteCriticalSection(&testCS);
//DetoursUnHook();
break;
}
return TRUE;
}
HOOK 庫打包下載鏈接:
鏈接:https://pan.baidu.com/s/1zhXqPfPhZdSWsipDuWVVQg
提取碼:tcg5