在Windows系统中用VC++实现钩子机制_第1页
在Windows系统中用VC++实现钩子机制_第2页
在Windows系统中用VC++实现钩子机制_第3页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

在Windows系统中用VC++实现钩子机制

摘要:本文分析了在Windows环境下,什么是钩子程序以及怎样用VC++实现一个钩子机制的关键技术。最后,用一个可以截获鼠标信息的完整程序说明了这些问题。关键词:钩子程序,DLL,消息截获一.

什么是钩子。Windows系统是建立在事件驱动的机制上的,说穿了就是整个系统都是通过消息的传递来实现的。钩子(hook)是一种特殊的消息处理机制,钩子可以监视系统或进程中的各种事件消息,截获发往目标窗口的消息并进行处理。这样,我们就可以在系统中安装自定义的钩子,监视系统中特定事件的发生,完成特定的功能,比如截获键盘、鼠标的输入,屏幕取词,日志监视等等。钩子的种类很多,每种钩子可以截获并处理相应的消息,如键盘钩子可以截获键盘消息,外壳钩子可以截取、启动和关闭应用程序的消息等。钩子可以分为线程钩子和系统钩子,线程钩子监视指定线程的事件消息,系统钩子监视系统中的所有线程的事件消息。因为系统钩子会影响系统中所有的应用程序,所以钩子函数必须放在独立的动态链接库(DLL)中。二.

实现钩子机制的几个关键技术。1.

windows的钩子程序,需要用到几个sdk中的api函数。下面列出这几个函数的原型及说明:hhooksetwindowshookex(intidhook,hook_proclpfn,hinstancehmod,dworddwthreadid);参数说明如下:

idhook:钩子的类型

lpfn:钩子处理函数地址

hmod:包含钩子函数的模块句柄

dwthreadid:钩子的监控线程函数说明:函数将在系统中挂上一个由idhook指定类型的钩子,监控并处理相应的特定消息。boolunhookwindowshookex(hhookhhk);函数说明:函数将撤销由hhk指定的钩子。lresultcallnexthookex(hhookhhk,intncode,wparamwparam,lparamlparam);函数说明:函数将消息向下传递,下一个钩子处理将截获这一消息。2.

由于钩子的处理涉及到模块及进程间的数据地址问题,一般情况是把钩子整合到一个动态链接库(dll)中,VC中有三种形式的MFCDLL可供选择,即RegularstaticallylinkedtoMFCDLL(标准静态链接MFCDLL)、RegularusingthesharedMFCDLL(标准动态链接MFCDLL)以及ExtensionMFCDLL(扩展MFCDLL)。第一种DLL在编译时把使用的MFC代码链接到DLL中,执行程序时不需要其他MFC动态链接类库的支持,但体积较大;第二种DLL在运行时动态链接到MFC类库,因而体积较小,但却依赖于MFC动态链接类库的支持;这两种DLL均可被MFC程序和Win32程序使用。第三种DLL的也是动态连接,但做为MFC类库的扩展,只能被MFC程序使用。另外,要设立一个全局数据共享数据段,以存贮一些全局变量,保留上次钩子消息事件发生时的状态。3.

Win32DLL的入口和出口函数都是DLLMain。只要有进程或线程载入和卸载DLL时,都会调用该函数,其原型是:BOOLWINAPIDllMain(HINSTANCEhinstDLL,DWORDfdwReason,LPVOIDlpvReserved);其中,第一个参数表示DLL的实例句柄;第三个参数系统保留;第二个参数指明了当前调用该动态连接库的状态,它有四个可能的值:DLL_PROCESS_ATTACH(进程载入)、DLL_THREAD_ATTACH(线程载入)、DLL_THREAD_DETACH(线程卸载)、DLL_PROCESS_DETACH(进程卸载)。在DLLMain函数中可以通过对传递进来的这个参数的值进行判别,根据不同的参数值对DLL进行必要的初始化或清理工作。由于在Win32环境下,所有进程的空间都是相互独立的,这减少了应用程序间的相互影响,但大大增加了编程的难度。当进程在动态加载DLL时,系统自动把DLL地址映射到该进程的私有空间,而且也复制该DLL的全局数据的一份拷贝到该进程空间,每个进程所拥有的相同的DLL的全局数据其值却并不一定是相同的。当DLL内存被映射到进程空间中,每个进程都有自己的全局内存拷贝,加载DLL的每一个新的进程都重新初始化这一内存区域,也就是说进程不能再共享DLL。因此,在Win32环境下要想在多个进程中共享数据,就必须进行必要的设置。一种方法便是把这些需要共享的数据单独分离出来,放置在一个独立的数据段里,并把该段的属性设置为共享,建立一个内存共享的DLL。三.

