一、Hook簡介 
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中。 
在VB如何設定Hook呢?使用SetWindowsHookEx() 
Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" _ 
(ByVal idHook As Long, _ 
ByVal lpfn As Long, _ 
ByVal hmod As Long, _ 
ByVal dwThreadId As Long) As Long 
idHook代表是何種Hook,有以下幾種 
Public Const WH_CALLWNDPROC = 4 
Public Const WH_CALLWNDPROCRET = 12 
Public Const WH_CBT = 5 
Public Const WH_DEBUG = 9 
Public Const WH_FOREGROUNDIDLE = 11 
Public Const WH_GETMESSAGE = 3 
Public Const WH_HARDWARE = 8 
Public Const WH_JOURNALPLAYBACK = 1 
Public Const WH_JOURNALRECORD = 0 
Public Const WH_KEYBOARD = 2 
Public Const WH_MOUSE = 7 
Public Const WH_MSGFILTER = (-1) 
Public Const WH_SHELL = 10 
Public Const WH_SYSMSGFILTER = 6 
lpfn代表Hook Function所在的Address,這是一個CallBack Fucnction,當掛上某個 
Hook時,我們便得定義一個Function來當作某個訊息產生時,來處理它的Function 
,這個Hook Function有一定的三數格式 
Private Function HookFunc(ByVal ncode As Long, _ 
ByVal wParam As Long, _ 
ByVal lParam As Long) As Long 
 
nCode 代表是什麽請況之下所產生的Hook,隨Hook的不同而有不同組的可能值 
wParam lParam 傳回值則隨Hook的種類和nCode的值之不同而不同。 
因這個三數是一個 Function的Address所以我們屆景謢X木馬網站●ont=Times New Roman]Hook Function放在.Bas中, 
並以AddressOf HookFunc傳入。至於Hook Function的名稱我們可以任意給定,不一 
定叫 HookFunc 
hmod 代表.DLL的hInstance,如果是Local Hook,該值可以是Null(VB中可傳0進去), 
而如果是Remote Hook,則可以使用GetModuleHandle(".dll名稱")來傳入。 
dwThreadId 代表執行這個Hook的ThreadId,如果不設定是那個Thread來做,則傳0(所以 
一般來說,Remote Hook傳0進去),而VB的Local Hook一般可傳App.ThreadId進去 
值回值如果SetWindowsHookEx()成功,它會傳回一個值,代表目前的Hook的Handle, 
這個值要記錄下來。 
因為A程式可以有一個System Hook(Remote Hook),如KeyBoard Hook,而B程式也來設一 
個Remote的KeyBoard Hook,那麽到底KeyBoard的訊息誰所攔截?答案是,最後的那一個 
所攔截,也就是說A先做keyboard Hook,而後B才做,那訊息被B攔截,那A呢?就看B的 
Hook Function如何做。如果B想讓A的Hook Function也得這個訊息,那B就得呼叫 
CallNextHookEx()將這訊息Pass給A,於是產生Hook的一個連線。如果B中不想Pass這訊息 
給A,那就不要呼叫CallNextHookEx()。 
Declare Function CallNextHookEx Lib "user32" _ 
(ByVal hHook As Long, _ 
ByVal ncode As Long, _ 
ByVal wParam As Long, _ 
lParam As Any) As Long 
hHook值是SetWindowsHookEx()的傳回值,nCode, wParam, lParam則是Hook Procedure 
中的三個三數。 
最後是將這Hook去除掉,請呼叫UnHookWindowHookEx() 
Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long 
hHook便是SetWindowsHookEx()的傳回值。此時,以上例來說,B程式結束Hook,則換A可 
以直接攔截訊息。 
KeyBoard Hook的範例 
Hook Function的三個三數 
nCode wParam lParam 傳回值 
HC_ACTION 表按鍵Virtual Key 與WM_KEYDOWN同 若訊息要被處理傳0 
或 反之傳1 
HC_NOREMOVE 
Public hHook As Long 
Public Sub UnHookKBD() 
If hnexthookproc <> 0 Then 
UnhookWindowsHookEx hHook 
hHook = 0 
End If 
End Sub 
Public Function EnableKBDHook() 
If hHook <> 0 Then 
Exit Function 
End If 
hHook = SetWindowsHookEx(WH_KEYBOARD, AddressOf MyKBHFunc, App.hInstance, App.ThreadID) 
End Function 
Public Function MyKBHFunc(ByVal iCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long 
MyKBHFunc = 0 '表示要處理這個訊息 
If wParam = vbKeySnapshot Then '偵測 有沒有按到PrintScreen鍵 
MyKBHFunc = 1 '在這個Hook便吃掉這個訊息 
End If 
Call CallNextHookEx(hHook, iCode, wParam, lParam) '傳給下一個Hook 
End Function 
只要將上面代碼放在VB的模組中,用標準VB程式就可以了,當運行該程式後,就能攔截所有鍵盤操作。 |