深入淺出HOOKS

深入淺出HOOKS

關鍵字     hooks 
  


HOOKS 說明書

 

hook是WINDOWS提供的一種消息處理機制,它使得程序員可以使用子過程來監視系統消息,並在消息到達目標過程前得到處理。

下面將介紹WINNDOWS HOOKS並且說明如何在WINDOWS 程序中使用它。

 

=========================關於HOOKS======================

使用HOOK 將會降低系統效率,因爲它增加了系統處量消息的工作量。建議在必要時才使用HOOK,並在消息處理完成後立即移去該HOOK。

HOOK鏈

WINDOWS提供了幾種不同類型的HOOKS;不同的HOOK可以處理不同的消息。例如,WH_MOUSE HOOK用來監視鼠標消息。

WINDOWS爲這幾種HOOKS維護着各自的HOOK鏈。HOOK鏈是一個由應用程序定義的回調函數隊列,當某種類型的消息發生時,WINDOWS向此種類型的HOOK鏈的第一個函數發送該消息,在第一函數處理完該消息後由該函數向鏈表中的下一個函數傳遞消息,依次向下。如果鏈中某個函數沒有向下傳送該消息,那麼鏈表中後面的函數將得不到此消息。(對於某些類型的HOOK,不管HOOK鏈中的函數是否向下傳遞消息,與此類型HOOK聯繫的所有HOOK函數都會收到系統發送的消息)

 

===========================HOOK過程========================

爲了攔截特定的消息,你可以使用SetWindowsHookEx函數在該類型的HOOK鏈中安裝你自己的HOOK函數。該函數語法如下:

public function MyHook(nCode,wParam,iParam) as long

‘加入代碼

end function

其中MyHook可以隨便命名,其它不能變。該函數必須放在模塊段。nCode指定HOOK類型。wParam,iParam的取值隨nCode不同而不同,它代表了某種類型的HOOK的某個特定的動作。

SetWindowsHookEx總是將你的HOOK函數放置在HOOK鏈的頂端。你可以使用CallNextHookEx函數將系統消息傳遞給HOOK鏈中的下一個函數。

[註釋]對於某些類型的HOOK,系統將向該類的所有HOOK函數發送消息,這時,HOOK函數中的CallNextHookEx語句將被忽略。 

全局HOOK函數可以攔截系統中所有線程的某個特定的消息(此時該HOOK函數必須放置在DLL中),局部HOOK函數可以攔截指定線程的某特定消息(此時該HOOK函數可以放置在DLL中,也可以放置在應用程序的模塊段)。

[註釋] 建議只在調試時使用全局HOOK函數。全局HOOK函數將降低系統效率,並且會同其它使用該類HOOK的應用程序產生衝突。

 

========================HOOK類型=================================

WH_CALLWNDPROC 和 WH_CALLWNDPROCRET HOOK

WH_CALLWNDPROC 和WH_CALLWNDPROCRET HOOK可以監視SendMessage發送的消息。系統在向窗體過程發送消息前,將調用WH_CALLWNDPROC;在窗體過程處理完該消息後系統將調用WH_CALLWNDPROCRET。

WH_CALLWNDPROCRET HOOK會向HOOK過程傳送一個CWPRETSTRUCT結構的地址。該結構包含了窗體過程處理系統消息後的一些信息。

WH_CBT Hook

系統在激活,創建,消毀,最小化,最大化,移動,改變窗體前;在完成一條系統命令前;在從系統消息隊列中移去鼠標或鍵盤事件前;在設置輸入焦點前,或同步系統消息隊列前,將調用WH_CBT HOOK。你可以在你的HOOK 過程攔截該類HOOK,並返回一個值,告訴系統,是否繼續執行上面的操作。

WH_DEBUG HOOK

系統在調用與某種HOOK類型聯繫的HOOK過程前,將調用WH_DEBUG ,應用程序可以使用該HOOK決定是否讓系統執行某種類型的HOOK。

WH_FOREGROUNDIDLE Hook

系統在空閒時調用該HOOK,在後臺執行優先權較低的應用程序。

WH_GETMESSAGE Hook

WH_GETMESSAGE Hook使應用程序可以攔截GetMessage 或 PeekMessage的消息。應用程序使用WH_GETMESSAGE HOOK監視鼠標、鍵盤輸入和發送到隊列中的其它消息。

WH_JOURNALRECORD Hook

WH_JOURNALRECORD Hook使應用程序可以監視輸入事件。典型地,應用程序使用該HOOK記錄鼠標、鍵盤輸入事件以供以後回放。該HOOK是全局HOOK,並且不能在指定線程中使用。

