windows鈎子函數
關于鈎子的了解:
windows應用程式是基于消息驅動的。
windows鈎子可以監視指定視窗的某種類型的消息。
當監視的消息到達該指定的視窗時,在該視窗處理消息前,鈎子函數将截獲此消息。
鈎子函數既可以攔截處理此消息,也可以不做任何處理将該消息傳遞下去。
相關函數:
HHOOK hHook = NULL;
LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam) //鈎子函數
{
if (code == HC_ACTION)
{
PKBDLLHOOKSTRUCT param = (PKBDLLHOOKSTRUCT)lParam;
int x = 1;
}
return CallNextHookEx(hHook, HC_ACTION, wParam, lParam);
}
DLL_HOOK_GETKEYBOARD_API bool KeyboardDll::initKeyboardHook() //加載鈎子
{
hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, NULL, 0);
if (hHook == NULL)
{
printf("SetWindowsHookEx() error :%d\n", GetLastError());
return false;
}
return true;
}
DLL_HOOK_GETKEYBOARD_API bool KeyboardDll::stopHook() //解除安裝鈎子
{
if (UnhookWindowsHookEx(hHook) == FALSE)
{
printf("UnhookWindowsHookEx() error :%d\n");
return false;
}
fclose(fp);
return true;
}
SetWindowsHookEx函數介紹:
SetWindowsHookEx(
int idHook, //要安裝的鈎子的類型。
HOOKPROC lpfn, //鈎子函數的位址。
HINSTANCE hMode, //鈎子函數DLL在程序内的位址。目前程序中,此參數應被指定為NULL.
DWORD dwThread, //要安裝鈎子的線程。如為0,則為所有線程安裝鈎子。
//如果隻檢測本程序,可用GetCurrentThreadId()
);
BOOL UnhookWindowsHookEx(HHOOK hhk);
問題:為什麼鈎子函數必須在動态庫中實作???寫在主程式内時隻可以在主程式内安裝鈎子。
HOOK技術 可以隻hook本程序的消息,這樣不需要全局鈎子,不用寫在dll中。
但如果需要hook其他程序或者全部程序,就需要全局鈎子,必須利用dll實作。
因為每個程序有自己獨立的程序記憶體空間,捕獲其消息,需要windows将hook加載到其程序空間中,
而實作這個最好的方法,就是用DLL來實作。系統會自動把該DLL注入到所有的程序空間中。
也就是每個程序都将自動加載此動态庫。調用鈎子函數來處理捕獲消息。