利用钩子函数来捕捉键盘响应的windows应用程序

利用钩子函数来捕捉键盘响应的windows应用程序,第1张

利用钩子函数来捕捉键盘响应的windows应用程序,第2张

1.简介:

你可能一直对金山词霸截屏词的实现原理感到困惑。你可能想及时记录下自己键盘鼠标的活动,甚至你想知道木马是如何在windows操作系统中加载木马dll的...其实这些都是windows的钩子功能。因此,本文将讲解钩子函数的相关知识。当然,本文的目的并不是让读者通过这个程序窃取别人的密码,而是因为hook函数是windows系统中一个非常重要的系统接口函数,所以想和大家探讨一下。当然,本文也对如何建立动态链接库(DLL)做了一些简单的描述。(本文的程序是vc6.0的开发环境,语言为:C和win32 api)。

二。挂钩概述:

微软的windowsX操作系统基于事件驱动机制,即通过消息传递。在windows操作系统中,hook是一种可以在事件到达应用程序之前接收事件(如消息、鼠标激活、键盘响应)的机制。而且钩子函数还可以通过修改、丢弃等手段作用于事件。
Windows有两种挂钩,一种是特定线程挂钩,另一种是全系统挂钩。特定线程钩子只监视指定的线程,而全局系统钩子可以监视系统中的所有线程。无论是特定线程钩子还是全局系统钩子,钩子都是通过SetWindowsHookEx()设置的。对于特定的线程钩子,钩子函数可以包含在。exe或. dll。但是对于全局系统钩子,钩子函数必须包含在单独的dll中。因此,当我们想要捕捉键盘响应时,我们必须创建一个动态链接库。但是,当hook函数获得控制权并处理了相关事件后,如果希望消息继续传递,则必须调用另一个函数:CallNextHookEx。因为系统要处理每一条消息,钩子程序增加了处理负担,从而降低了系统的性能。有鉴于此,windows ce中不支持hook程序。所以当程序结束退出时,你要释放钩子,调用函数:UnhookWindowsHookEx。
接下来我们举一个例子(抓取键盘)来详细讲解hook函数的程序设计。

三、程序的设计:

I:设置挂钩。

设置钩子是通过SetWindowsHookEx()的API函数。
Prototype:hhook setWindowsHookex(int id hook,hook pro lpfn,hint hmod,Ord dw threadid)
idhook:加载钩子的类型。
lpfn:钩子进程的入口地址
hMod:应用程序的事件句柄
dwThreadId:加载钩子的线程标识

参数:
idHook:
该参数可以是以下值:
WH_CALLWNDPROCRET、WH_CBT、WH_DEBUG、WH_FOREGROUNDIDLE、WH_GETMESSAGE、WH_JOURNALPLAYBACK、WH_JOURNALRECORD、WH_KEYBOARD、WH_KEYBOARD_LL、WH_MOUSE、WH_MOUSE_LL、WH_MSGFILTER、WH_SHELL、WH_SYSMSGFILTER .
我不想一一解释这些参数,因为在MSDN有关于它们的详细评论。我只选择其中的几个用中文解释。
WH_KEYBOARD:一旦有敲击键盘的消息(键盘按下,键盘弹出),WINDOWS会调用你的hook函数,才会将这个消息放入应用程序的消息队列中。钩子函数可以改变和丢弃键盘敲击信息。
WH _鼠标:在每个鼠标消息被放入应用程序的消息队列之前,WINDOWS会调用你的钩子函数。钩子函数可以改变和丢弃鼠标消息。

WH_GETMESSAGE:每次你的应用程序调用GETMESSAGE()或PeekMessage()从应用程序的消息队列中请求消息时,WINDOWS都会调用你的钩子函数。钩子函数可以改变并丢弃这个消息。

二:松开钩子

使用UnhookWindowsHookEx()函数释放钩子
prototype:bool unhook windowshookex(hhookhk)
unhook windowshookex()函数将释放钩子链中SetWindowsHookEx函数加载的钩子进程。
hhk:将被释放的钩子进程的句柄。

