VB编程中钩子的实现及应用

编程

 前言

  Windows系统中钩子具有相当强大的功能,通过这种技术可以对几乎所有的Windows 系统中的消息进行拦截、监视、处理。这种技术可以广泛应用于各种软件,尤其是需要有监控、自动记录等对系统进行监测功能的软件。本文针对这个专题进行了探讨,希望可以为读者朋友们起到抛砖引玉的作用。

  一、钩子的机制及类型

  Windows的应用程序都是基于消息驱动的,应用程序的操作都依赖于它所得到的消息的类型及内容。钩子与Dos中断截获处理机制有类似之处。钩子(Hook)是Windows消息处理机制的一个平台,通过安装各种钩子,应用程序可以在上面设置子程序以监视指定窗口的某种消息,并且当消息到达目标窗口之前处理它。

  在Windows中,钩子有两种,一种是系统钩子(RemoteHook),它对消息的监视是整个系统范围,另一种是线程钩子(LocalHook),它的拦截范围只有进程内部的消息。对于系统钩子,其钩子函数(HookFunction)应在Windows系统的动态链接库(DLL)中实现,而对于线程钩子来说,钩子函数可以在DLL之中实现,也可以在相应的应用程序之中实现。这是因为当开发人员创建一个钩子时,Windows先在系统内存中创建一个数据结构,该数据结构包含了钩子的相关信息,然后把该结构体加到已经存在的钩子链表中去,并且新的钩子将排在老的钩子的前面。当一个事件发生时,如果安装的是一个局部钩子,当前进程中的钩子函数将被调用。如果是一个远程钩子,系统就必须把钩子函数插入到其它进程的地址空间,要做到这一点就要求钩子函数必须在一个动态链接库中,所以如果想要使用远程钩子,就必须把该钩子函数放到动态链接库中去。对于钩子所监视的消息类型来说,Windws一共提供了如下几种类型:如表1所示:

表一、Windows消息类型

消息类型常量标识

消息类型
适用范围

WH_CALLWNDPROC
4
发给窗口的消息
线程或系统

WH_CALLWNDPROCRET
12
窗口返回的消息
线程或系统

WH_CBT
5
窗口变化、焦点设定等消息
线程或系统

WH_DEBUG
9
是否执行其它Hook的Hook
线程或系统

WH_FOREGROUNDIDLE
11
前台程序空闲
线程或系统

WH_GETMESSAGE
3
投放至消息队列中的消息
线程或系统

WH_JOURNALPLAYBACK
1
将所记载的消息进行回放
系统

WH_JOURNALRECORD
0
监视并记录输入消息
系统

WH_KEYBOARD
2
键盘消息
线程或系统

WH_MOUSE
7
鼠标消息
线程或系统

WH_MSGFILTER
-1
菜单滚动条、对话框消息
线程或系统

WH_SHELL
10
外壳程序的消息
线程或系统

WH_SYSMSGFILTER
6
所有线程的菜单滚动条、对话框消息
系统

  二、VB编程中钩子的实现

  (一)钩子函数(HOOK Function)的格式。Hook Function实际上是一个函数,如果是系统钩子,该函数必须放在动态链接库中。该函数有一定的参数格式,在VB中如下:

Private Function HookFunc(ByVal nCode As Long,ByVal wParam As Long,ByVal lParam As Long)As Long

  其中,nCode代表是什么情况之下所产生的钩子,随钩子的不同而有不同组的可能值;参数wParam,lParam传回值包括了所监视到的消息内容,它随Hook所监视消息的种类和nCode的值不同而不同。对于用VB所设置的钩子函数,一般的框架形式如下:

Private Function HookFunc(ByVal nCode As Long,ByVal wParam As Long,ByVal lParam As Long)As Long
 Select case of nCode
  case ncode<0:hookfunc=callnexthookex(hHookFunc,nCode,wParam,lParam)
  case值1:处理过程1:HookFunc=X1
  case2:处理过程2:HookFunc=X1
  ……
 end select
end Function

  函数的传回值,如果消息要被处理,则传0,否则传1,吃掉消息。

  (二)钩子的安装及执行。钩子的安装要用到几个API函数:可以使用API函数SetWindowsHookEx()把一个应用程序定义的钩子子程安装到钩子链表中。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值为它处理的消息类型;lpfn值为钩子子程序的地址指针。如果dwThreadId参数为0或是一个由别的进程创建的线程的标识,lpfn必须指向DLL中的钩子子程。除此以外,lpfn可以指向当前进程的一段钩子子程代码。hMod值为应用程序的句柄,标识包含lpfn所指的子程的DLL。如果dwThreadId标识当前进程创建的一个线程,而且子程代码位于当前进程,hMod必须为0。dwThreadId值为与安装的钩子子程相关联的线程的标识符,如果为0,钩子子程与所有的线程关联。钩子安装成功则返回钩子子程的句柄,失败返回0。

  另外,一般应在钩子子程中调用CallNextHookEx()函数以执行钩子链表所指的下一个钩子子程,否则安装了别的钩子的应用程序就会收不到钩子通知,从而产生错误的结果。CallNextHookEx()函数的声明如下:

