一 何時用到鉤子?(when)
Windows操做系統是創建在事件驅動的消息處理機制之上,系統各部分之間的溝通也都是經過消息的相互傳遞而實現的。一般狀況下,應用程序只能處理當前進程的消息,若是須要對其它進程的消息進行攔截處理就必須採鉤子技術。
二 什麼是鉤子?(what)
鉤子其實是一段用以處理系統消息的程序(鉤子函數),經過系統調用,將其掛入到系統。每當特定的消息發出,在沒有到達目標窗口前,鉤子程序就先捕獲該消息,即鉤子函數先獲得控制權。在鉤子函數中,能夠加工處理(改變)該消息,也能夠不做處理而繼續傳遞該消息,還能夠強制結束消息的傳遞。鉤子函數是一個應用程序定義的回調函數,不能定義成某個類的成員函數,只能定義爲普通的C函數。
三 什麼是鉤子鏈表?(what)
系統提供多種不一樣類型的鉤子用於處理不一樣的消息。在某一時刻可能有多個進程安裝了相同類型的鉤子,即同一種鉤子有多個不一樣的鉤子處理函數。這多個不一樣的鉤子處理函數的指針構成了鉤子鏈表,由操做系統維護。當某種類型的消息發生時系統向該類型的鉤子鏈表的第一個函數發送該消息,在第一函數處理完該消息後由該函數向鏈表中的下一個函數傳遞消息,依次向下。若是鏈中某個函數沒有向下傳送該消息,那麼鏈表中後面的函數將得不到此消息。(對於某些類型的鉤子,無論鉤子鏈中的函數是否向下傳遞消息,與此類型鉤子關聯的全部鉤子函數都會收到系統發送的消息)最近安裝的鉤子放在鏈的開始,而最先安裝的鉤子放在最後,也就是後加入的先得到控制權。系統並不要求鉤子子程的卸載順序必定得和安裝順序相反。每當有一個鉤子被卸載,系統便釋放其佔用的內存,並更新整個鉤子鏈表。若是應用程序安裝了鉤子,可是在還沒有卸載鉤子以前就結束了,那麼系統會自動卸載鉤子。
四 鉤子的做用範圍(where)
一共有兩種範圍(類型)的鉤子:局部的和遠程的。
1.局部鉤子僅鉤掛您本身進程的事件。
2.遠程的鉤子還能夠將鉤掛其它進程發生的事件。
遠程的鉤子又有兩種:
2.1 基於線程的它將捕獲其它進程中某一特定線程的事件。簡言之,就是能夠用來觀察其它進程中的某一特定線程將發生的事件。
2.2系統範圍的將捕捉系統中全部進程將發生的事件消息。
五 鉤子的使用步驟(How)
1 安裝鉤子
SetWindowsHookEx函數能夠把應用程序定義的鉤子函數安裝到系統中。
HHOOK SetWindowsHookEx(
int idHook ; // 指定鉤子的類型
HOOKPROC lpfn; //鉤子函數的地址。若是是遠程鉤子,鉤子函數必須放在一個DLL中。
HINSTANCE hMod; // 鉤子函數所在的DLL的實例句柄。局部的鉤子,該參數爲NULL。
DWORD dwThreadID; //指定要爲哪一個線程安裝鉤子。若該值爲0被解釋成系統範圍內的。
);
2 定義鉤子函數
鉤子函數的通常形式以下:
LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
// 處理該消息的代碼 …..
Return ::CallNextHookEx(hHook,nCode,wParam,lParam);
}
HookProc是鉤子函數的名稱。nCode參數是Hook代碼,鉤子函數使用這個參數來肯定任務,它的值依賴於Hook的類型。wParam和lParam參 數的值依賴於Hook代碼,可是它們典型的值是一些關於發送或者接收消息的信息。由於系統中可能會有多個鉤子的存在,因此要調用那個 CallNextHookEx函數把消息傳到鏈中下一個鉤子函數。hHook參數是安裝鉤子時獲得的鉤子句柄(SetWindowsHookEx的返回值)。
3 卸載鉤子
要卸載鉤子,能夠調用UnhookWindowsHookEx函數。
BOOL UnhookWindowsHookEx(HHOOK hhk); // hhk 爲要卸載的鉤子的句柄
注意:
安裝鉤子的代碼能夠在DLL模塊中,也能夠在主模塊中,可是通常在DLL裏實現它,主要是爲了使程序更加模塊化。
六 鉤子的幾個實例
七 鉤子的幾點總結
1.鉤子是用截獲系統中的消息流。利用鉤子,能夠處理任何感興趣的消息,包括其餘進程的消息。
2.截獲消息後,用於處理消息的子程序叫作鉤子函數,它是應用程序自定義的一個函數,在安裝鉤子時要把這個函數的地址告訴系統。
3.在操做系統中,同一時間可能有多個進程安裝了同一種類型的鉤子,即會有多個鉤子函數,多個鉤子函數在一塊兒組成鉤子鏈。因此在處理截獲到的消息時,應該把消息事件傳遞下去,以便其餘鉤子函數也有機會處理這一消息。
4.鉤子會使得系統變慢,由於它增長了系統對每一個消息的處理量。僅應該在必要時才安裝鉤子,並且在不須要時應儘快移除。
模塊化