WINDOWS鉤子函數詳解

來源:互聯網
上載者:User

本課中我們將要學習WINDOWS鉤子函數的使用方法。WINDOWS鉤子函數的功能非常強大,有了它您可以探測其它進程並且改變其它進程的行為。
理論:
WINDOWS的鉤子函數可以認為是WINDOWS的主要特性之一。利用它們,您可以捕捉您自己進程或其它進程發生的事件。通過“鉤掛”,您可以給WINDOWS一個處理或過濾事件的回呼函數,該函數也叫做“鉤子函數”,當每次發生您感興趣的事件時,WINDOWS都將調用該函數。一共有兩種類型的鉤子:局部的和遠端。
局部鉤子僅鉤掛您自己進程的事件。
遠端鉤子還可以將鉤掛其它進程發生的事件。遠端鉤子又有兩種:
基於線程的 它將捕獲其它進程中某一特定線程的事件。簡言之,就是可以用來觀察其它進程中的某一特定線程將發生的事件。
系統範圍的 將捕捉系統中所有進程將發生的事件訊息。
安裝鉤子函數將會影響系統的效能。監測“系統範圍事件”的系統鉤子特別明顯。因為系統在處理所有的相關事件時都將調用您的鉤子函數,這樣您的系統將會明顯的減慢。所以應謹慎使用,用完後立即卸載。還有,由於您可以預先截獲其它進程的訊息,所以一旦您的鉤子函數出了問題的話必將影響其它的進程。記住:功能強大也意味著使用時要負責任。
在正確使用鉤子函數前,我們先講解鉤子函數的工作原理。當您建立一個鉤子時,WINDOWS會先在記憶體中建立一個資料結構,該資料結構包含了鉤子的相關資訊,然後把該結構體加到已經存在的鉤子鏈表中去。新的鉤子將加到老的前面。當一個事件發生時,如果您安裝的是一個局部鉤子,您進程中的鉤子函數將被調用。如果是一個遠程鉤子,系統就必須把鉤子函數插入到其它進程的地址空間,要做到這一點要求鉤子函數必須在一個動態連結程式庫中,所以如果您想要使用遠程鉤子,就必須把該鉤子函數放到動態連結程式庫中去。當然有兩個例外:工作日誌鉤子和工作日誌回放鉤子。這兩個鉤子的鉤子函數必須在安裝鉤子的線程中。原因是:這兩個鉤子是用來監控比較底層的硬體事件的,既然是記錄和回放,所有的事件就當然都是有先後次序的。所以如果把回呼函數放在DLL中,輸入的事件被放在幾個線程中記錄,所以我們無法保證得到正確的次序。故解決的辦法是:把鉤子函數放到單個的線程中,譬如安裝鉤子的線程。
鉤子一共有14種,以下是它們被調用的時機:
WH_CALLWNDPROC 當調用SendMessage時
WH_CALLWNDPROCRET 當SendMessage的調用返回時
WH_GETMESSAGE 當調用GetMessage 或 PeekMessage時
WH_KEYBOARD 當調用GetMessage 或 PeekMessage 來從訊息佇列中查詢WM_KEYUP 或 WM_KEYDOWN 訊息時
WH_MOUSE 當調用GetMessage 或 PeekMessage 來從訊息佇列中查詢滑鼠事件訊息時
WH_HARDWARE 當調用GetMessage 或 PeekMessage 來從訊息佇列種查詢非滑鼠、鍵盤訊息時
WH_MSGFILTER 當對話方塊、菜單或捲軸要處理一個訊息時。該鉤子是局部的。它時為那些有自己的訊息處理過程的控制項對象設計的。
WH_SYSMSGFILTER 和WH_MSGFILTER一樣,只不過是系統範圍的
WH_JOURNALRECORD 當WINDOWS從硬體隊列中獲得訊息時
WH_JOURNALPLAYBACK 當一個事件從系統的硬體輸入隊列中被請求時
WH_SHELL 當關於WINDOWS外殼事件發生時,譬如任務條需要重畫它的按鈕.
WH_CBT 當基於電腦的訓練(CBT)事件發生時
WH_FOREGROUNDIDLE 由WINDOWS自己使用,一般的應用程式很少使用
WH_DEBUG 用來給鉤子函數除錯
現在我們知道了一些基本的理論,現在開始講解如何安裝/卸載一個鉤子。
要安裝一個鉤子,您可以調用SetWindowHookEx函數。該函數的原型如下:
SetWindowsHookEx proto HookType:DWORD, pHookProc:DWORD, hInstance:DWORD, ThreadID:DWORD
HookType 是我們上面列出的值之一,譬如: WH_MOUSE, WH_KEYBOARD
pHookProc 是鉤子函數的地址。如果使用的是遠端鉤子,就必須放在一個DLL中,否則放在本身代碼中
hInstance 鉤子函數所在DLL的執行個體控制代碼。如果是一個局部的鉤子,該值為NULL
ThreadID 是您安裝該鉤子函數後想監控的線程的ID號。該參數可以決定該鉤子是局部的還是系統範圍的。如果該值為NULL,那麼該鉤子將被解釋成系統範圍內的,那它就可以監控所有的進程及它們的線程。如果您指定了您自己進程中的某個線程識別碼,那該鉤子是一個局部的鉤子。如果該線程ID是另一個進程中某個線程的ID,那該鉤子是一個全域的遠程鉤子。這裡有兩個特殊情況:WH_JOURNALRECORD 和 WH_JOURNALPLAYBACK總是代表局部的系統範圍的鉤子,之所以說是局部,是因為它們沒有必要放到一個DLL中。WH_SYSMSGFILTER 總是一個系統範圍內的遠程鉤子。其實它和WH_MSGFILTER鉤子類似,如果把參數ThreadID設成0的話,它們就完全一樣了。
如果該函數調用成功的話,將在eax中返回鉤子的控制代碼,否則返回NULL。您必須儲存該控制代碼,因為後面我們還要它來卸載鉤子。
要卸載一個鉤子時調用UnhookWidowHookEx函數,該函數僅有一個參數,就是欲卸載的鉤子的控制代碼。如果調用成功的話,在eax中返回非0值,否則返回NULL。
現在您知道了如何安裝和卸載一個鉤子了,接下來我們將看看鉤子函數。.
只要您安裝的鉤子的訊息事件類型發生,WINDOWS就將調用鉤子函數。譬如您安裝的鉤子是WH_MOUSE類型,那麼只要有一個滑鼠事件發生時,該鉤子函數就會被調用。不管您安裝的時那一類型鉤子,鉤子函數的原型都時是一樣的:
HookProc proto nCode:DWORD, wParam:DWORD, lParam:DWORD

