课程设计报告-windows钩子程序实现.doc

上传人:哈尼dd 文档编号:5027426 上传时间:2020-01-29 格式:DOC 页数:13 大小:372.50KB
返回 下载 相关 举报
课程设计报告-windows钩子程序实现.doc_第1页
第1页 / 共13页
课程设计报告-windows钩子程序实现.doc_第2页
第2页 / 共13页
课程设计报告-windows钩子程序实现.doc_第3页
第3页 / 共13页
课程设计报告-windows钩子程序实现.doc_第4页
第4页 / 共13页
课程设计报告-windows钩子程序实现.doc_第5页
第5页 / 共13页
点击查看更多>>
资源描述

《课程设计报告-windows钩子程序实现.doc》由会员分享,可在线阅读,更多相关《课程设计报告-windows钩子程序实现.doc(13页珍藏版)》请在三一文库上搜索。

1、课程设计报告windows钩子程序实现班级:学号:姓名:教师评语:教师签名:2010年7月课程设计题目windows钩子程序实现目的和背景目的:1)更深入的学习C+,并学会在Visual C+ 6.0上编写应用程序2)了解windows钩子程序的基本原理,类型和实现过程3)掌握用C+来设计一个钩子程序背景:钩子的本质是一段用以处理系统消息的程序,通过系统调用,把他挂入系统。钩子的种类很多,每种钩子可以截获并处理相应的消息,每当特定的消息发出,在到达目的窗口之前,钩子程序先行截获该消息、得到对此消息的控制权。此时钩子函数可以对截获的消息进行加工处理,甚至可以强制结束消息的传递。鼠标钩子是能截获鼠

2、标的操作,包括单击,双击,鼠标所在的位置等;而键盘钩子是截获从键盘输入的信息。主要内容1)熟悉钩子程序在Windows操作系统的作用2)通过找资料,学习钩子程序的基本原理,包括Windows的消息传递机制,钩子的概念,钩子的类型,钩子的实现过程3)学习和掌握钩子函数,Win32全局钩子的运行机制,VC6中MFC DLL的分类及特点和在VC6中全局共享数据的实现4)用C+编写一个windows钩子程序;实现适时获取当前鼠标所在窗口的标题和监视各种键盘消息,如,把把鼠标所在窗口标题显示在一个EDITBOX中,从键盘输入的信息记录在一个文档里采用的工具方法Windows XP 操作系统,Visual

3、 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 王西武,阎梅 ,赵怀勋. 在V

4、C6下应用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.- 11 -1目的和背景钩子的本质是一段用以处理系统消息的程序,通过系统调用,把他挂入系统。钩子的种类很多,每种钩子可以截获并处理

5、相应的消息,每当特定的消息发出,在到达目的窗口之前,钩子程序先行截获该消息、得到对此消息的控制权。此时钩子函数可以对截获的消息进行加工处理,甚至可以强制结束消息的传递。鼠标钩子是能截获鼠标的操作,包括单击,双击,鼠标所在的位置等;而键盘钩子是截获从键盘输入的信息。通过这个课程设计,目的是更深入的学习C+,并学会在Visual C+ 6.0上编写应用程序,了解windows钩子程序的基本原理,类型和实现过程,掌握用C+来设计一个钩子程序。2设计想思钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制

6、权。这时钩子函数即可以加工处理该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。对每种类型的钩子由系统来维护一个钩子链,最近安装的钩子放在链的开始,而最先安装的钩子放在最后,也就是后加入的先获得控制权。由此,我们建立一个鼠标和键盘钩子,把它挂入系统,鼠标钩子是能截获鼠标所指的窗口的标题,而键盘钩子是截获从键盘输入的字符。因为要建立的是全局钩子,要Win32的运行机制,并且在Visual C+6.0中用Win32 DLL来构造动态链接库。3函数与数据结构(1)函数SetWindowsHookEx要实现Win32的系统钩子,必须调用SDK中的API函数SetWindowsHookE