用钩子机制实现截获鼠标左右键按压次数。建立钩子程序时需要把钩子处理整合到动态链接库中,所以例程中需要建立两个project。1.

钩子处理动态链接库(1)

选择mfcappwizard(dll)创建一个新project,命名为“spy”。(2)

选择mfcextensiondll类型。(3)

创建一个新的头文件,命名为“hook.h”,修改它的代码如下:extern"C"LRESULTCALLBACKmouseproc(intcode,WPARAMwparam,LPARAMlparam);//钩子处理函数extern"C"boolWINAPIstarthook();//启动钩子函数extern"C"boolWINAPIstophook();//撤销钩子函数extern"C"intWINAPIgetresultl();//取得鼠标左键单击次数的函数extern"C"intWINAPIgetresultr();//取得鼠标右键单击次数的函数(4)

修改spy.cpp程序代码如下:#include"hook.h"

//包含头文件hook#pragmadata_seg("publicdata")//定义全局数据段HHOOKhhook=NULL;//钩子句柄HINSTANCEpinstance=NULL;//钩子模块句柄UINTmouseclickl=0;//记录鼠标左键单击次数的变量UINTmouseclickr=0;//记录鼠标右键单击次数#pragmadata_seg()extern"C"intAPIENTRYDllMain(HINSTANCEhInstance,DWORDdwReason,LPVOIDlpReserved)

{if(dwReason==DLL_PROCESS_ATTACH)

{……

//省略部分机器生成代码

newCDynLinkLibrary(SpyDLL);

pinstance=hInstance;//取得模块句柄}……;

}extern"C"LRESULTCALLBACKmouseproc(intcode,

WPARAMwparam,LPARAMlparam)//钩子处理函{

if(code<0)

//若code〈0,则直接调用callnexthookex返回returnCallNextHookEx(hhook,code,wparam,lparam);

if(wparam==WM_LBUTTONDOWN)

{

mouseclickl++;//记录鼠标左键单击次数

}

if(wparam==WM_RBUTTONDOWN)

{

mouseclickr++;//记录鼠标右键单击次数

}

returnCallNextHookEx(hhook,code,wparam,lparam);}extern"C"boolWINAPIstarthook()//启动钩子函数{

hhook=SetWindowsHookEx(WH_MOUSE,mouseproc,pinstance,0);//挂上钩子

if(hhook!=NULL)returntrue;

elsereturnfalse;}extern"C"boolWINAPIstophook()//撤销钩子函数{

returnUnhookWindowsHookEx(hhook);//撤销钩子}extern"C"intWINAPIgetresultl()//返回鼠标左键单击次数{

returnmouseclickl;}extern"C"intWINAPIgetresultr()//返回鼠标右键单击次数{

returnmouseclickr;}

(5)

修改spy.def程序代码如下:

exportsstophook@2starthook@1getresultl@3getresultr@4(6)编译project,生成spy.dll文件和spy.lib文件。2.

建立使用钩子的应用程序(1)

生成一个单文档的可执行文件(exe)的project。(2)

修改资源中的主选单,增加一个选单项“监控”,下有三个子选单项,分别为“启动”、“撤销”和“取出”。(3)

在project中加入spy.lib文件。(4)

分别修改“启动”、“撤销”和“取出”选单项的command响应函数如下:#include"E:\DevStudio\MyProjects\spy\hook.h"//路径可不同voidCMainFrame::OnMenuitem32771()//“启动”选单项的响应函数{

starthook();}voidCMainFrame::OnMenuitem32772()//“撤销”选单项的响应函数{

stophook();}voidCMainFrame::OnMenuitem32773()//“取出”选单项的响应函数{

intresultl=getresultl();

intresultr=getresultr();

charbuffer[80];

wsprintf(buffer,"在程序运行期间,你共单击鼠标左键%d次,右键%d次!",resultl,resultr);

::MessageBox(this->m_hWnd,buffer,"message",MB_OK);}编译这个project,并把spy.dll放到生成的可执行文件目录下,便可运行程序。运行时,选择“监控”选单中的“启动”选单项,钩子便开始工作,监视鼠标的活动情况;选择“撤销”选

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论