WH_JOURNALPLAYBACK Hook

` WH_JOURNALPLAYBACK Hook使應用程序可以向系統消息隊列中插入消息。該HOOK可以回放以前由WH_JOURNALRECORD HOOK錄製的鼠標、鍵盤輸入事件。在WH_JOURNALPLAYBACK Hook安裝到系統時,鼠標、鍵盤輸入事件將被屏蔽。該HOOK同樣是一個全局HOOK,不能在指定線程中使用。

WH_JOURNALPLAYBACK Hook返回一個時間暫停值,它告訴系統,在處理當前回放的消息時,系統等待百分之幾秒。這使得此HOOK可以控制在回放時的時間事件。

WH_KEYBOARD Hook

WH_KEYBOARD Hook使應用程序可以監視由GetMessage和PeekMessage返回的WM_KEYDOWN 及WM_KEYUP消息。應用程序使用該HOOK監視發送到消息隊列中的鍵盤輸入。

WH_MOUSE Hook

WH_MOUSE Hook 使應用程序可以監視由GetMessage和PeekMessage返回的消息。應用程序使用該HOOK監視發送到消息隊列中的鼠標輸入。

WH_MSGFILTER and WH_SYSMSGFILTER Hooks

WH_MSGFILTER 和WH_SYSMSGFILTER Hooks使應用程序可以監視菜單、滾動條、消息框、對話框,當用戶使用ALT+TAB或ALT+ESC來切換窗體時,該HOOK也可以攔截到消息。WH_MSGFILTER僅在應用程序內部監視菜單、滾動條、消息框、對話框,而WH_SYSMSGFILTER則可以在系統內監視所有應用程序的這些事件。

WH_SHELL Hook

一個SHELL程序可以使用WH_SHELL Hook來接收重要的信息。當一個SHELL程序被激活前或當前窗體被創建、消毀時,系統會調用WH_SHELL Hook過程。

 

=======================使用HOOK============================

安裝、消毀HOOK過程

監視系統事件

 

安裝、消毀HOOK過程

使用SetWindowsHookEx函數,指定一個HOOK類型,自己的HOOK過程是全局還是局部HOOK,同時給出HOOK過程的進入點,就可以輕鬆的安裝你自己的HOOK過程。

爲了安裝一個全局HOOK過程,必須在應用程序外建立一個DLL,並將該HOOK函數封裝到其中,應用程序在安裝全局HOOK過程時必須先得到該DLL模塊的句柄。將DLL名傳遞給LoadLibrary 函數,就會得到該DLL模塊的句柄;得到該句柄 後,使用GetProcAddress函數可以得到HOOK過程的地址。最後,使用SetWindowsHookEx將HOOK過程的首址嵌入相應的HOOK鏈中,SetWindowsHookEx傳遞一個模塊句柄,它爲HOOK過程的進入點,線程標識符置爲0,指出:該HOOK過程同系統中的所有線程關聯。

以下是C寫的例程,大家可以方便的轉換爲VB程序。

HOOKPROC hkprcSysMsg; 

static HINSTANCE hinstDLL; 

static HHOOK hhookSysMsg; 

 

hinstDLL = LoadLibrary((LPCTSTR) "c://windows//sysmsg.dll"); 

hkprcSysMsg = (HOOKPROC)GetProcAddress(hinstDLL, "SysMessageProc"); 

hhookSysMsg = SetWindowsHookEx(WH_SYSMSGFILTER, 

hkprcSysMsg, hinstDLL, 0); 


  Hook這個東西有時令人又愛又怕,Hook是用來攔截系統某些信息之用,例如說,我們想 讓系統不管在什麼地方只要按個Ctl-B便執行NotePad,或許您會使用Form的KeyPreview,設定爲True,但在其他Process中按Ctl-B呢?那就沒有用,這時就得設一個Keyboard Hook來攔截所有Key in的鍵;再如:MouseMove的Event只在該Form或Control上有效,如 果希望在Form的外面也能得知Mouse Move的信息,那隻好使用Mouse Hook來欄截Mouse 的信息。再如:您想記錄方纔使用者的所有鍵盤動作或Mosue動作,以便錄巨集,那就使用JournalRecordHook,如果想停止所有Mosue鍵盤的動作,而放(執行)巨集,那就使用JournalPlayBack Hook;Hook呢,可以是整個系統爲範圍(Remote Hook),即其他 Process的動作您也可以攔截,也可以是LocalHook,它的攔截範圍只有Process本身。Remote Hook的Hook Function要在.Dll之中,Local Hook則在.Bas中。

發佈了94 篇原創文章 · 獲贊 2 · 訪問量 23萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章