三:挂钩过程

钩子进程使用函数HookProc实际上,HookProc只是应用程序定义的一个符号。比如你可以写KeyBoardHook。但是参数是不变的。Win32 API提供的函数有:CallWndProc、GetMsgProc、DebugProc、CBTProc、MouseProc、KeyboardProc、MessageProc等。关于他们的详细解释,请参考MSDN。这里我只解释一下KeyBoardHook的意思。
Prototype: LResult回调键盘钩子(Intncode,WPARAM WPARAM,LPARAM LPARAM)
描述:钩子进程是一些附加在钩子上的函数,所以钩子进程只被WINDOWS调用而不被应用程序调用,它们有时需要作为回调函数使用。

参数说明:
nCode:钩子代码,钩子进程用来决定是否执行。钩子代码的值取决于钩子的种类。每种类型的钩子都有自己的代码,并有一系列的特征。比如对于WH _键盘,钩子代码的参数是:HC_ACTION,HC_NOREMOVE。HC_ACTION的含义:参数wParam和lParam包含键盘敲击消息的信息,HC_NOREMOVE的含义:参数wParam和lParam包含键盘敲击消息的信息,键盘敲击消息没有从消息队列中删除。(应用程序调用PeekMessage函数并设置PM_NOREMOVE标志)。也就是说,当nCode等于HC_ACTION时,钩子子程必须处理消息。当使用HC_NOREMOVE时,钩子子程必须将消息传递给CallNextHookEx函数而不做进一步处理,并且必须有CallNextHookEx函数的返回值。
wParam:键盘敲击产生的键盘消息,键盘按键的虚拟代码。
lParam:包含消息详细信息。

注意:如果钩子进程中的nCode小于零,钩子进程必须返回CallNextHookex (ncode,wparam,lparam);钩子子程中的nCode大于零,但是钩子子程不处理消息。作者建议你调用CallNextHookEx,返回这个函数的返回值。否则,如果另一个应用程序也加载了WH键盘钩子,钩子将不接受钩子通知并返回一个不正确的值。如果钩子进程处理消息,它可能会返回一个非零值,以防止系统将消息传递给其他剩余的钩子或windows进程。所以CallNextHookEx的返回值是在钩子过程结束时返回的。

IV:调用下一个钩子函数。

调用下一个钩子函数时使用CallNexHookEx函数。
Prototype:LRESULT CallNextHookex(hhook HHK,Intncode,WParam WParam,LPARAM LPARAM)
CallNexHookex()函数用于将钩子信息传递给当前钩子链中的下一个钩子进程。钩子子程可以在钩子信息被处理之前或之后调用这个函数。为什么要使用这个功能在hook iii过程中的“注意事项”中已经有详细说明。
hhk:当前钩子的句柄
nCode:传递给钩子进程的钩子代码。
wParam:传递给挂钩进程的值。
lParam:传递给挂钩进程的值。
参数:
hhk:当前钩子的句柄。应用程序接受这个句柄作为之前调用SetWindowsHookE函数
nCode的结果:钩子代码传输到钩子进程,下一个钩子进程使用这个代码来决定如何处理钩子信息。
wParam:传输到挂钩进程的wParam参数值。参数值的具体含义与当前钩子链的钩子类型有关。
lParam: wParam参数值传递给钩子进程,参数的具体含义与当前钩子链的钩子类型有关
返回值:返回值是链中下一个钩子进程返回的值,当前钩子进程必须返回这个值。返回值的具体含义与钩子的钩子类型有关。具体请参考具体的hook流程描述。

建立一个动态链接库

当我们熟悉了上面的函数,现在开始写动态链接库(DLL)。这里我用WIN32 DLL代替MFC DLL。而且后面的程序都是用C语言写的。这主要是因为WIN32 API可以更细致更全面的控制程序如何执行,而一些底层的控制用MFC是做不到的(当然只针对这个程序,MFC也可以用)。

位律师回复
DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
白度搜_经验知识百科全书 » 利用钩子函数来捕捉键盘响应的windows应用程序

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情