开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 2032|回复: 4
收起左侧

[图文教程] C - VB编程中钩子的实现及应用

[复制链接]

结帖率:74% (14/19)
发表于 2012-4-8 05:36:54 | 显示全部楼层 |阅读模式   山西省太原市
前言
  Windows系统中钩子具有相当强大的功能,通过这种技术可以对几乎所有的Windows 系统中的消息进行拦截、监视、处理。这种技术可以广泛应用于各种软件,尤其是需要有监控、自动记录等对系统进行监测功能的软件。本文针对这个专题进行了探讨,希望可以为读者朋友们起到抛砖引玉的作用。
  一、钩子的机制及类型
  Windows的应用程序都是基于消息驱动的,应用程序的操作都依赖于它所得到的消息的类型及内容。钩子与Dos中断截获处理机制有类似之处。钩子(Hook)是Windows消息处理机制的一个平台,通过安装各种钩子,应用程序可以在上面设置子程序以监视指定窗口的某种消息,并且当消息到达目标窗口之前处理它。
  在Windows中,钩子有两种,一种是系统钩子(RemoteHook),它对消息的监视是整个系统范围,另一种是线程钩子(LocalHook),它的拦截范围只有进程内部的消息。对于系统钩子,其钩子函数(HookFunction)应在Windows系统的动态链接库(DLL)中实现,而对于线程钩子来说,钩子函数可以在DLL之中实现,也可以在相应的应用程序之中实现。这是因为当开发人员创建一个钩子时,Windows先在系统内存中创建一个数据结构,该数据结构包含了钩子的相关信息,然后把该结构体加到已经存在的钩子链表中去,并且新的钩子将排在老的钩子的前面。当一个事件发生时,如果安装的是一个局部钩子,当前进程中的钩子函数将被调用。如果是一个远程钩子,系统就必须把钩子函数插入到其它进程的地址空间,要做到这一点就要求钩子函数必须在一个动态链接库中,所以如果想要使用远程钩子,就必须把该钩子函数放到动态链接库中去。对于钩子所监视的消息类型来说,Windws一共提供了如下几种类型:如表1所示:
  表一、Windows消息类型
  
消息类型常量标识消息类型适用范围
WH_CALLWNDPROC4 发给窗口的消息线程或系统
WH_CALLWNDPROCRET12窗口返回的消息线程或系统
WH_CBT5 窗口变化、焦点设定等消息线程或系统
WH_DEBUG 9 是否执行其它Hook的Hook线程或系统
WH_FOREGROUNDIDLE11前台程序空闲 线程或系统
WH_GETMESSAGE 3 投放至消息队列中的消息线程或系统
WH_JOURNALPLAYBACK1 将所记载的消息进行回放系统
WH_JOURNALRECORD0 监视并记录输入消息系统
WH_KEYBOARD 2 键盘消息 线程或系统
WH_MOUSE7 鼠标消息线程或系统
WH_MSGFILTER-1菜单滚动条、对话框消息 线程或系统
WH_SHELL10 外壳程序的消息 线程或系统
WH_SYSMSGFILTER6 所有线程的菜单滚动条、对话框消息系统

  二、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来说,虽然很多人认为是非专业的设计工具,但实现钩子这样的高级技术也是非常方便的。另外在使用钩子时应注意到,钩子虽然功能比较强,但如果使用不当将会严重影响系统的效率,所以要尽量避免使用系统钩子,并且在不用钩子时,应将钩子及时卸载
结帖率:92% (11/12)
发表于 2012-4-11 20:53:20 | 显示全部楼层   山东省济宁市
顶起。。。。。。
回复 支持 反对

使用道具 举报

发表于 2012-4-12 13:54:10 | 显示全部楼层   江苏省南京市
看看。了解一下。。。。。。。。。
回复 支持 反对

使用道具 举报

发表于 2012-4-12 15:48:03 | 显示全部楼层   湖北省武汉市
刚才游戏去了 ~~嘿嘿~~
回复 支持 反对

使用道具 举报

结帖率:0% (0/2)

签到天数: 2 天

发表于 2012-9-24 08:26:53 | 显示全部楼层   湖北省黄冈市
谢谢.学习了!!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:wp@125.la
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表