欢迎光临
我们一直在努力

VB编程中钩子的实现及应用-.NET教程,VB.Net语言

建站超值云服务器,限时71元/月

 前言

  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来说,虽然很多人认为是非专业的设计工具,但实现钩子这样的高级技术也是非常方便的。另外在使用钩子时应注意到,钩子虽然功能比较强,但如果使用不当将会严重影响系统的效率,所以要尽量避免使用系统钩子,并且在不用钩子时,应将钩子及时卸载。

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » VB编程中钩子的实现及应用-.NET教程,VB.Net语言
分享到: 更多 (0)

相关推荐

  • 暂无文章