天天看點

C++鈎子技術

涉及函數

HHOOK SetWindowsHookEx(      

    int idHook,
    HOOKPROC lpfn,
    HINSTANCE hMod,
    DWORD dwThreadId
);
           

參數說明:

    idHook: 鈎子類型

WH_CALLWNDPROC: 回調鈎子, 監視在系統發送消息到目标視窗之前擷取消息 

WH_CALLWNDPROCRET: 監視 在系統發送消息到目标視窗之後擷取消息 WH_CBT: WH_DEBUG: 調試鈎子 WH_FOREGROUNDIDLE:處理前景色鈎子 WH_GETMESSAGE: 監視發送消息到消息隊列 WH_JOURNALPLAYBACK:檢視被 WH_JOURNALRECORD 記錄的消息 WH_JOURNALRECORD: 記錄輸入的消息,發送到消息隊列,主要用在記錄宏 WH_KEYBOARD:鍵盤消息鈎子 WH_KEYBOARD_LL:鍵盤消息鈎子,用在監視較低級别的鍵盤事件 WH_MOUSE: 滑鼠鈎子 WH_MOUSE_LL: 監視低級别的滑鼠事件 鈎子 WH_MSGFILTER: 監視對話框,消息框,菜單,滾動條的輸入事件 WH_SHELL : 監視 shell 程式 

WH_SYSMSGFILTER: 監視與調用線程在同一桌面上的控件消息

lpfn:指向過程函數的指針

如果dwThreadId =0 或者被不同程序建立的線程,那麼lpfn 必須指向是DLL的鈎子

否則,lpfn指向目前程序中定義的鈎子過程

hMod: 包含指向lpfn參數的鈎子的DLL句柄, 如果dwThreadId訓示的線程是目前程序建立并且關聯到目前程序的鈎子

那麼hMod 設定為NULL

dwThreadId: 鈎子過程關聯的線程,如果為0, 為全局鈎子,将監視目前調用線程同一桌面的所有的消息

SetWindowsHookEx : 把一個新的鈎子 加入到鈎子鍊中, 最後加入的鈎子在鍊的最前面

傳回值: 成功,鈎子過程的句柄; 失敗傳回NULL

描述:

SetWindowsHookEx 可以進行DLL 注入到另外一個程序,但是32位 DLL不能注入到64位程序, 64位DLL的也不能注入到32位的程序中。

如果使用鈎子進行注入DLL, 32位的DLL 和64位餓DLL 需要名稱不相同

如果hMod = NULL,并且 (dwThreadId=0, 或者dwThreadId被另外一個程序建立),那麼将抛出錯誤。

建議調用 CallNextHookEx 把事件往下一個鈎子傳遞, 否則最終程式擷取不到事件,也有可能導緻系統錯誤。 除非你一定不想讓消息往下傳遞。

在中斷程式前, 一定要調用 UnhookWindowsHookEx 去是否鈎子所占用的系統資源

Hook Scope
WH_CALLWNDPROC Thread or global
WH_CALLWNDPROCRET Thread or global
WH_CBT Thread or global
WH_DEBUG Thread or global
WH_FOREGROUNDIDLE Thread or global
WH_GETMESSAGE Thread or global
WH_JOURNALPLAYBACK Global only
WH_JOURNALRECORD Global only
WH_KEYBOARD Thread or global
WH_KEYBOARD_LL Global only
WH_MOUSE Thread or global
WH_MOUSE_LL Global only
WH_MSGFILTER Thread or global
WH_SHELL Thread or global
WH_SYSMSGFILTER Global only

如果既是線程鈎子又是全局鈎子, 那麼先調用線程鈎子,再調用全局鈎子。

Minimum DLL Version user32.dll
Header Declared in Winuser.h, include Windows.h
Import library User32.lib
Minimum operating systems Windows 95, Windows NT 3.1
Unicode Implemented as ANSI and Unicode versions

測試: 

1.線程鈎子

建立MFC 對話框應用程式, 在OnInitDialog 中加入 代碼

SetWindowsHookEx(WH_MOUSE,(HOOKPROC)MouseProc,NULL,GetCurrentThreadId());
           

因為是目前主線程建立的鈎子,所有 hMod =NULL , 擷取目前線程Id 使用 GetCurrentThreadId(), 鈎子類型是滑鼠鈎子

添加鈎子過程函數:

LRESULT CALLBACK MouseProc(int nCode,
	WPARAM wParam,
	LPARAM lParam
	)
{


}
           
LRESULT CallNextHookEx(      

    HHOOK hhk,
    int nCode,
    WPARAM wParam,
    LPARAM lParam
);      

此函數, 是把參數傳遞到目前鈎子鍊中的下一個鈎子

問題: VS2010生成 lib 檔案

VS2010預設生成dll,但不生成Lib檔案,方法是:在所建工程上單擊滑鼠右鍵,在彈出的右鍵菜單中選擇“添加-->建立項....---->子產品定義檔案”,在該子產品定義檔案中寫導出函數表,單擊确定。然後在所建工程上單擊滑鼠右鍵,選擇“屬性”菜單,在彈出的屬性對話框中“連結器-->輸入-->子產品定義檔案”中填寫剛才定義的def檔案,然後再重新編譯即可生成LIB檔案。

WH_GETMESSAGE是從消息隊列中取消息, 而WH_CALLWNDPROC 是擷取發送中前的消息

WH_GETMESSAGE Hook隻攔截由GetMessage or PostMessage的消息,不能攔截由SendMessage引起的消息。

the WH_GETMESSAGE hook enables an application to monitor messages about to be returned by the GetMessage or PeekMessage function. You can use the WH_GETMESSAGE hook to monitor mouse and keyboard input and other messages posted to the message queue.

要Hook SendMessage必須Hook WH_CALLWNDPROC and WH_CALLWNDPROCRET Hooks

The WH_CALLWNDPROC and WH_CALLWNDPROCRET hooks enable you to monitor messages sent to window procedures by the SendMessage function. Windows calls a WH_CALLWNDPROC hook procedure before passing the message to the receiving window procedure, and calls the WH_CALLWNDPROCRET hook procedure after the window procedure has processed the message. 

The WH_CALLWNDPROCRET hook passes the address of a CWPRETSTRUCT structure to the hook procedure. The structure contains the return value from the window procedure that processed the message, as well as the message parameters associated with the message. Subclassing the window does not work for messages set between processes.

事列源碼 : 線程鈎子

繼續閱讀