7、x来安装这个鼠标和键盘钩子,这个函数的原型是HHOOKSetwindowsHookEx(int idHook,HOOKPROC Lpfn,INSTANCE hMod,DWORD dwTreadId)参数:idHook:表示钩子类型,它是和钩子函数类型一一对应的。比如,WH_KEYBOAR,表示安装的是键盘钩子,WH_MOUSE表示是鼠标钩子等。Lpfn:是钩子函数的地址。HMod:是钩子函数所在的实例的句柄。对于线程钩子,该参数为NULL;对于系统钩子,该参数为钩子函数所在的DLL句柄。dwThreadId :指定钩子所监视的线程的线程号。对于全局钩子,该参数为NULL。SetWindowsH

8、ookEx:返回所安装的钩子句柄。值得注意的是线程钩子和系统钩子的钩子函数的位置有很大的差别。线程钩子一般在当前线程或者当前线程派生的线程内,而系统钩子必须放在独立的动态链接库中。 (2)函数WINAPI DllMain当一个进程或线程载入和 卸载DLL时,都要调用该函数,它的原型是BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason, LPVOID lpvReserved);其中:第一个参数hinstDLL:表示DLL的实例句柄;第二个参数fdwReason:它有四个可能的值:DLL_PROCESS_ATTACH(进程载入),DLL_T

9、HREAD_ATTACH(线程载入),DLL_THREAD_DETACH(线程卸载),DLL_PROCESS_DETACH (进程卸载),在DLLMain函数中可以对传递进来的这个参数的值进行判别,并根据不同的参数值对DLL进行必要的初始化或清理工作。举个例子来说,当有一个进程载入一个DLL时,系统分派给DLL的第二个参数为DLL_PROCESS_ATTACH,这时,你可以根据这个参数初始化特定的数据。第三个参数lpvReserved:是系统保留;在Win32环境下,所有应用程序都有自己的私有空间,每个进程的空间都是相互独立的,这减少了应用程序间的相互影响,但同时也增加了编程的难度。当进程在载

10、入DLL时,系统自动把DLL地址映射到该进程的私有空间,而且也复制该DLL的全局数据的一份拷贝到该进程空间,也就是说每个进程所拥有的相同的DLL的全局数据其值却并不一定是相同的。因此,在Win32环境下要想在多个进程中共享数据,就必须进行必要的设置。亦即把这些需要共享的数据分离出来,放置在一个独立的数据段里,并把该段的属性设置为共享。(3)函数MouseProcMouseProc 是鼠标钩子处理函数,当SetWindowsHookEx函数第一个参为:WH_MOUSE时,调用本函数,首先要在系统中安装一个鼠标消息钩子。 函数原型:LRESULT CALLBACK MouseProc( int n

11、Code, 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,则必须 返回CallNext

12、HookEx(),也就是CallNextHookEx()的返回值如果参数ncode大于等于0,并且钩子处理函数没有处理消息,CallNextHookEx()的返回值,否则当您安装WH_MOUSE钩子的应用程序将不会得到通知,并且得到一个错误的结果,如果钩子处理的消息,您可以返回一个非0值,防止系统把消息发送到目标窗口程序。(4)函数KeyboardProcKeyboardProc是键盘钩子处理函数 函数原型: LRESULT CALLBACK KeyboardProc( int code,WPARAM wParam, LPARAM lParam );参数:Code:根据这个数值决定怎样处理消息

13、如果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按下,

14、其他情况为0 ;30位:如果是按键按下后发送的消息,30位为1,如果是按键抬起后30位为1;31位:指定转变状态:31位为0时候,按键正在被按下,为1时候,按键正在被释放。返回值:如果参数code小于0,则必须返回CallNextHookEx(),也就是返回CalNextHookEx()的返回值 如果参数code大于等于0,并且钩子处理函数没有处理消息,返回CallNextHookEx()的返回值,否则当您安装WH_KEYBOARD钩子时,钩子将不会得到通知,并返回错误结果。如果钩子处理的消息,可以返回一个非0值,防止系统把消息传递给钩子链中的下一个钩子,或者把消息发送到目标窗口。(5)函数C

15、allNextHookEx功能是调用下一个钩子,原型为:CallNextHookEx(hhk HHOOK,nCode Integer,wParam WPARAM,lParam LPARAM);参数:HHOOK:当前钩子的句柄nCode:钩子代码; 就是给下一个钩子要交待的WPARAM:要传递的参数; 由钩子类型决定是什么参数LPARAM:要传递的参数; 由钩子类型决定是什么参数返回值:返回下一个钩子执行后的返回值:0表示失败 。其中,参数 nCode的可选值:HC_ACTION = 0; HC_GETNEXT = 1;HC_SKIP = 2;HC_SKIP = 2;HC_NOREMOVE =

16、3;HC_NOREM = HC_NOREMOVE;HC_SYSMODALON = 4;HC_SYSMODALOFF = 5;(6)函数XYZWindowFromPoint(实现流程图见图1,代码见附录3)是返回返回光标(point)所在点的子窗口句柄,原型为:XYZWindowFromPoint(HWND hwndParent,POINT point,UINT uFlags );其中:第一个参数hwndParent为处理父窗口;第二个参数point为光标的坐标;第三个参数uFlags为窗口的选择。这里默认为CWP_SKIPINVISIBLE(忽略不可见的子窗口);(7)函数SendMessag

17、e该函数将指定的消息发送到一个或多个窗口。此函数为指定的窗口调用窗口程序,直到口窗程序处理完消息再返回。原型为SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam);参数:hWnd:其窗口程序将接收消息的窗口的句柄。如果此参数HWND_BROADCAST,则消息将被发送到系统中所有顶层窗口,包括无效或不可见的非自身拥有的窗口、被覆盖的窗口和弹出式窗口,但消息不被发送到子窗口。Msg:指定被发送的消息。wParam:指定附加的消息指定信息。IParam:指定附加的消息指定信息。返回值:返回值指定消息处理的结果,依赖于所发送的消息。图