Declare Function CallNextHookEx Lib"user32" Alias "CallNextHookEx"(ByVal hHook As Long,ByVal ncode As Lonog, ByVal wParam As Long,lParam As Any)As Long

  hHook值是SetWindowsHookEx()的传回值,nCode、wParam、lParam则是Hook函数中的三个参数。在程序终止之前,必须调用UnhookWindowsHookEx()函数释放与钩子关联的系统资源。UnhookWindowsEx()函数声明如下:

Declare Function Unhook WindowsHookEx Lib "user32" Alias "Unhook WindowsHookEx(ByVal hHook As Long)As Long

  hHook为安装钩子时的返回值,即钩子子程的句柄。

  (三)VB中钩子安装应注意的问题。lpfn参数是一个HookFunc的地址,VB规定必须将HookFunc代码放到标准的.BAS模块中,并以"Address Of HookFunc"传入,而不可以将其放到类模块中,也不能将其附加到窗体上。而对于RemoteHook来说,HookFunc应包含在动态链接库中,因此如果在VB中使用RemoteHook,则还要用到GetModuleHandle()、GetProcAddress()两个API函数,它们的声明如下:

Declare Function GetModuleHandle Lib"kernel32" Alias "GetModuleHandleA"(ByVal lpModuleName As String)As Long
Declare Function GetProcAddress Lib "kernel32" Alias "GetProcAddress"(ByVal hModule As Long,ByVal lpProcName As String)As Long

  hmod值是含钩子过程的模块名柄,如果是LocalHook,该值可以是Null(VB中传0),而如果是RemoteHook,则可以使用GetModuleHandle("名称.dll")来传入。
三、实例--键盘消息的拦截

  在程序开发时常用的有对输入消息进行监视的键盘钩子,对于所监视到的消息应进行处理,下面对键盘钩子参数的具体内容组成进行说明:

  如果有键盘消息(WM_KEYUP或WM_KEYDOWN)将被处理时,则系统调用键盘钩子。

  nCode为HC_ACTION或HC_NOREMOVE,若小于0,则要求处理函数向下传递该消息。

  wParam表示按键键码常数,A键到Z键与其ASCII码的相应值'A'到'Z'是一致的,例如按C键,则wParam值为67。

  lParam与WM_KEYDOWN同,占四个字节,其包括的内容较多,其二进制结构如下:

0
1
……
15
16
………
23
24
25
……
28
29
30
31

  0-15位(Key repeat count),键码重复次数。16-23位(Scan code),按键的扫描码。24位(Extended_Key flag),扩展键(功能键、数字小键盘上的键)标志,为1则是扩展键,否则为0。25-28位被保留。29位(Context Code),状态描述码,ALT键被按下则为1,否则为0。30位(Previouskey_stateflag)指定先前的键状态,如果消息被发出之前键处于按下状态,则为1;键处于释放状态则为0。31位(Transiton_stateflag)状态转换标志,如果键是被按下值为1,如果键被放开值为0。

  本例中的钩子用来监视并记录应用程序中的按键信息。在程序中,ALT+F4组合键被屏蔽。下面是部分代码:

Public hHook as Long
Private Sub Form_Load()′程序启动时安装钩子
hHook=SetWindowsHookEx(2,Address of MyKBHook,0,App.ThreadID)
End Sub
′具体的钩子程序,本例中该过程被包含在Module1中
Public Function MyKBHook(ByVal nCode As Long,ByVal wParam As Long,ByVal lParam As Long)As Long
If nCode>=0 then
Open "C:\Keyfile.txt" For Append As #1 '将键盘的操作记录在Keyfile.txt文件之中
'记录所操作的键、操作时间、日期操作时的按键状态,用16进制记录
Write #1,wParam,Hex(lParam),Date,time
Close #1
MyKBHook=0 '表示要处理这个消息
'屏蔽ALT+F4组合键
if wParam=115 And(lParam And&H20000000)<>0 Then
if(lParam And &HC000000)=0 Then  '是否进行ALT+F4操作
MyHBHook=1 '钩子吃掉这个消息
End if
End if
End if
Call CallNextHookEx(hHook,nCode,wParam,lParam)'将消息传给下一个钩子
End Function
'程序退出时卸载钩子
Private Sub Form_Unload(Cancel As Interger)
Call Unhook WindowsHookEx(hHook)
End Sub

  四、总结

  钩子处理程序是Windows高级编程技术,一般程序员都使用VC++等程序设计工具实现,本文表明,对于VB来说,虽然很多人认为是非专业的设计工具,但实现钩子这样的高级技术也是非常方便的。另外在使用钩子时应注意到,钩子虽然功能比较强,但如果使用不当将会严重影响系统的效率,所以要尽量避免使用系统钩子,并且在不用钩子时,应将钩子及时卸载。

时间: 2024-12-12 13:40:12

