七月网

消息钩子(消息钩子软件)

七月网2400

一、消息钩子的VB中的Hook技术应用

1、Hook这个东西有时令人又爱又怕,Hook是用来拦截系统某些讯息之用,例如说,我们想

消息钩子(消息钩子软件)

2、让系统不管在什么地方只要按个Ctl-B便执行NotePad,或许您会使用Form的KeyPreview

3、,设定为True,但在其他Process中按Ctl-B呢?那就没有用,这是就得设一个Keyboard

4、Hook来拦截所有Key in的键;再如:MouseMove的Event只在该Form或Control上有效,如果希望在Form的外面也能得知Mouse Move的讯息,那只好使用Mouse Hook来栏截Mouse

5、的讯息。再如:您想记录方才使用者的所有键盘动作或Mosue动作,以便录巨集,那就

6、使用JournalRecordHook,如果想停止所有Mosue键盘的动作,而放(执行)巨集,那就

7、使用JournalPlayBack Hook;Hook呢,可以是整个系统为范围(Remote Hook),即其他

8、Process的动作您也可以拦截,也可以是LocalHook,它的拦截范围只有Process本身。

9、Remote Hook的Hook Function要在.Dll之中,Local Hook则在.Bas中。

10、在VB如何设定Hook呢?使用SetWindowsHookEx()

11、Declare Function SetWindowsHookEx Lib'user32' Alias'SetWindowsHookExA'_

12、ByVal dwThreadId As Long) As Long

13、idHook代表是何种Hook,有以下几种

14、Public Const WH_CALLWNDPROC= 4

15、Public Const WH_CALLWNDPROCRET= 12

16、Public Const WH_FOREGROUNDIDLE= 11

17、Public Const WH_JOURNALPLAYBACK= 1

18、Public Const WH_JOURNALRECORD= 0

19、Public Const WH_MSGFILTER=(-1)

20、Public Const WH_SYsmSGFILTER= 6

21、WH_CALLWNDPROC当调用SendMessage时

22、WH_CALLWNDPROCRET当SendMessage的调用返回时

23、WH_GETMESSAGE当调用GetMessage或 PeekMessage时

24、WH_KEYBOARD当调用GetMessage或 PeekMessage来从消息队列中查询WM_KEYUP或 WM_KEYDOWN消息时

25、WH_MOUSE当调用GetMessage或 PeekMessage来从消息队列中查询鼠标事件消息时

26、WH_HARDWARE当调用GetMessage或 PeekMessage来从消息队列种查询非鼠标、键盘消息时

27、WH_MSGFILTER当对话框、菜单或滚动条要处理一个消息时。该钩子是局部的。它时为那些有自己的消息处理过程的控件对象设计的。

28、WH_SYsmSGFILTER和WH_MSGFILTER一样,只不过是系统范围的

29、WH_JOURNALRECORD当WINDOWS从硬件队列中获得消息时

30、WH_JOURNALPLAYBACK当一个事件从系统的硬件输入队列中被请求时

31、WH_SHELL当关于WINDOWS外壳事件发生时,譬如任务条需要重画它的按钮.

32、WH_CBT当基于计算机的训练(CBT)事件发生时

33、WH_FOREGROUNDIDLE由WINDOWS自己使用,一般的应用程序很少使用

34、lpfn代表Hook Function所在的Address,这是一个CallBack Fucnction,当挂上某个

35、Hook时,我们便得定义一个Function来当作某个讯息产生时,来处理它的Function

36、,这个Hook Function有一定的叁数格式

