课程报告windows钩子程序实现班级:学号:姓名:教师评语:教师签名:2010年7月课程设计题目windows钩子程序实现目的和背景目的:1)更深入的学习C++,并学会在Visual C++ 6.0上编写应用程序2)了解windows钩子程序的基本原理,类型和实现过程3)掌握用C++来设计一个钩子程序背景:钩子的本质是一段用以处理系统消息的程序,通过系统调用,把他挂入系统。
钩子的种类很多,每种钩子可以截获并处理相应的消息,每当特定的消息发出,在到达目的窗口之前,钩子程序先行截获该消息、得到对此消息的控制权。
此时钩子函数可以对截获的消息进行加工处理,甚至可以强制结束消息的传递。
鼠标钩子是能截获鼠标的操作,包括单击,双击,鼠标所在的位置等;而键盘钩子是截获从键盘输入的信息。
主要内容1)熟悉钩子程序在Windows操作系统的作用2)通过找资料,学习钩子程序的基本原理,包括Windows的消息传递机制,钩子的概念,钩子的类型,钩子的实现过程3)学习和掌握钩子函数,Win32全局钩子的运行机制,VC6中MFC DLL的分类及特点和在VC6中全局共享数据的实现4)用C++编写一个windows钩子程序;实现适时获取当前鼠标所在窗口的标题和监视各种键盘消息,如,把把鼠标所在窗口标题显示在一个EDITBOX中,从键盘输入的信息记录在一个文档里采用的工具方法Windows XP 操作系统,Visual C++ 6.0进度安排1)18周周(三)—18周周(四):查找相关的资料,对钩子程序的相关知识进行全面的了解2)18周周(五)—19周周(一):对程序进行分析,并加强有关方面的知识,如,C++编程的能力3)19周周(二)—19周周(三):学习了解Win32全局钩子的运行机制,VC6中MFC DLL的分类及特点和在VC6中全局共享数据的实现4)19周周(四)—20周周(一):编码实现windows钩子程序,并实现相应的功能5)20周周(二)—20周周(三):进行程序测试参考资料[1] 王育坚.Visual C++面向对象编程教程(第2版)[M].北京:清华大学出版社,2007.10.[2] 王西武,阎梅,赵怀勋. 在VC6下应用Windows系统钩子技术[J]. 现代电子技术 . 2004:27(17) .[3] 徐士良.常用算法程序集:C++语言描述(第4版)[M].北京:清华大学出版社,2009.7.[4] 钱能.C++程序设计教程:设计思想与实现(修订版)[M].北京:清华大学出版社.2009.7.[5] 游洪跃, 伍良富, 王景熙.C++面向对象程序设计实验和课程设计教程[M].北京:清华大学出版社,2009.2.[6]倪步喜.Windows的钩子技术及实现[J].计算机与现代化.2007,28(1):28-30.1目的和背景钩子的本质是一段用以处理系统消息的程序,通过系统调用,把他挂入系统。
钩子的种类很多,每种钩子可以截获并处理相应的消息,每当特定的消息发出,在到达目的窗口之前,钩子程序先行截获该消息、得到对此消息的控制权。
此时钩子函数可以对截获的消息进行加工处理,甚至可以强制结束消息的传递。
鼠标钩子是能截获鼠标的操作,包括单击,双击,鼠标所在的位置等;而键盘钩子是截获从键盘输入的信息。
通过这个课程设计,目的是更深入的学习C++,并学会在Visual C++ 6.0上编写应用程序,了解windows钩子程序的基本原理,类型和实现过程,掌握用C++来设计一个钩子程序。
2设计想思钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。
每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。
这时钩子函数即可以加工处理该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。
对每种类型的钩子由系统来维护一个钩子链,最近安装的钩子放在链的开始,而最先安装的钩子放在最后,也就是后加入的先获得控制权。
由此,我们建立一个鼠标和键盘钩子,把它挂入系统,鼠标钩子是能截获鼠标所指的窗口的标题,而键盘钩子是截获从键盘输入的字符。
因为要建立的是全局钩子,要Win32的运行机制,并且在Visual C++6.0中用Win32 DLL来构造动态链接库。
3函数与数据结构(1)函数SetWindowsHookEx要实现Win32的系统钩子,必须调用SDK中的API函数SetWindowsHookEx来安装这个鼠标和键盘钩子,这个函数的原型是HHOOKSetwindowsHookEx(int idHook,HOOKPROC Lpfn,INSTANCE hMod,DWORD dwTreadId)参数:idHook:表示钩子类型,它是和钩子函数类型一一对应的。
比如,WH_KEYBOAR,表示安装的是键盘钩子,WH_MOUSE表示是鼠标钩子等。
Lpfn:是钩子函数的地址。
HMod:是钩子函数所在的实例的句柄。
对于线程钩子,该参数为NULL;对于系统钩子,该参数为钩子函数所在的DLL句柄。
dwThreadId :指定钩子所监视的线程的线程号。
对于全局钩子,该参数为NULL。
SetWindowsHookEx:返回所安装的钩子句柄。
值得注意的是线程钩子和系统钩子的钩子函数的位置有很大的差别。
线程钩子一般在当前线程或者当前线程派生的线程内,而系统钩子必须放在独立的动态链接库中。
(2)函数WINAPI DllMain当一个进程或线程载入和卸载DLL时,都要调用该函数,它的原型是BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason, LPVOID lpvReserved);其中:第一个参数hinstDLL:表示DLL的实例句柄;第二个参数fdwReason:它有四个可能的值:DLL_PROCESS_ATTACH(进程载入),DLL_THREAD_ATTACH(线程载入),DLL_THREAD_DETACH(线程卸载),DLL_PROCESS_DETACH (进程卸载),在DLLMain函数中可以对传递进来的这个参数的值进行判别,并根据不同的参数值对DLL进行必要的初始化或清理工作。
举个例子来说,当有一个进程载入一个DLL时,系统分派给DLL的第二个参数为DLL_PROCESS_ATTACH,这时,你可以根据这个参数初始化特定的数据。
第三个参数lpvReserved:是系统保留;在Win32环境下,所有应用程序都有自己的私有空间,每个进程的空间都是相互独立的,这减少了应用程序间的相互影响,但同时也增加了编程的难度。
当进程在载入DLL时,系统自动把DLL地址映射到该进程的私有空间,而且也复制该DLL的全局数据的一份拷贝到该进程空间,也就是说每个进程所拥有的相同的DLL的全局数据其值却并不一定是相同的。
因此,在Win32环境下要想在多个进程中共享数据,就必须进行必要的设置。
亦即把这些需要共享的数据分离出来,放置在一个独立的数据段里,并把该段的属性设置为共享。
(3)函数MouseProcMouseProc 是鼠标钩子处理函数,当SetWindowsHookEx函数第一个参为:WH_MOUSE 时,调用本函数,首先要在系统中安装一个鼠标消息钩子。
函数原型:LRESULT CALLBACK MouseProc( int nCode,WPARAM wParam,LPARAM lParam);参数:nCode:跟所有其他钩子处理函数一样,当nCode小于0时:调用CallNextHookEx()。
nCode 可以是HC_ACTION和HC_NOREMOVE。
当nCode等于HC_ACTION时,wParam和lParam 包含鼠标信息;当nCode等于HC_NOREMOVE时,wParam和lParam 包含鼠标信息,并且鼠标消息没有从消息队列里移除。
wParam:指定鼠标消息ID。
lParam:一个MOUSEHOOKSTRUCT 结构的指针。
返回值:如果参数ncode小于0,则必须返回CallNextHookEx(),也就是CallNextHookEx()的返回值如果参数ncode大于等于0,并且钩子处理函数没有处理消息,CallNextHookEx()的返回值,否则当您安装WH_MOUSE钩子的应用程序将不会得到通知,并且得到一个错误的结果,如果钩子处理的消息,您可以返回一个非0值,防止系统把消息发送到目标窗口程序。
(4)函数KeyboardProcKeyboardProc是键盘钩子处理函数函数原型:LRESULT CALLBACK KeyboardProc( int code,WPARAM wParam,LPARAM lParam );参数:Code:根据这个数值决定怎样处理消息如果code 小于0,则必须KeyboardProc()函数返回CallNextHookEx() code可以是下列值:HC_ACTION:wParam和lParam包含按键消息;HC_NOREMOVE:wParam和lParam包含按键消息,并且按键消息不能从消息队列中移除。
wParam:按键的虚拟键值消息。
lParam:32位内存,内容描述包括:指定扩展键值,扫描码,上下文,重复次数。
0-15位:按下键盘次数;16-23位:指定扫描码,依赖于OEM ;24位为1时候:表示按键是扩展键;为0时候:表示按键是是数字键盘按键;25-28位:保留位;29位:上下文键:为1时:ALT按下,其他情况为0 ;30位:如果是按键按下后发送的消息,30位为1,如果是按键抬起后30位为1;31位:指定转变状态:31位为0时候,按键正在被按下,为1时候,按键正在被释放。
返回值:如果参数code小于0,则必须返回CallNextHookEx(),也就是返回CalNext HookEx()的返回值如果参数code大于等于0,并且钩子处理函数没有处理消息,返回CallNextHookEx()的返回值,否则当您安装WH_KEYBOARD钩子时,钩子将不会得到通知,并返回错误结果。
如果钩子处理的消息,可以返回一个非0值,防止系统把消息传递给钩子链中的下一个钩子,或者把消息发送到目标窗口。
(5)函数CallNextHookEx功能是调用下一个钩子,原型为:CallNextHookEx(hhk HHOOK,nCode Integer,wParam WPARAM,lParam LPARAM);参数:HHOOK:当前钩子的句柄nCode:钩子代码; 就是给下一个钩子要交待的WPARAM:要传递的参数; 由钩子类型决定是什么参数LPARAM:要传递的参数; 由钩子类型决定是什么参数返回值:返回下一个钩子执行后的返回值:0表示失败。