VB编程中钩子的实现及应用的相关文章

vb编程 我使用的TCPListener和异步方法BeginAcceptTCPClient多个客户端 连接TCP服务器

问题描述 vb编程 我使用的TCPListener和异步方法BeginAcceptTCPClient多个客户端 连接TCP服务器 Public Sub TCPlisten() try Dim listener As New TcpListener(IPAddress.Any, Local_Port) listener.Start() listener.BeginAcceptTcpClient(New AsyncCallback(AddressOf AcceptClient), listener)

VB6和VB.NET中对光标的编程

编程 在VB6中利用API对光标进行编程: Option ExplicitPrivate Type POINTAPI    X As Long    Y As LongEnd TypePrivate Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As LongPrivate Declare Function ShowCursor Lib "user32" (ByVal bShow A

VB.NET数据库编程中的图形处理

编程|数据|数据库|图形 把图形文件名存入数据库中,这是VB.NET数据库编程中处理图形的一种简单有效的方法.本文就介绍如何在VB.NET中使用这种方法来设计Windows和Web图形据库程序. 关键词:VB.NET,数据库,图形,Windows程序,Web程序. 随着多媒体技术的发展,图形数据库在实际应用中已经越来越广泛了.在VB.NET数据库编程中处理图形的方法之一就是把图形作为数据库的一个字段存放到数据库中:第二个方法就是把图形的文件名作为一个字段保存到数据库中,而一张张图片则作为独立的文

VB.NET中的面向对象编程特征

编程|对象 Visual Basic 7也被称作VB.NET,具备了面向对象(OOP)编程语言的所有特征.对于VB编程人员来说,面向对象的概念和面向对象编程方式都不陌生.       如果问一个面向对象程序设计高手什么是面向对象程序设计语言?他可能会说出一大堆诸如类.接口.消息隐匿.封装.继承.多态性这样的名词,这些名词听起来都很酷,不是吗?但面向对象编程并非通过一两天的学习或听一次课就能掌握的.要真正地掌握面向对   象程序设计,不但需要掌握一定的理论知识,同时还要进行一些实际的编程练习.本文

VB与VC混合编程中处理消息的方法

现在越来越多的人采用VB与VC的混合编程:用VB快速开发出漂亮的界面以及外围处理程序,再用VC编写底层的各种操作,例如内存的操作.IO端口的操作等,VC中还可以嵌入汇编语言进行更底层的操作. 一般的做法是将VC程序编译成DLL,在VB中用Declare语句声明DLL中的函数,例如: Declare Function SendCommand Lib ″c:\program files\devstudio\wjfprojects\Hr0506dllMnsr\debug\Hr0506dllMnsr.d

VB. NET中的USB编程

问题描述 想要在VB.net中实现下挂USB设备的通信,可以读写数据进USB设备中,可不可以通过API函数实现啊?如何实现呢?据说有个HIDP,最好有详细的例子哦,谢谢! 解决方案 解决方案二:USB不也是串口么?serialport啊解决方案三:serialport真的可以操作USB吗?有试过吗?我只用过一个DLL来与USB进行HID通讯.解决方案四:usb只是一个底层的协议,上层有模拟成网卡的.串口的.大容量存储的.人机交互设备的等等,那么它们的编程各不相同.

VB编程 及EXCEL 的VBA编程,用什么把一段代码括起来啊(就是用什么东西来实现C语言中的{}功能啊)?

问题描述 VB编程及EXCEL的VBA编程,用什么把一段代码括起来啊(就是用什么东西来实现C语言中的{}功能啊)? 解决方案 解决方案二:不是有begin和end吗解决方案三:region?C的{}有很多啊,只能你VB书都没看过if...endif-------------if{}for...endfor---------for{}解决方案四:for..next.............我草解决方案五:学c的时候用按键精灵的时候我也愣了一阵子...很多是用end,if之后用endif,while

vb.net中的钩子是指的什么东西

问题描述 vb.net中的钩子是指的什么东西 今年刚学的vb.net,我看到要好多人都提到了钩子,请问下什么是钩子呢,他都能干什么呢,请各位专家指点下 解决方案 简单来说,钩子(Hook)就是允许你在现有的系统中扩展你自己的处理代码.因为每个这样的处理程序在处理完自身后,又将控制权转移给下一个调用者,直至操作系统,很像钩子一样,顾名思义得到这个词. 最常用的钩子是windows中的键盘鼠标钩子和日志钩子,可以用来做键盘拦截和鼠标拦截,很多做网游外挂的人用它. VB6时代还有一种技术,就是通过拦截

【vb编程】怎样把数据保存到excel中

问题描述 小弟不会vb编程,特求大神给个demo,在此感谢! 下面是我在网上找到的例子,运行报错: Dim ExcelApp As Object Private Sub Form_Unload(Cancel As Integer) Dim X As Integer X = MsgBox("是否保存更改?", vbYesNoCancel + vbExclamation, "VB 保存数据到中 Excel") If X = 6 Then '单击"是"