成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

淺談VB.NET中的跨進程消息鉤子

開發 后端
本文將簡單談談VB.NET中的跨進程消息鉤子,在VB6里面可以用API函數來進行子類化,以處理自身的窗體過程;如果跨進程,這就麻煩了,就需要用到文中的方法。

我們都知道在VB6里面可以用API函數來進行子類化,以處理自身的窗體過程;如果跨進程,這就麻煩了,由于我們的函數在我們的進程中(廢話),而目標進程的窗口的消息處理函數在目標進程(還是廢話),所以只能想辦法把我們的代碼放到對方進程中去執行——并且要告知我們的進程得到了什么消息。恐怕寫匯編就有點嚇人了,于是大家都寫DLL,其原理就是把回調函數放到一個DLL里面注入到對方進程,DLL去修改目標窗口的默認處理函數——把消息發送給我們。

當然也有“另類”一點的:http://www.it-berater.org/ThueDownloads/index.shtml上面有一個DLL包,其中含有一個dssubcls.dll,用它,可以輕松的完成我們的工作:就像調用一個API一樣簡單,而且在我們的程序中使用回調函數!呵呵,省去了自己寫DLL的麻煩之后,這些好處足以吸引各位觀眾了吧?

好了,VB6的代碼大家可以在下載的壓縮包中找到,作者提供了一個以記事本為基礎的實例(在\dssubcls目錄下),非常詳細無需詳細敘述了。關鍵是在VB.NET里面如何使用它——如何聲明API,如何進行回調,看用來子類化的API的VB6聲明先:

Declare Function SubClass& Lib "dssubcls" (ByVal HwndSubclass&, _
 Optional ByVal Address& = 0, _
 Optional ByVal OldStyle& = 0, _
 Optional ByVal NewStyle& = 0, _
 Optional ByVal Ext& = 0, _
 Optional ByVal SubClass& = 0)
轉化成VB.NET的聲明類似下面的樣子(習慣使然,我把&展開成了As Integer):

Declare Function SubClass Lib "dssubcls" (ByVal HwndSubclass As Integer, Optional ByVal Address As Integer = 0, Optional ByVal OldStyle As Integer = 0, Optional ByVal NewStyle As Integer = 0, Optional ByVal Ext As Integer = 0, Optional ByVal SubClass As Integer = 0) As Integer

這不是很好嘛?問題來了,這樣的聲明在VB6里面可以使用Addressof function來傳入第二個參數(參見你下載的源碼),但是在VB.NET里面直接Addressof就不成了——我們需要委托一個回調:

Private Delegate Function HookCallBack(ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer

這個委托,對應的是以下函數:

Private Function mCallback(ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
‘在這里處理得到的消息

End Function

使用時,需要注意先實例化這個委托:

Private fix_COCD = New HookCallBack(AddressOf mCallback)

此時,fix_COCD就是我們的mCallback函數引用了,用更直觀的觀點來看,fix_COCD就是一個指向mCallback的指針,相當于VB6里面的Addressof function得到的結果,看似問題解決了,于是我們寫了以下代碼來搞對方的進程窗體消息:

SubClass(Handle, fix_COCD, 0, 0, 0, 1) '修改處理函數

問題真是接踵而至!IDE提示變量類型不符!!事實確實如此,我們把一個HookCallBack類型當做Integer來傳遞,無法通過檢查,那么強行轉換吧?當然,你可以去試試。這時,我所做的是,修改這個API聲明:

Private Declare Function SubClass Lib "dssubcls" (ByVal HwndSubclass As Integer, Optional ByVal Address As HookCallBack = Nothing, Optional ByVal OldStyle As Integer = 0, Optional ByVal NewStyle As Integer = 0, Optional ByVal Ext As Integer = 0, Optional ByVal SubClass As Integer = 0) As Integet

使之符合我們的調用?有點倒行逆施?并非如此,當你習慣了修改API聲明之后,會發現有些事變得如此簡單,有些事需要你重新認識——對于WIN32 API也是如此。

 

至此,大功告成:

較為完整的代碼如下:

Code
Private Declare Function SubClass Lib "dssubcls" (ByVal HwndSubclass As Integer, Optional ByVal Address As HookCallBack = Nothing, Optional ByVal OldStyle As Integer = 0, Optional ByVal NewStyle As Integer = 0, Optional ByVal Ext As Integer = 0, Optional ByVal SubClass As Integer = 0) As Integer
Private Declare Function UseSendMessage Lib "dssubcls" (ByVal use As Integer) As Integer
'實例化的委托
Private fix_COCD = New HookCallBack(AddressOf mCallback)
'委托
Private Delegate Function HookCallBack(ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
Public Sub Hook(ByVal Handle As Integer)
proc = SubClass(Handle, fix_COCD, 0, 0, 0, 1) '修改處理函數
UseSendMessage(1)
End Sub

Private Function mCallback(ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer

End Function

 

用這個代碼的時候,可能會碰見一些“意外情況“,例如wm_datacopy,此時,我們需要進一步去獲取LPARTM所指向的結構并對其進行解析(我們要讀的是對方窗口所在進程的內存,具體地址由lParam確定——實際上lParam一直是一個指針——IntPrt,但它與Integer完全就是一回事(如果你使用VB2005可能需要使用Intprt.toint32或intprt=new intprt(integer)這些):

Code
Public Class GetMsg
Public Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Integer, ByVal lpBaseAddress As Integer, ByVal lpBuffer() As Byte, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Integer
Public Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Integer, ByVal lpBaseAddress As Integer, ByRef int As Integer, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Integer
Public Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Integer, ByVal bInheritHandle As Integer, ByVal dwProcessId As Integer) As Integer
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Integer) As Integer
Private hProc As IntPtr
Sub New(ByVal PID As Integer)
hProc = OpenProcess(&HFFFF, False, PID)
End Sub

Function readmsg(ByVal address As Integer) As Byte()
Dim buf(19) As Byte
ReadProcessMemory(hProc, address, buf, 20, 0)
Return buf
End Function

Protected Overrides Sub Finalize()
CloseHandle(hProc)
MyBase.Finalize()
End Sub
End Class
這個類提供了Readmsg方法來讀取一些內容——但這并不是完整的,我們知道,LPARAM指向的結構是這樣的:

_
Public Structure COPYDATASTRUCT
Public dwData As Integer
Public cbData As Integer
Public lpData As IntPtr
End Structure

其中dwData我們不是很關心,當然其中也可能存在一些有用信息(這里不想多說,網上有些文章純屬誤導)

而cbData是一個長度:lpData的長度

lpData這里被聲明為指針,看起來更直觀了——它就是地址

有了地址和長度,如何讀取代碼就自己寫吧。

提示一下:參考我重載的ReadProcessMemory可能對你有不少幫助。

當然,上面提到的只是“特殊情況”中的一個典型,還有很多時候,進程是用自定義消息(>&H40A)來傳遞數據的,例如我所開發的這個工程,打印mCallBack的參數后,得到的是如下結果(十六進制,只提取了有用的信息):

4731442257D0

其中lParam就是一個指針,我讀了其中的一部分:

Function readmsg(ByVal address As Integer) As Byte()
Dim buf(19) As Byte
ReadProcessMemory(hProc, address, buf, 20, 0)
Return buf
End Function

現在就明白為什么上面的代碼是那樣了:)

然后進行了一個處理,得到了我想要的信息:

'消息解碼后得到的移動棋子信息:玩家,起X,起Y,止X,止Y,棋子編號,走棋總步數
Event Move(ByVal player As Byte, ByVal sx As Byte, ByVal sy As Byte, ByVal dx As Byte, ByVal dy As Byte, ByVal name As Byte, ByVal [step] As Byte)
Private Function mCallback(ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
If wParam = &H14 Then
Dim s As Byte() = msg.readmsg(lParam)
RaiseEvent Move(s(1), s(10), s(11), s(12), s(13), s(14), s(16))
End If
End Function

當然,在我的工程里面重載的ReadProcessMemory并沒有被使用。

補充一下咯:

在VB.NET中,處理自己的窗體的消息只需要重載窗體消息處理過程就可以了,無需子類化:)

有補充一下:

對于wm_datacopy來說,還有一些數據獲取的問題沒有說清楚,實際上都可以用一些方法來解決。

【編輯推薦】

  1. 淺談VB.NET中的跨進程消息鉤子
  2. VB.NET中的動態代碼生成技巧
  3. C#和VB.NET類型相關知識匯總向
  4. VB.NET中有用的通用對象列表
  5. VB.NET和C#逐層橫向對比
責任編輯:彭凡 來源: cnblogs
相關推薦

2009-10-14 12:51:41

VB.NET Data

2009-10-28 10:31:23

VB.NET Impl

2009-10-20 09:39:04

VB.NET Butt

2009-10-12 13:32:58

VB.NET線程構造器

2009-10-16 10:14:26

VB.NET使用Fil

2009-10-13 11:22:46

VB.NET調用Web

2009-06-29 10:50:18

VB.NET面向對象能力

2010-01-07 16:51:56

VB.NET窗體鉤子

2010-01-22 15:56:03

VB.NET獲取當前U

2009-10-19 11:28:42

VB.NET語言.NET開發語言

2010-01-21 15:10:37

VB.NET靜態托盤程

2010-01-21 17:23:05

VB.NET Radi

2009-12-24 14:30:56

VB.NET

2009-10-26 17:07:17

VB.NET UNDO

2010-01-22 13:08:50

VB.NET創建數組

2009-10-20 14:03:48

VB.NET數組聲明VB.NET數組初始化

2009-11-02 16:55:50

VB.NET Smar

2009-10-29 14:02:24

VB和VB.NET比較

2009-10-20 14:21:55

VB.NET fnSi

2011-06-17 11:05:22

VB.NET
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久99精品久久久 | 日韩快播电影 | 国产高清视频在线播放 | 免费看国产片在线观看 | 一区二区国产在线 | 日韩高清黄色 | 成人做爰www免费看 午夜精品久久久久久久久久久久 | 视频一区在线播放 | 国产伦精品 | 国产一级精品毛片 | 99福利视频 | 成人视屏在线观看 | 高清人人天天夜夜曰狠狠狠狠 | 日本a视频| 在线国产视频 | 中文字幕色站 | 国产一区二区三区四区 | 精品一区二区久久久久久久网站 | 天天操人人干 | 四虎伊人| 中文字幕一区二区三区四区五区 | 中文字幕欧美在线观看 | 亚洲激情一级片 | 欧美精品一区二区在线观看 | 亚洲乱码一区二区三区在线观看 | 亚洲美女在线一区 | 九九九久久国产免费 | 国产精品1区2区 | 亚洲第一天堂无码专区 | 国产成人精品区一区二区不卡 | 中午字幕在线观看 | 久久网站免费视频 | 免费久久久 | 亚洲成人黄色 | 在线一级片 | 秋霞影院一区二区 | 日韩一区二区三区在线看 | 看片网站在线 | 一区二区三区免费观看 | 中文字幕成人在线 | 亚洲 欧美 综合 |