37、Private Function HookFunc(ByVal ncode As Long,_

38、nCode代表是什么请况之下所产生的Hook,随Hook的不同而有不同组的可能值

39、wParam lParam传回值则随Hook的种类和nCode的值之不同而不同。

40、因这个叁数是一个 Function的Address所以我们固定将Hook Function放在.Bas中,

41、并以AddressOf HookFunc传入。至于Hook Function的名称我们可以任意给定,不一

42、hmod代表.DLL的hInstance,如果是Local Hook,该值可以是Null(VB中可传0进去),

43、而如果是Remote Hook,则可以使用GetModuleHandle('.dll名称')来传入。

44、dwThreadId代表执行这个Hook的ThreadId,如果不设定是那个Thread来做,则传0(所以

45、一般来说,Remote Hook传0进去),而VB的Local Hook一般可传App.ThreadId进去

46、值回值如果SetWindowsHookEx()成功,它会传回一个值,代表目前的Hook的Handle,

47、因为A程式可以有一个System Hook(Remote Hook),如KeyBoard Hook,而B程式也来设一

48、个Remote的KeyBoard Hook,那么到底KeyBoard的讯息谁所拦截?答案是,最后的那一个

49、所拦截,也就是说A先做keyboard Hook,而后B才做,那讯息被B拦截,那A呢?就看B的

50、Hook Function如何做。如果B想让A的Hook Function也得这个讯息,那B就得呼叫

51、CallNextHookEx()将这讯息Pass给A,于是产生Hook的一个连线。如果B中不想Pass这讯息

52、给A,那就不要呼叫CallNextHookEx()。

53、Declare Function CallNextHookEx Lib'user32'_

54、hHook值是SetWindowsHookEx()的传回值,nCode, wParam, lParam则是Hook Procedure

55、最后是将这Hook去除掉,请呼叫UnHookWindowHookEx()

56、Declare FunctionUnhookWindowsHookExLib'user32'(ByVal hHook As Long) As Long

57、hHook便是SetWindowsHookEx()的传回值。此时,以上例来说,B程式结束Hook,则换A可

58、HC_ACTION表按键Virtual Key与WM_KEYDOWN同若讯息要被处理传0

59、If hnexthookproc<> 0 Then

60、Public Function EnableKBDHook()

61、If hHook<> 0 Then

62、hHook= SetWindowsHookEx(WH_KEYBOARD, AddressOf MyKBHFunc, App.hInstance, App.ThreadID)

63、Public Function MyKBHFunc(ByVal iCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

64、MyKBHFunc= 0'表示要处理这个讯息

65、If wParam= vbKeySnapshot Then'侦测有没有按到PrintScreen键

66、MyKBHFunc= 1'在这个Hook便吃掉这个讯息

67、Call CallNextHookEx(hHook, iCode, wParam, lParam)'传给下一个Hook

68、只要将上面代码放在VB的模块中,用标准VB程序就可以了,当运行该程序后,就能拦截所有键盘操作。

二、安装消息钩子是什么意思

安装一个钩子函数,用于在消息发送到目标窗口过程前将其截取。该类型可以是一个系统级别的钩子或者线程级别的钩子。也就是通过安装“消息钩子”,可以窃取网络游戏玩家的账号密码,发送到黑客指定的远程服务器或邮箱,导致用户无法正常运行游戏

三、浅谈VB.NET中的跨进程消息钩子

1、我们都知道在VB里面可以用API函数来进行子类化以处理自身的窗体过程如果跨进程这就麻烦了由于我们的函数在我们的进程中(废话)而目标进程的窗口的消息处理函数在目标进程(还是废话)所以只能想办法把我们的代码放到对方进程中去执行——并且要告知我们的进程得到了什么消息恐怕写汇编就有点吓人了于是大家都写DLL其原理就是把回调函数放到一个DLL里面注入到对方进程 DLL去修改目标窗口的默认处理函数——把消息发送给我们

2、当然也有另类一点的/ThueDownloads/index s上面有一个DLL包其中含有一个dssubcls dll用它可以轻松的完成我们的工作就像调用一个API一样简单而且在我们的程序中使用回调函数!呵呵省去了自己写DLL的麻烦之后这些好处足以吸引各位观众了吧?

3、好了 VB的代码大家可以在下载的压缩包中找到作者提供了一个以记事本为基础的实例(在\dssubcls目录下)非常详细无需详细叙述了关键是在VB NET里面如何使用它——如何声明API如何进行回调看用来子类化的API的VB声明先

4、 Declare Function SubClass& Lib dssubcls(ByVal HwndSubclass&_Optional ByVal Address&=_Optional ByVal OldStyle&=_Optional ByVal NewStyle&=_Optional ByVal Ext&=_Optional ByVal SubClass&=)转化成VB NET的声明类似下面的样子(习惯使然我把&展开成了As Integer)

5、 Declare Function SubClass Lib dssubcls(ByVal HwndSubclass As Integer Optional ByVal Address As Integer= Optional ByVal OldStyle As Integer= Optional ByVal NewStyle As Integer= Optional ByVal Ext As Integer= Optional ByVal SubClass As Integer=) As Integer

6、这不是很好嘛?问题来了这样的声明在VB里面可以使用Addressof function来传入第二个参数(参见你下载的源码)但是在VB NET里面直接Addressof就不成了——我们需要委托一个回调

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

8、 Private Function mCallback(ByVal wMsg As Integer ByVal wParam As Integer ByVal lParam As Integer) As Integer在这里处理得到的消息

9、使用时需要注意先实例化这个委托

10、 Private fix_COCD= New HookCallBack(AddressOf mCallback)

11、此时 fix_COCD就是我们的mCallback函数引用了用更直观的观点来看 fix_COCD就是一个指向mCallback的指针相当于VB里面的Addressof function得到的结果看似问题解决了于是我们写了以下代码来搞对方的进程窗体消息

12、 SubClass(Handle fix_COCD)修改处理函数

13、问题真是接踵而至!IDE提示变量类型不符!!事实确实如此我们把一个HookCallBack类型当做Integer来传递无法通过检查那么强行转换吧?当然你可以去试试这时我所做的是修改这个API声明

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

15、使之符合我们的调用?有点倒行逆施?并非如此当你习惯了修改API声明之后会发现有些事变得如此简单有些事需要你重新认识——对于WIN API也是如此

16、 CodePrivate Declare Function SubClass Lib dssubcls(ByVal HwndSubclass As Integer Optional ByVal Address As HookCallBack= Nothing Optional ByVal OldStyle As Integer= Optional ByVal NewStyle As Integer= Optional ByVal Ext As Integer= Optional ByVal SubClass As Integer=) As IntegerPrivate 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 IntegerPublic Sub Hook(ByVal Handle As Integer)proc= SubClass(Handle fix_COCD)修改处理函数UseSendMessage()End Sub

17、 Private Function mCallback(ByVal wMsg As Integer ByVal wParam As Integer ByVal lParam As Integer) As Integer

18、用这个代码的时候可能会碰见一些意外情况例如wm_datacopy此时我们需要进一步去获取LPARTM所指向的结构并对其进行解析(我们要读的是对方窗口所在进程的内存具体地址由lParam确定——实际上lParam一直是一个指针——IntPrt但它与Integer完全就是一回事(如果你使用VB可能需要使用Intprt toint或intprt=new intprt(integer)这些)

19、 CodePublic Class GetMsgPublic Declare Function ReadProcessmemory Lib kernel(ByVal hProcess As Integer ByVal lpBaseAddress As Integer ByVal lpBuffer() As Byte ByVal nSize As Integer ByRef lpNumberOfBytesWritten As Integer) As IntegerPublic Declare Function ReadProcessmemory Lib kernel(ByVal hProcess As Integer ByVal lpBaseAddress As Integer ByRef int As Integer ByVal nSize As Integer ByRef lpNumberOfBytesWritten As Integer) As IntegerPublic Declare Function OpenProcess Lib kernel(ByVal dwDesiredAccess As Integer ByVal bInheritHandle As Integer ByVal dwProcessId As Integer) As IntegerPublic Declare Function CloseHandle Lib kernel(ByVal hObject As Integer) As IntegerPrivate hProc As IntPtrSub New(ByVal PID As Integer)hProc= OpenProcess(&HFFFF False PID)End Sub

20、 Function readmsg(ByVal address As Integer) As Byte()Dim buf() As ByteReadProcessmemory(hProc address buf)Return bufEnd Function

21、 Protected Overrides Sub Finalize()CloseHandle(hProc)MyBase Finalize()End SubEnd Class这个类提供了Readmsg方法来读取一些内容——但这并不是完整的我们知道 LPARAM指向的结构是这样的

22、_Public Structure COPYDATASTRUCTPublic dwData As IntegerPublic cbData As IntegerPublic lpData As IntPtrEnd Structure

23、其中dwData我们不是很关心当然其中也可能存在一些有用信息(这里不想多说网上有些文章纯属误导)

24、而cbData是一个长度 lpData的长度

25、 lpData这里被声明为指针看起来更直观了——它就是地址

26、有了地址和长度如何读取代码就自己写吧

27、提示一下参考我重载的ReadProcessmemory可能对你有不少帮助

28、当然上面提到的只是特殊情况中的一个典型还有很多时候进程是用自定义消息(>&H A)来传递数据的例如我所开发的这个工程打印mCallBack的参数后得到的是如下结果(十六进制只提取了有用的信息)

29、其中lParam就是一个指针我读了其中的一部分

30、 Function readmsg(ByVal address As Integer) As Byte()Dim buf() As ByteReadProcessmemory(hProc address buf)Return bufEnd Function

31、现在就明白为什么上面的代码是那样了)

32、然后进行了一个处理得到了我想要的信息

33、消息解码后得到的移动棋子信息玩家起X起Y止X止Y棋子编号

34、走棋总步数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 IntegerIf wParam=&H ThenDim s As Byte()= msg readmsg(lParam)RaiseEvent Move(s() s() s() s() s() s() s())End IfEnd Function

35、当然在我的工程里面重载的ReadProcessmemory并没有被使用

36、在VB NET中处理自己的窗体的消息只需要重载窗体消息处理过程就可以了无需子类化)

OK,关于消息钩子和消息钩子软件的内容到此结束了,希望对大家有所帮助。