日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

钩子(hook)编程

發布時間:2024/8/1 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 钩子(hook)编程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

鉤子(hook)編程??

?

一、鉤子介紹

?????1.1鉤子的實現機制

鉤子英文名叫Hook,是一種截獲windows系統中某應用程序或者所有進程的消息的一種技術。下圖是windows應用程序傳遞消息的過程:

如在鍵盤中按下一鍵,操作系統將收到鍵按下消息,把消息放入消息隊列,然后消息隊列對消息進行派發,發給相應的應用程序,經過應用程序處理后發給操作系統,操作系統再調用相應的應用程序的創建的窗口過程。

????????我們可能通過鉤子截獲這些消息,讓消息不再往下傳遞,或者說截獲到感興趣的消息后做點什么。

1.2鉤子分類與實現

????????鉤子分進程內鉤子與全局鉤子,進程內鉤子是截取某一指定的進程的消息,直接在進程內創建與消除鉤子即可。全局鉤子是截取所有進程的消息,得以動態庫的方式實現。

????????實現一個鉤子一般有三個步驟,首先創建鉤子,有專門的API:SetWindowsHookEx,創建成功后,消息將會傳給SetWindowsHookEx的形參指定的處理函數。然后在消息處理函數中分析收到的消息,做相應的處理。最后,鉤子用完后,用API(UnhookWindowsHookEx)消毀鉤子。

?

二、創建鉤子

2.1鉤子的創建

????????????SetWindowsHookEx安裝一個應用程序定義的鉤子過程,并把創建的鉤子過程放在鉤子鏈中,可以安裝多個鉤子,多個鉤子就形成了鉤子鏈,最后安裝的鉤子總是在最前面。創建鉤子的函數如下:

創建鉤子,返回鉤子句柄,否則返回NULL。形參定義如下:

idHook:鉤子過程類型,如:鼠標消息鉤子、鍵盤消息鉤子、消息隊列監控鉤子等等。具體取值如下:

lpfn:相應的鉤子過程,也就是一個處理消息的回調函數名而已,如果參數dwThreadId為0,或者dwThreadId指向的是其他進程創建的線程標志符,那么lpfn必須指向一個位于某一動態庫中的鉤子過程。其他情況下,lpfn可以指向本進程內的某一鉤子過程。

hMod:指向鉤子過程所在的應用程序實例句柄,如:鉤子過程所在的DLL的句柄。如果dwThreadId指定的線程是由當前進程創建,并且鉤子過程在當時進程中,那么hMod必須設置為NULL。

dwThreadId:指定與鉤子相關的線程標志。如果為0,那么鉤子將與桌面上運行的所有線程相關。

????????鉤子過程可以與特定線程相關也可以與所有線程相關,取決于dwThreadId的取值。

2.2鉤子過程分析

????????鉤子過程,是處理鉤子截取的消息的一個回調函數,即SetWindowsHookEx函數中的第二個形參。格式如下:

LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam);形參含義并不是都一樣的,不同鉤子過程形參表示的意義不一樣,我們以鼠標鉤子為例說明,參數含義如下:

nCode:指示鉤子過程如何處理當前的消息,如果鉤子是鼠標消息鉤子的話,有兩種含義:

?

wParam:指示鼠標消息標志。

lParam:指向MOUSEHOOKSTRUCT結構體指針。以下是MOUSEHOOKSTRUCT結構體,包含著鼠標消息。

typedef struct {

???POINT pt;//光標包含x,y,是屏幕坐標。

???HWND hwnd;//目標窗口句柄

???UINT wHitTestCode;

???ULONG_PTR dwExtraInfo;

} MOUSEHOOKSTRUCT, *PMOUSEHOOKSTRUCT;

通過這三個參數,可對消息進行分析處理。

????????其他鉤子過程參數的含義可以通過MSDN文檔查看詳細說明,如KeyboardProc、MessageProc等。

2.3消毀鉤子

????????BOOL UnhookWindowsHookEx(HHOOK hhk);此API的功能是把SetWindowsHookEx創建的鉤子從鉤子鏈中移除。形參是SetWindowsHookEx返回的鉤子句柄。

?

三、進程內鉤子

????????進程內鉤子一般是為了截獲當前應用程序的消息,一般會可以在應用程序初始化的時候創建,當然也可以在自己想創建的時候創建,只是創建之前的消息無法截獲。

3.1鼠標鉤子過程函數

以下為鼠標鉤子過程代碼:

HWND????????????g_DestWndH = NULL;

HHOOK??????????g_hHookDm = NULL;

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

{????????????//此區間內的消息都是鼠標消息

?????????????if (WM_MOUSEMOVE <= wParam && wParam <=?WM_MOUSEWHEEL) {

???????????????????????????if(g_DestWndH != NULL) {

?????????????????????????????????????????::SendMessage(g_DestWndH, wParam, wParam, lParam);

?????????????????????????????????????????//鼠標鉤子,lParamMOUSEHOOKSTRUCT結構指針

?????????????????????????????????????????PMOUSEHOOKSTRUCT lpMsg = (PMOUSEHOOKSTRUCT)lParam;

?????????????????????????????????????????lpMsg->hwnd = NULL;????//把目的窗口置NULL

?????????????????????????????????????????lpMsg->dwExtraInfo = 0L;

?????????????????????????????????????????lpMsg->pt = CPoint(0, 0);

?????????????????????????????????????????lpMsg->wHitTestCode = 0L;

???????????????????????????}

???????????????????????????return 1;//如果想讓此消息不再往下傳,返回非0

?????????????}

?????????????else//不感興趣的消息往下傳

???????????????????????????return ::CallNextHookEx(g_hHookDm, nCode, wParam, lParam);

}