nCode 指定是否需要處理該訊息
wParam 和 lParam 包含該訊息的附加訊息
HookProc 可以看作是一個函數名的預留位置。只要函數的原型一致,您可以給該函數取任何名字。至於以上的幾個參數及傳回值的具體含義各種類型的鉤子都不相同。譬如:
WH_CALLWNDPROC
nCode 只能是HC_ACTION,它代表有一個訊息發送給了一個視窗
wParam 如果非0,代表正被發送的訊息
lParam 指向CWPSTRUCT型結構體變數的指標
return value: 未使用,返回0
WH_MOUSE
nCode 為HC_ACTION 或 HC_NOREMOVE
wParam 包含滑鼠的事件訊息
lParam 指向MOUSEHOOKSTRUCT型結構體變數的指標
return value: 如果不處理返回0,否則返回非0值
所以您必須查詢您的WIN32 API 指南來得到不同類型的鉤子的參數的詳細定義以及它們傳回值的意義。這裡還有一個問題需要注意:所有的鉤子都串在一個鏈表上,最近加入的鉤子放在鏈表的頭部。當一個事件發生時,WINDOWS將按照從鏈表頭到鏈表尾調用的順序。所以您的鉤子函數有責任把訊息傳到下一個鏈中的鉤子函數。當然您可以不這樣做,但是您最好明白這時這麼做的原因。在大多數的情況下,最好把訊息事件傳遞下去以便其它的鉤子都有機會獲得處理這一訊息的機會。調用下一個鉤子函數可以調用函數CallNextHookEx。該函數的原型如下:
CallNextHookEx proto hHook:DWORD, nCode:DWORD, wParam:DWORD, lParam:DWORD
hHook 時是您自己的鉤子函數的控制代碼。利用該控制代碼可以遍曆鉤子鏈。
nCode, wParam and lParam 您只要把傳入的參數簡單傳給CallNextHookEx即可。
請注意:對於遠程鉤子,鉤子函數必須放到DLL中,它們將從DLL中映射到其它的進程空間中去。當WINDOWS映射DLL到其它的進程空間中去時,不會把資料區段也進行映射。簡言之,所有的進程僅共用DLL的代碼,至於資料區段,每一個進程都將有其單獨的拷貝。這是一個很容易被忽視的問題。您可能想當然的以為,在DLL中儲存的值可以在所有映射該DLL的進程之間共用。在通常情況下,由於每一個映射該DLL的進程都有自己的資料區段,所以在大多數的情況下您的程式運行得都不錯。但是鉤子函數卻不是如此。對於鉤子函數來說,要求DLL的資料區段對所有的進程也必須相同。這樣您就必須把資料區段設成共用的,這可以通過在連結開關中指定段的屬性來實現。在MASM中您可以這麼做:
/SECTION:<section name>, S
已初期化的段名是.data,未初始化的段名是.bss。`加入您想要寫一個包含鉤子函數的DLL,而且想使它的未初始化的資料區段在所有進程間共用,您必須這麼做:
link /section:.bss,S /DLL /SUBSYSTEM:WINDOWS ..........
S 代表該段是共用段。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.