VB.net中HOOK的應用(二) (轉)
中HOOK的應用(二)
二、那麼,在vb.net中對的和Hook的實現上作了什麼樣的變化呢?
我們對應著一個問題一個問題來看:
1. 新建一個module,先寫一下API的宣告:
Declare Function SetHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As HookType, ByVal lpfn As HOOKPROC, ByVal hmod As Integer, ByVal dwThreadId As Integer) As Integer:namespace prefix = o ns = "urn:schemas--com::office" />
Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Integer) As Integer
Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Integer, ByVal ncode As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
和上面vb6裡的宣告比一下,你發現了什麼?是不是資料型別發生了變化?integer代替了long。這個好理解,因為vb.net中integer定義為32位(4位元組)的整數,值的範圍是-231到231(首位是符號位),這與中long的定義是一致的,因此,我們必須做一下這樣的轉換。
等等,還有一個變化,就是SetWindowsHookEx的引數lpfn的型別變成了HOOKPROC,那……那是什麼意思。噢,wait,我再補一句宣告先:
Public Delegate Function HOOKPROC(ByVal nCode As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
看出來什麼了嗎?HOOKPROC其實就是一個宣告,但是前面有一個Delegate(委託)是什麼意思?為什麼在vb.net中不能用integer表示lpfn的型別了呢?我們回頭看一下vb6中呼叫API的句子:
hnextHookproc = SetWindowsHookEx(WH_KEYBOARD, AddressOf _
MyKBHFunc, App.hInstance, 0)
Lpfn在這裡被表示為AddressOf MyKBHFunc,即說明Hook發生作用時,呼叫的子程是MyKBHFunc。也就是說lpfn表示的是函式或過程的地址。在vb6中用long型別就可以記錄下函式或過程的地址。
在vb.net中,有了一點小變化嘍,AddressOf 運算子建立的是一個指向指定的子程的子程委託。當指定的子程是一個例項方法時,子程委託同時引用例項和方法,以便當呼叫該子程委託時,呼叫指定例項的指定方法。AddressOf 運算子可以用作委託建構函式的運算元,或可以用在能夠確定委託型別的上下文中。
所以,正是由於Addressof建立的不再只是簡單的函式指標了,而是子程委託!打住先,什麼是委託?(^?^)
解釋一下:事件是傳送的訊息,以發訊號通知操作的發生。操作可能是由互動(例如滑鼠單擊)引起的,也可能是由某些其他的邏輯觸發的。引發(觸發)事件的物件叫做事件傳送方。捕獲事件並對其作出響應的物件叫做事件接收方。在事件通訊中,事件傳送方類不知道哪個物件或方法將接收到(處理)它引發的事件。所需要的是在源和接收方之間存在一個媒介(或類似指標的機制)。.NET 定義了一個特殊的型別(Delegate),該型別提供函式指標的功能。看,這裡提到了.net框架,所以等vs.net中的語言都可以有這個型別嘍。
委託就是可用於呼叫其他物件方法的物件。與其他的類不同,委託類具有一個簽名,並且它只能對與其簽名匹配的方法進行引用。這樣,委託就等效於一個型別函式指標或一個回撥。因為它們與其他語言中所使用的函式指標相似。但不同於函式指標,.NET 委託是基於 System.Delegate 類的引用型別,它可以引用共享方法—無需特定即可呼叫的方法—和例項方法。(具體內容請自已去查閱一下MSDN或等我的後續文章再說明)
回過頭來總結一下,也就是說,Addressof建立的是DelegateType(委託型別)。而不是簡單的子程指標了,所以它的表示法就不是地址型別的long了,而是與呼叫的子程相一致的委託型別表示形式。因此,我定義了一個與MyKBHFunc宣告同形的委託函式HOOKPROC來表示lpfn的型別。
(呼,一頭汗,還不知道說清楚了沒有。希望是說清楚了……)
繼續,我又接著宣告瞭一個API:
Declare Function GetCurrentThreadId Lib "kernel32" Alias "GetCurrentThreadId" () As Integer
函式說明:本函式是用於獲取當前執行緒一個唯一的執行緒識別符號。返回值:當前的執行緒識別符號。這個有什麼用,一會再說,反正是個簡單的問題,不如賣個關子,哈哈……(不要砸我)
2. 定義的常量是:
Public hnextHookproc As Long
Public Const WH_KEYBOARD = 2 ‘這個是表明Hook的種類是鍵盤Hook
Public Const PM_KEY_SPACE = &H20 ‘空格鍵
或者,實際上也是,我在程式中對上面的第二句寫法改變了一下,也沒什麼了,就是多交待一點東西給朋友們嘛:
Public Enum HookType
WH_KEYBOARD = 2
End Enum
定義成了一個列舉。其實Hook的種類真的很多,比如有:WH_CALLWNDPROC、WH_CALLWNDPROCRET、WH_C、WH_DE、WH_GETMESSAGE等等。所以你不妨寫一個列舉,以達到一勞永逸的目的。
3. 程式碼段
Module Module1
Public frm1 As New Form1() ‘這個的作用,最後再說
Declare Function GetCurrentThreadId Lib "kernel32" Alias "GetCurrentThreadId" () As Integer
Declare Function SetWindowsHookEx Lib "user32" Alias _
"SetWindowsHookExA" (ByVal idHook As Integer, ByVal lpfn As HOOKPROC, _
ByVal hmod As Integer, ByVal dwThreadId As Integer) As Integer
Declare Function UnhookWindowsHookEx Lib "user32" _
(ByVal hHook As Integer) As Integer
Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Integer, _
ByVal ncode As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
Public Delegate Function HOOKPROC(ByVal nCode As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
Public hnexthookproc As Integer
Public Const PM_KEY_SPACE = &H20
Public Enum HookType
WH_KEYBOARD = 2
End Enum
Public Sub UnHook() ‘解Hook
If hnexthookproc <> 0 Then
UnhookWindowsHookEx(hnexthookproc)
hnexthookproc = 0
End If
End Sub
Public Function SetHook() ‘設定Hook
If hnexthookproc <> 0 Then
Exit Function
End If
hnexthookproc = SetWindowsHookEx(HookType.WH_KEYBOARD, AddressOf MyKeyboardProc, 0, GetCurrentThreadId())
我把第三個引數設為0(即NULL),表示的是此Hook的程式碼在此程式中。第四個引數用了一個API去取Hook子程相關聯的執行緒的識別符號。(參見前面的API宣告)
End Function
Public Function MyKeyboardProc(ByVal nCode As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
MyKeyboardProc = 0
If nCode < 0 Then
MyKeyboardProc = CallNextHookEx(hnexthookproc, nCode, wParam, lParam)
Exit Function
End If
If wParam = PM_KEY_SPACE Then
MyKeyboardProc = 1
‘寫入你自己的程式碼
frm1.textbox1.text=”HOOK成功!”
End If
End Function
Sub main()
Application.Run(frm1)
End Sub
End Module
同時請在:
解決方案管理器-〉windowsapplication1.sln -〉右點滑鼠 -〉屬性 -〉通用屬性->常規->啟動物件 -〉改為Module1
4.在Form1中的程式碼:
Private Sub Form1_Load(ByVal sender As System., ByVal e As System.EventArgs) Handles MyBase.Load
Call SetHook()
End Sub
‘vb.net中沒有form_unload事件了,而是用closing
Private Sub Form1_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
Call UnHook()
End Sub
最後簡單說明一下,為什麼我在module1裡用了Public frm1 As New Form1()這句話,及啟動物件 -〉改為Module1的作法。這是由於vb.net已經是OO的了,如果你是CSDN上vb.net版的常客,你就會很熟悉這個問題,我們已經討論過N次了。我也回過不知多少貼子來說明這一問題。由於和本文主題與篇幅所限,您要是對這個問題不明白,請先看一下:
獲得一些概念。我會在後續的文章中進行更為詳細和的介紹(其實它也是我最想先寫的問題之一)。
結束語:關於API的呼叫,本文只涉及了冰山之一角,關於具體的呼叫變化,我會根據vb.net版上的具體情況再寫相關的文章來說明的。
對了,補充一點,vb.net不再認any型別了,因此,在宣告時要具體宣告成你想要用的型別即可。
By Henry
2002.9.21(中秋夜)
如果你看過此文,程式出了問題,想要獲得vb.net HOOK的原始碼,可以和我聯絡(但實際上,我已經把程式碼全部寫在上面了)
e-:
qq: 18349592
----
宣告:本文版權與解釋權歸韓睿所有,如需轉載,請保留完整的內容及此宣告。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-993747/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- TS基礎應用 & Hook中的TSHook
- Henry手記-VB.net WinForm中的FORM初探(二) (轉)ORM
- VB.NET中物件的克隆 (轉)物件
- 在你的VB.NET應用程式中使用多執行緒 (轉)執行緒
- 從VB 6到VB.NET——窗體特殊應用 (轉)
- 精通ASP.NET(基於VB.NET)( 二)VB.NET類 (轉)ASP.NET
- 淺談API HOOK技術(二) (轉)APIHook
- Attribute 在.NET程式設計中的應用(二) (轉)程式設計
- 雙緩衝在畫板程式中的應用(二) (轉)
- 在VB.NET中尋找App (轉)APP
- 走近VB.Net(二) 再談函式呼叫 (轉)函式
- vb.net 存取資料庫中的圖片 (轉)資料庫
- sqlserver在JAVA中的應用 (轉)SQLServerJava
- linux中gcc的應用(轉)LinuxGC
- mfc中的訊息的應用 (轉)
- VB.NET中的物件導向程式設計特徵 (轉)物件程式設計特徵
- C#/VB.NET 在Excel單元格中應用多種字型格式C#Excel
- 設計模式在vue中的應用(二)設計模式Vue
- AOP及其在Spring中的應用(二)Spring
- 汽車行業的CRM應用(中) (轉)行業
- 動態SQL中DESCRIPTOR的應用 (轉)SQL
- Hook簡介 (轉)Hook
- VB.NET中關於DataGrid顏色的自定義。 (轉)
- React Hook原始碼解析(二)ReactHook原始碼
- VB.NET聊天程式 (轉)
- 用JScript實現VB.Net,C#的[委託Delegate]: (轉)JSC#
- ERP在企業中的應用(轉)
- apache web 中的CGI應用問題(轉)ApacheWeb
- VB.NET中實現"關機/休眠/重啟/登出"的類 (轉)
- DCOM實現分散式應用(二) (轉)分散式
- 【VB.NET視訊總結(二)】
- react中的 Hook 使用規則ReactHook
- 在VB.Net中建立使用控制元件陣列 (轉)控制元件陣列
- 我的Hook學習筆記 (轉)Hook筆記
- React應用裡Invalid hook call錯誤訊息的處理ReactHook
- 在應用程式中將OJB作為一個儲存層使用(二) (轉)
- asp.net(VB.net)中儲存過程的使用方法 (轉)ASP.NET儲存過程
- 提取應用程式中的圖示資源 (轉)