3.2創建鉤子過程

????????以下為創建鉤子過程的代碼:

if(g_hHookDm == NULL) {

?????????????//如果dwThreadId指定的線程是由當前進程創建,并且鉤子過程在當時進程中,那么hMod必須設置為NULL。

?????????????g_hHookDm = ::SetWindowsHookEx(WH_MOUSE,MouseProc, NULL, GetCurrentThreadId());

?????????????if (NULL != g_hHookDm)//創建成功

???????????????????????????g_DestWndH = m_hWnd;//保存目的窗口句柄

}

3.3消毀進程內鉤子

????????把鉤子過程從鉤子鏈中拿下來,調用一個API即可:

if (NULL != g_hHookDm) {

?????????????UnhookWindowsHookEx(g_hHookDm);

?????????????g_DestWndH = NULL;

}

到此進程內鉤子的創建與執行到消毀整個過程都完成了。

四、全局鉤子

4.1鍵盤鉤子過程函數

以上進程內鉤子只是截獲本進程的消息,如果要截獲桌面全部線程的消息則要通過全局鉤子。全局鉤子必須在DLL上實現,鉤子過程不能在本進程代碼中實現,所以先得寫一個DLL,代碼見”HookDll”,以鍵盤鉤子為例:

nCode:與鼠標鉤子是一樣的含義,有HC_ACTION與HC_NOREMOVE兩個值。

Param:代表具體的虛擬鍵,如:VK_TAB、VK_RETURN分別代表Tab鍵、Enter鍵按下,其他虛擬鍵消息可查看MSDN的”virtual-key code”.

lParam:存放一些擴展信息,如:按鍵重復數據、29位表示ALT鍵的按下情況。

參數的具體含義可查MSDN。關于組合鍵的問題,參看以下鍵盤鉤子函數的示例代碼:

HHOOK g_HookKeyBoard = NULL;

LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)

{

?????????????//wParam表示虛擬鍵,lparam29位表示ALT鍵按下狀態(按下為1,否則為0),

?????????????//GetKeyState可以獲得對應鍵的狀態,所以收下表示Control + ALT + Z組合鍵按下

?????????????if ('Z' == wParam && GetKeyState(VK_CONTROL) < 0 && (lParam >> 29 & 1)) {

???????????????????????????::SendMessage(g_DestWnd, WM_KEYDOWN, wParam, lParam);

???????????????????????????return 1;

?????????????}

?????????????else

???????????????????????????return CallNextHookEx(g_HookKeyBoard, nCode, wParam, lParam);

}

注:全局鉤子在某版本的系統中,調試狀態下,如果調試程序窗口沒有獲得焦點,在設置斷點的方不會停留,如果獲得焦點才會停留,也就是說,在調試狀態下,不屬于本進程的消息斷點處不會停留。

4.2創建全局鉤子接口

????????創建全局鉤子的方法在DLL中,所以得引出一個接口,代碼如下:

BOOL SetHook(HWND hWnd){

?????????????if (NULL == hWnd)

???????????????????????????return FALSE;

?????????????g_DestWnd = hWnd;

?????????????//第三個參數可通過些方法獲得:GetModuleHandle("MouseHook.dll")

?????????????return (NULL != (g_HookKeyBoard = ::SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hInst, 0)));

}

其形參是一窗口句柄,指示截獲的興趣消息需傳向的窗口的句柄,其中MetWindowsHookE的第三個參數是DLL的應用程序實例句柄,可通過DllMain的傳入參數得到,亦可通過GetModuleHandle方法得到,第四個參數必須為0,才能獲得全部桌面線程的消息。成功將返回TRUE否則FALSE。

4.3消毀全局鉤子接口

????????在DLL中也得引出一接口消毀全局鉤子,代碼如下:

void DestroyHook(){

?????????????if (NULL != g_HookKeyBoard) {

???????????????????????????UnhookWindowsHookEx(g_HookKeyBoard);

???????????????????????????g_DestWnd = NULL;

?????????????}

}

4.4使用DLL創建全局鉤子

????????以下為創建與消毀全局鉤子的實現,代碼如下:

HINSTANCE hIst = NULL;

void CHookTestDlg::OnCreateDllHook()

{

?????????????hIst = ::LoadLibrary("..\\HookDll\\Debug\\HookDll.dll");

?????????????if (NULL != hIst) {

???????????????????????????typedef BOOL (*pFunSetHook)(HWND);

???????????????????????????pFunSetHook pSetHook = (pFunSetHook)GetProcAddress(hIst, "SetHook");

???????????????????????????if (NULL != pSetHook) {

?????????????????????????????????????????if(pSetHook(m_hWnd))

???????????????????????????????????????????????????????AfxMessageBox("創建全局鉤子成功...");

???????????????????????????}

?????????????}

}

void CHookTestDlg::OnDestroyDllHook()

{

?????????????if (NULL != hIst) {

???????????????????????????typedef void (*pFunDestroyHook)();

???????????????????????????pFunDestroyHook pDestryHook = (pFunDestroyHook)GetProcAddress(hIst, "DestroyHook");

???????????????????????????if (NULL != pDestryHook) {

?????????????????????????????????????????pDestryHook();

?????????????????????????????????????????::FreeLibrary(hIst);

?????????????????????????????????????????hIst = NULL;

???????????????????????????}

?????????????}

}

?

配套源碼鏈接:http://download.csdn.net/detail/mingojiang/4526390

?

轉載自:http://blog.csdn.net/mingojiang?

總結

以上是生活随笔為你收集整理的钩子(hook)编程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。