18、1 XYZWindowFromPoint的实现过程4具体实现步骤其具体实现过程见图2(1)建立钩子KSHook.DLL选择MFC AppWizard(DLL)创建项目KSHook;选择MFC Extension DLL(共享MFC拷贝)类型;由于VC5没有现成的钩子类,所以要在项目目录中创建KSHook.h文件,在其中建立钩子图2主程序流程图类:class AFX_EXT_CLASS CKSHook : public CObject public:CKSHook();/钩子类的构造函数virtual CKSHook();/钩子类的析构函数public:BOOL StartHook(HWND h

19、Wnd); /安装钩子函数BOOL StopHook();/卸载钩子函数 ;在KSHook.cpp文件的顶部加入#include KSHook.h语句;在KSHook.cpp文件的顶部加入全局共享数据变量:#pragma data_seg(mydata) HWND glhPrevTarWnd=NULL; /上次鼠标所指的窗口句柄 HWND glhDisplayWnd=NULL; /显示目标窗口标题编辑框的句柄 HHOOK glhmouse=NULL; /安装的鼠标勾子句柄HHOOK glhkey=NULL; /安装的键盘勾子句柄 HINSTANCE glhInstance=NULL; /DLL

20、实例句柄 #pragma data_seg()在DEF文件中定义段属性:SECTIONS mydata READ WRITE SHARED 在主文件KSHook.cpp的DllMain函数中加入保存DLL实例句柄的语句:glhInstance=hInstance; 钩子函数的实现:(详细代码见附录1)类KSHook的成员函数的具体实现:(详细代码见附录2)编译项目生成KSHook.dll。(2)创建钩子可执行程序用MFC的AppWizard(EXE)创建项目Hook;选择“基于对话应用”并按下“完成”键;编辑对话框,删除其中原有的两个按钮,加入静态文本框和编辑框,用鼠标右键点击静态文本框,在弹

