Windows Hook机制
转自https://blog.csdn.net/xkdcc/article/details/1531779 本文将试图以下面的顺序讲解HOOK的大部分内容: 1、WINDOWS的消息机制 2、HOOK介绍 3、HOOK链 4、HOOK钩子的作用范围 5、HOOK类型 6、回调函数 7、HOOK钩子的安装与卸载 +++++++++++++++++++ WINDOWS的消息机制 +++++++++++++++++++ Windows系统是以消息处理为其控制机制,系统通过消息为窗口过程(windows procedure)传递输入。系统和应用两者都可以产生消息。对于每个输入事件,例如用 户按下了键盘上的某个键、移动了鼠标、单击了一个控件上的滚动条,等等,系统都 将产生一系列消息。此外,对于应用带给系统的变化,如字体资源的改变、应用本身 窗口的改变,系统都将通过消息以响应这种变化。应用通过产生消息指示应用的窗口 完成特定的任务,或与其他应用的窗口进行通信。 每个窗口都有一个处理Windows系统发送消息的处理程序,称为窗口程序。它是 隐含在窗口背后的一段程序脚本,其中包含对事件进行处理的代码。 Windows系统为每条消息指定了一个消息编号,例如当一个窗口变为活动窗口时,它事 实上是收到一条来自Windows系统的WM_ACTIVATE消息,该消息的编号为6,它对 应于VB窗口的Activate事件。对于窗口来说,诸如Open、Activate、MouseDown、Resize 等事件,实际上对应的是窗口内部的消息处理程序,这些程序对于用户来讲是不可见的。 类似地,命令按钮也有消息处理程序,它的处理程序响应诸如WM_LBUTTONDOWN 和WM_RBUTTONDOWN之类的消息,即激活命令按钮的MouseDown事件。 WINDOWS的消息处理机制为了能在应用程序中监控系统的各种事件消息,提供 了挂接各种回调函数(HOOK)的功能。这种挂钩函数(HOOK)类似扩充中断驱动程序, 挂钩上可以挂接多个反调函数构成一个挂接函数链。系统产生的各种消息首先被送 到各种挂接函数,挂接函数根据各自的功能对消息进行监视、修改和控制等,然后交 还控制权或将消息传递给下一个挂接函数以致最终达到窗口函数。WINDOW系统的 这种反调函数挂接方法虽然会略加影响到系统的运行效率,但在很多场合下是非常有 用的,通过合理有效地利用键盘事件的挂钩函数监控机制可以达到预想不到的良好效 果。 +++++++++++ hook介绍 +++++++++++ Hook(钩子)是WINDOWS提供的一种消息处理机制平台,是指在程序正常运 行中接受信息之前预先启动的函数,用来检查和修改传给该程序的信息,(钩子)实 际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出, 在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这 时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还 可以强制结束消息的传递。 注意:安装钩子函数将会影响系统的性能。监测“系统范围事件”的系统钩子特 别明显。因为系统在处理所有的相关事件时都将调用您的钩子函数,这样您的系统将 会明显的减慢。所以应谨慎使用,用完后立即卸载。还有,由于您可以预先截获其它 进程的消息,所以一旦您的钩子函数出了问题的话必将影响其它的进程。记住:功能 强大也意味着使用时要负责任。 +++++++++++++ HOOK链 +++++++++++++ WINDOWS提供了14种不同类型的HOOKS;不同的HOOK可以处理不同的消 息。例如,WH_MOUSEHOOK用来监视鼠标消息。 WINDOWS为这几种HOOKS维护着各自的HOOK链表。HOOK链表是一串由 应用程序定义的回调函数(CALLBACKFunction)队列,当某种类型的消息发生时, WINDOWS向此种类型的HOOK链的第一个函数(HOOK链的顶部)发送该消息, WH_JOURNALRECORDHook用来监视和记录输入事件。典型的,可以使用这 须查询WIN32API指南来得到不同类型钩子参数的详细定义以及它们返回值的意义。(如果哪位朋友有时间和兴趣的话,请整理一下贴出来,顺便发给我一份,我的邮箱:wlclass163.com)譬如:WH_CALLWNDPROCnCode只能是HC_ACTION,它代表有一个消息发送给了一个窗口wParam如果非0,代表正被发送的消息lParam指向CWPSTRUCT型结构体变量的指针returnvalue:未使用,返回0WH_MOUSEnCode为HC_ACTION或HC_NOREMOVEwParam包含鼠标的事件消息lParam指向MOUSEHOOKSTRUCT型结构体变量的指针returnvalue:如果不处理返回0,否则返回非0值++++++++++++++++++++++++++钩子的安装/卸载++++++++++++++++++++++++++现在我们知道了一些基本的理论,接下来开始讲解如何安装和卸载一个钩子。◆安装钩子使用SetWindowsHookEx函数(API函数),指定一个HOOK类型、自己的HOOK过程是全局还是局部HOOK,同时给出HOOK过程的进入点,就可以轻松的安装你自己的HOOK过程。SetWindowsHookEx总是将你的HOOK函数放置在HOOK链的顶端。你可以使用CallNextHookEx函数将系统消息传递给HOOK链中的下一个函数。[注意]对于某些类型的HOOK,系统将向该类的所有HOOK函数发送消息,这时,HOOK函数中的CallNextHookEx语句将被忽略。全局(远程钩子)HOOK函数可以拦截系统中所有线程的某个特定的消息,为了安装一个全局HOOK过程,必须在应用程序外建立一个DLL,并将该HOOK函数封装到其中,应用程序在安装全局HOOK过程时必须先得到该DLL模块的句柄。将DLL名传递给LoadLibrary函数,就会得到该DLL模块的句柄;得到该句柄后,使用GetProcAddress函数可以得到HOOK过程的地址。最后,使用SetWindowsHookEx将HOOK过程的首址嵌入相应的HOOK链中,SetWindowsHookEx传递一个模块句柄,它为HOOK过程的进入点,线程标识符置为0,指出:该HOOK过程同系统中的所有线程关联。如果是安装局部HOOK此时该HOOK函数可以放置在DLL中,也可以放置在应用程序的模块段。建议只在调试时使用全局HOOK函数。全局HOOK函数将降低系统效率,并且会同其它使用该类HOOK的应用程序产生冲突。SetWindowsHookEx函数的VB声明及参数解释:PublicDeclareFunctionSetWindowsHookExLib"user32"Alias"SetWindowsHookExA"(ByValidHookAsLong,ByVallpfnAsLong,ByValhmodAsLong,ByValdwThreadIdAsLong)AsLongSetWindowHookEx函数参数说明:idHook:代表是何种Hook(也就是上面讲的14种Hook)lpfn:代表处理Hook的过程所在的Address,这是一个CallBackFucnction(也就是上面讲的回调函数),当挂上某个Hook时,我们便得定义一个Function来当作某个信息产生时,来处理它的Function。因这个参数是一个Function的Address所以我们固定将HookFunction放在.Bas中,并以AddressOfHookFunc传入hmod:代表.DLL的hInstance,如果是LocalHook,该值可以是Null(VB中可传0进去),而如果是RemoteHook,则可以使用GetModuleHandle(".dll名称")来传入。dwThreadId:代表执行这个Hook的ThreadId(线程ID),如果不设定是那个Thread(线程)来做,则传0,而VB的LocalHook一般可传App.ThreadId进去ThreadID是您安装该钩子函数后想监控的线程的ID号。该参数可以决定该钩子是局部的还是系统范围的。如果该值为NULL,那么该钩子将被解释成系统范围内的,那它就可以监控所有的进程及它们的线程。如果您指定了您自己进程中的某个线程ID号,那该钩子是一个局部的钩子。如果该线程ID是另一个进程中某个线程的ID,那该钩子是一个全局的远程钩子。这里有两个特殊情况:WH_JOURNALRECORD和WH_JOURNALPLAYBACK总是代表局部的系统范围的钩子,之所以说是局部,是因为它们没有必要放到一个DLL中。WH_SYSMSGFILTER总是一个系统范围内的远程钩子。其实它和WH_MSGFILTER钩子类似,如果把参数ThreadID设成0的话,它们就完全一样了。SetWindowHookEx函数回值:如果SetWindowsHookEx()成功,它会传回一个值,代表目前的Hook的Handle,否则返回NULL。您必须保存该句柄,因为后面我们还要它来卸载钩子。CallNextHookEx函数的VB声明及参数解释:DeclareFunctionCallNextHookExLib"user32"Alias"CallNextHookEx"(ByValhHookAsLong,ByValncodeAsLong,lParamAsAny)AsLonghHook值是SetWindowsHookEx()的传回值,nCode,wParam,lParam则是回调函数中的三个参数。在钩子子程中调用得到控制权的钩子函数在完成对消息的处理后,如果想要该消息继续传递,那么它必须调用另外一个API函数CallNextHookEx来传递它,以执行钩子链表所指的下一个钩子子过程。这个函数成功时返回钩子链中下一个钩子过程的返回值,返回值的类型依赖于钩子的类型。◆卸载钩子要卸载一个钩子非常简单,只需要使用UnhookWindowsHookEx函数来卸载创建的钩子。函数声明:DeclareFunctionUnhookWindowsHookExLib"user32"Alias"UnhookWindowsHookEx"(ByValhHookAsLong)AsLong参数说明:hHook:是SetWindowsHookEx()的传回值,上面告诉过你要记下来嘛。^_^ (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 使用Burn作为WiX对话框和自定义操作的替代方法
- windows-phone-8.1 – Microsoft Band SDK部署错误:发布中
- windows-7 – Windows 7 64位上的FoxPro 2.6 DOS
- MySQL_8.0.15_Windows10_X64 安装教程
- windows – 如何在循环中获取局部变量的子串?
- windows-server-2008 – Server 2008 R2到Server 2016选项
- 如何在Windows中挂钩应用程序和进程启动?
- Windows锁屏幕后面会发生什么?
- 在Windows上设置gVim
- 在windows下部署包含C3P0的war包没问题,部署到linux下面的