21、出的菜单中选择“属性”,设置其标题为“鼠标所在的窗口标题”;在HookDlg.h中加入对KSHook.h的包含语句#include KSHook.h;在CHookDlg.h的CHookDlg类定义中添加私有数据成员:CKSHook m_hook; /加入钩子类作为数据成员BOOL bHooked; 修改CHookDlg:OnInitDialog()函数: CWnd * pwnd=GetDlgItem(IDC_EDIT1); /取得编辑框的类指针 m_hook.StartHook(pwnd-GetSafeHwnd();/取得编辑框的窗口句柄并安装钩子 链接DLL库,即把.KSHookdebug

22、KSHook ook.lib加入到项目设置链接标签中;编译项目生成可执行文件;把KSHook ook.DLL拷贝到.Hook debug目录中;先运行几个可执行程序,然后运行Hook.exe程序,把鼠标在不同窗口中移动,在Hook程序窗口中的编辑框内将显示出鼠标所在的应用程序主窗口的标题(见附录4)。按下键盘上的一些键,可以发现EXE目录下自动生成了一个key.txt文件,该文件记载了你的按键信息(见附录5)。5课程设计总结及其感想 这个课程设计是设计一个钩子程序,实现两个内容,第一是通过调用鼠标钩子来适时获取鼠标所在的窗口标题;第二是通过调用键盘钩子来获取键盘输入的信息。这个程序是用C+语言

23、在Visual C+ 6.0编程软件上编程实现的。整个程序包括两个模块,一个是KSHook.dll模块,它是把钩子函数集成在动态链接库中,利用动态链接库可以实现全局的钩子程序,它是程序的核心部分,里面包含钩子的创建、具体实现、撤消方面的内容,在创建时用到函数SetWindowsHookEx,在具体实现时用到函数MouseProc、函数KeyboardProc、函数CallNextHookEx,在撤消时用到函数UnhookWindowsHookEx来卸载钩子;另一个模块是Hook.exe模块,它是程序的入口,也是实现对话界面的,在运行过程中要调用KSHook.dll模块,来实现程序的功能。在本次

24、课程设计中,自己付出了很多的时间,不仅在课程安排时间里认真的做,而且在课余时间也开了很多的时间。从不知道钩子什么开始,到现在能自己编写了一个简单的鼠标键盘钩子程序,我的收获是很大的。这次用到的是Visual C+编程软件,在此以前,都没有用过这个软件,在学习C+时用的也不是这个软件,因此在开始做设计的前几天也花了一些时间去学习这个软件的应用,现在自己已经初步掌握了这个软件的应用了,但是要想熟练的应用还需进一步的学习。从这次课程设计中,我深刻的体会到重在坚持的意义,很多的东西一开始我们并不会的,但是只要坚持的看进去,一遍一遍的不厌其烦看,会发觉慢慢的就懂了,因此,无论做什么事都要有决心和恒心。6

25、参考文献1 王育坚.Visual C+面向对象编程教程(第2版)M.北京:清华大学出版社,2007.10.2 王西武,阎梅 ,赵怀勋. 在VC6下应用Windows系统钩子技术J. 现代电子技术. 2004:27(17):45-46.3 徐士良.常用算法程序集:C+语言描述(第4版)M.北京:清华大学出版社,2009.7.4 钱能.C+程序设计教程:设计思想与实现(修订版)M.北京:清华大学出版社,2009.7.5 游洪跃, 伍良富, 王景熙.C+面向对象程序设计实验和课程设计教程M.北京:清华大学出版社,2009.2.6 倪步喜.Windows的钩子技术及实现J.计算机与现代化.2007,2

26、8(1):28-30.附录1:(钩子函数的具体实现)/鼠标钩子函数LRESULT WINAPI MouseProc(int nCode,WPARAM wparam,LPARAM lparam) LPMOUSEHOOKSTRUCT pMouseHook=(MOUSEHOOKSTRUCT FAR *)lparam; if (nCode=0) HWND glhTargetWnd=XYZWindowFromPoint(NULL,pMouseHook-pt); if(glhTargetWnd!=glhPrevTarWnd) char szCaption100; GetWindowText(glhTarg

27、etWnd,szCaption,100) /取目标窗口标题 if(IsWindow(glhDisplayWnd)SendMessage(glhDisplayWnd,WM_SETTEXT,0,(LPARAM)(LPCTSTR)szCaption); glhPrevTarWnd=glhTargetWnd; /保存目标窗口 return CallNextHookEx(glhmouse,nCode,wparam,lparam); /继续传递消息 /键盘钩子函数LRESULT CALLBACK KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam) cha

28、r ch=0; FILE *fl; if( (DWORD)lParam&0x40000000) & (HC_ACTION=nCode) ) /有键按下 fl=fopen(key.txt,a); /输出到key.txt文件 if (wParam=0x100) ch= ; else BYTE ks256; GetKeyboardState(ks); WORD w; UINT scan=0; ToAscii(wParam,scan,ks,&w,0); /ch=MapVirtualKey(wParam,2); /把虚键代码变为字符 ch =char(w); fwrite(&ch, sizeof(cha

29、r), 1, fl); fclose(fl); return CallNextHookEx( glhkey, nCode, wParam, lParam ); 附录2:(类KSHook的成员函数的具体实现)CKSHook:CKSHook()CKSHook:CKSHook()if(glhmouse&glhkey)UnhookWindowsHookEx(glhmouse);UnhookWindowsHookEx(glhkey);/安装钩子并设定接收显示窗口句柄BOOL CKSHook:StartHook(HWND hWnd) BOOL bResult=FALSE; glhmouse=SetWind

30、owsHookEx(WH_MOUSE,MouseProc,glhInstance,0); glhkey=SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,glhInstance,0); if(glhmouse!=NULL&glhkey!=NULL) bResult=TRUE; glhDisplayWnd=hWnd; /设置显示目标窗口标题编辑框的句柄 return bResult; /卸载钩子BOOL CKSHook:StopHook() BOOL aResult=FALSE; BOOL bResult=FALSE; if(glhmouse&glhkey) a

31、Result= UnhookWindowsHookEx(glhmouse);bResult= UnhookWindowsHookEx(glhkey); if(bResult&aResult) glhPrevTarWnd=NULL; glhDisplayWnd=NULL; /清变量 glhmouse=NULL; glhkey=NULL; return bResult; 附录3:(获取窗口句柄)HWND XYZWindowFromPoint(HWND hwndParent,POINT point,UINT uFlags) if(hwndParent != NULL) return :ChildWi

32、ndowFromPointEx(hwndParent, point, uFlags); /返回光标(point)所在点的子窗口句柄 RECT rect, rectSearch; HWND pWnd, hWnd, hSearchWnd;hWnd = :WindowFromPoint(point);/得到光标(point)所在点的窗口句柄 if(hWnd != NULL) :GetWindowRect(hWnd, &rect); /得到整个窗口在屏幕上的矩形框位置 pWnd = :GetParent(hWnd); /得到父窗口句柄 if(pWnd != NULL) hSearchWnd = hWn

33、d; do hSearchWnd=:GetWindow(hSearchWnd, GW_HWNDNEXT); /如果再也找不到这样的窗口,该函数就会返回NULL :GetWindowRect(hSearchWnd, &rectSearch); if(:PtInRect(&rectSearch, point) & :GetParent(hSearchWnd) = pWnd &:IsWindowVisible(hSearchWnd) /比较看谁的面积最小 if(rectSearch.right-rectSearch.left) * (rectSearch.bottom - rectSearch.top) (rect.right - rect.left) * (rect.bottom - rect.top) hWnd = hSearchWnd; :GetWindowRect(hWnd, &rect); while(hSearchWnd != NULL); return hWnd; 附录4:(鼠标钩子截获的应用程序主窗口的标题)附录5:(键盘钩子截获的按键信息)在Hook中从键盘输入以下内容: EXE目录下自动生成了一个key.txt文件,记录按键信息:

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 研究报告 > 商业贸易


经营许可证编号:宁ICP备18001539号-1