鼠标钩子程设计报告.docx
- 文档编号:7067880
- 上传时间:2023-01-16
- 格式:DOCX
- 页数:17
- 大小:109.43KB
鼠标钩子程设计报告.docx
《鼠标钩子程设计报告.docx》由会员分享,可在线阅读,更多相关《鼠标钩子程设计报告.docx(17页珍藏版)》请在冰豆网上搜索。
鼠标钩子程设计报告
课程报告
windows钩子程序实现
班级:
学号:
姓名:
教师评语:
教师签名:
2010年7月
课程设计题目
windows钩子程序实现
目的和背景
目的:
1)更深入的学习C++,并学会在VisualC++6.0上编写应用程序
2)了解windows钩子程序的基本原理,类型和实现过程
3)掌握用C++来设计一个钩子程序
背景:
钩子的本质是一段用以处理系统消息的程序,通过系统调用,把他挂入系统。
钩子的种类很多,每种钩子可以截获并处理相应的消息,每当特定的消息发出,在到达目的窗口之前,钩子程序先行截获该消息、得到对此消息的控制权。
此时钩子函数可以对截获的消息进行加工处理,甚至可以强制结束消息的传递。
鼠标钩子是能截获鼠标的操作,包括单击,双击,鼠标所在的位置等;而键盘钩子是截获从键盘输入的信息。
主要内容
1)熟悉钩子程序在Windows操作系统的作用
2)通过找资料,学习钩子程序的基本原理,包括Windows的消息传递机制,钩子的概念,钩子的类型,钩子的实现过程
3)学习和掌握钩子函数,Win32全局钩子的运行机制,VC6中MFCDLL的分类及特点和在VC6中全局共享数据的实现
4)用C++编写一个windows钩子程序;实现适时获取当前鼠标所在窗口的标题和监视各种键盘消息,如,把把鼠标所在窗口标题显示在一个EDITBOX中,从键盘输入的信息记录在一个文档里
采用的工具方法
WindowsXP操作系统,VisualC++6.0
进度安排
1)18周周(三)—18周周(四):
查找相关的资料,对钩子程序的相关知识进行全面的了解
2)18周周(五)—19周周
(一):
对程序进行分析,并加强有关方面的知识,如,C++编程的能力
3)19周周
(二)—19周周(三):
学习了解Win32全局钩子的运行机制,VC6中MFCDLL的分类及特点和在VC6中全局共享数据的实现
4)19周周(四)—20周周
(一):
编码实现windows钩子程序,并实现相应的功能
5)20周周
(二)—20周周(三):
进行程序测试
参考资料
[1]王育坚.VisualC++面向对象编程教程(第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++,并学会在VisualC++6.0上编写应用程序,了解windows钩子程序的基本原理,类型和实现过程,掌握用C++来设计一个钩子程序。
2设计想思
钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。
每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。
这时钩子函数即可以加工处理该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。
对每种类型的钩子由系统来维护一个钩子链,最近安装的钩子放在链的开始,而最先安装的钩子放在最后,也就是后加入的先获得控制权。
由此,我们建立一个鼠标和键盘钩子,把它挂入系统,鼠标钩子是能截获鼠标所指的窗口的标题,而键盘钩子是截获从键盘输入的字符。
因为要建立的是全局钩子,要Win32的运行机制,并且在VisualC++6.0中用Win32DLL来构造动态链接库。
3函数与数据结构
(1)函数SetWindowsHookEx
要实现Win32的系统钩子,必须调用SDK中的API函数SetWindowsHookEx来安装这个鼠标和键盘钩子,这个函数的原型是
HHOOKSetwindowsHookEx(intidHook,HOOKPROCLpfn,INSTANCEhMod,DWORDdwTreadId)
参数:
idHook:
表示钩子类型,它是和钩子函数类型一一对应的。
比如,WH_KEYBOAR,表示安装的是键盘钩子,WH_MOUSE表示是鼠标钩子等。
Lpfn:
是钩子函数的地址。
HMod:
是钩子函数所在的实例的句柄。
对于线程钩子,该参数为NULL;对于系统钩子,该参数为钩子函数所在的DLL句柄。
dwThreadId:
指定钩子所监视的线程的线程号。
对于全局钩子,该参数为NULL。
SetWindowsHookEx:
返回所安装的钩子句柄。
值得注意的是线程钩子和系统钩子的钩子函数的位置有很大的差别。
线程钩子一般在当前线程或者当前线程派生的线程内,而系统钩子必须放在独立的动态链接库中。
(2)函数WINAPIDllMain
当一个进程或线程载入和卸载DLL时,都要调用该函数,它的原型是
BOOLWINAPIDllMain(HINSTANCEhinstDLL,DWORDfdwReason,LPVOIDlpvReserved);
其中:
第一个参数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)函数MouseProc
MouseProc是鼠标钩子处理函数,当SetWindowsHookEx函数第一个参为:
WH_MOUSE时,调用本函数,首先要在系统中安装一个鼠标消息钩子。
函数原型:
LRESULTCALLBACKMouseProc(intnCode,WPARAMwParam,LPARAMlParam);
参数:
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)函数KeyboardProc
KeyboardProc是键盘钩子处理函数
函数原型:
LRESULTCALLBACKKeyboardProc(intcode,WPARAMwParam,LPARAMlParam);
参数:
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(),也就是返回CalNextHookEx()的返回值
如果参数code大于等于0,并且钩子处理函数没有处理消息,返回CallNextHookEx()的返回值,否则当您安装WH_KEYBOARD钩子时,钩子将不会得到通知,并返回错误结果。
如果钩子处理的消息,可以返回一个非0值,防止系统把消息传递给钩子链中的下一个钩子,或者把消息发送到目标窗口。
(5)函数CallNextHookEx
功能是调用下一个钩子,原型为:
CallNextHookEx(hhkHHOOK,nCodeInteger,wParamWPARAM,lParamLPARAM);
参数:
HHOOK:
当前钩子的句柄
nCode:
钩子代码;就是给下一个钩子要交待的
WPARAM:
要传递的参数;由钩子类型决定是什么参数
LPARAM:
要传递的参数;由钩子类型决定是什么参数
返回值:
返回下一个钩子执行后的返回值:
0表示失败。
其中,参数nCode的可选值:
HC_ACTION=0;
HC_GETNEXT=1;
HC_SKIP=2;
HC_SKIP=2;
HC_NOREMOVE=3;
HC_NOREM=HC_NOREMOVE;
HC_SYSMODALON=4;
HC_SYSMODALOFF=5;
(6)函数XYZWindowFromPoint(实现流程图见图1,代码见附录3)
是返回返回光标(point)所在点的子窗口句柄,原型为:
XYZWindowFromPoint(HWNDhwndParent,POINTpoint,UINTuFlags);
其中:
第一个参数hwndParent为处理父窗口;
第二个参数point为光标的坐标;
第三个参数uFlags为窗口的选择。
这里默认为CWP_SKIPINVISIBLE(忽略不可见的子窗口);
(7)函数SendMessage
该函数将指定的消息发送到一个或多个窗口。
此函数为指定的窗口调用窗口程序,直到口窗程序处理完消息再返回。
原型为
SendMessage(HWNDhWnd,UINTMsg,WPARAMwParam,LPARAMIParam);
参数:
hWnd:
其窗口程序将接收消息的窗口的句柄。
如果此参数HWND_BROADCAST,则消息将被发送到系统中所有顶层窗口,包括无效或不可见的非自身拥有的窗口、被覆盖的窗口和弹出式窗口,但消息不被发送到子窗口。
Msg:
指定被发送的消息。
wParam:
指定附加的消息指定信息。
IParam:
指定附加的消息指定信息。
返回值:
返回值指定消息处理的结果,依赖于所发送的消息。
图1XYZWindowFromPoint的实现过程
4具体实现步骤
其具体实现过程见图2
(1)建立钩子KSHook.DLL
①选择MFCAppWizard(DLL)创建项目KSHook;
②选择MFCExtensionDLL(共享MFC拷贝)类型;
③由于VC5没有现成的钩子类,所以要在项目目录中创建KSHook.h文件,在其中建立钩子
图2主程序流程图
类:
classAFX_EXT_CLASSCKSHook:
publicCObject
{
public:
CKSHook();//钩子类的构造函数
virtual~CKSHook();//钩子类的析构函数
public:
BOOLStartHook(HWNDhWnd);//安装钩子函数
BOOLStopHook();//卸载钩子函数
};
④在KSHook.cpp文件的顶部加入#include"KSHook.h"语句;
⑤在KSHook.cpp文件的顶部加入全局共享数据变量:
#pragmadata_seg("mydata")
HWNDglhPrevTarWnd=NULL;//上次鼠标所指的窗口句柄
HWNDglhDisplayWnd=NULL;//显示目标窗口标题编辑框的句柄
HHOOKglhmouse=NULL;//安装的鼠标勾子句柄
HHOOKglhkey=NULL;//安装的键盘勾子句柄
HINSTANCEglhInstance=NULL;//DLL实例句柄
#pragmadata_seg()
⑥在DEF文件中定义段属性:
SECTIONS
mydataREADWRITESHARED
⑦在主文件KSHook.cpp的DllMain函数中加入保存DLL实例句柄的语句:
glhInstance=hInstance;
⑧钩子函数的实现:
(详细代码见附录1)
⑨类KSHook的成员函数的具体实现:
(详细代码见附录2)
⑩编译项目生成KSHook.dll。
(2)创建钩子可执行程序
①用MFC的AppWizard(EXE)创建项目Hook;
②选择“基于对话应用”并按下“完成”键;
③编辑对话框,删除其中原有的两个按钮,加入静态文本框和编辑框,用鼠标右键点击静态文本框,在弹出的菜单中选择“属性”,设置其标题为“鼠标所在的窗口标题”;
④在HookDlg.h中加入对KSHook.h的包含语句#include"KSHook.h";
⑤在CHookDlg.h的CHookDlg类定义中添加私有数据成员:
CKSHookm_hook;//加入钩子类作为数据成员
BOOLbHooked;
⑥修改CHookDlg:
:
OnInitDialog()函数:
CWnd*pwnd=GetDlgItem(IDC_EDIT1);//取得编辑框的类指针
m_hook.StartHook(pwnd->GetSafeHwnd());//取得编辑框的窗口句柄并安装钩子
⑦链接DLL库,即把..\KSHook\debug\KSHookook.lib加入到项目设置链接标签中;
⑧编译项目生成可执行文件;
⑨把KSHookook.DLL拷贝到..\Hook\debug目录中;
⑩先运行几个可执行程序,然后运行Hook.exe程序,把鼠标在不同窗口中移动,在Hook程序窗口中的编辑框内将显示出鼠标所在的应用程序主窗口的标题(见附录4)。
按下键盘上的一些键,可以发现EXE目录下自动生成了一个key.txt文件,该文件记载了你的按键信息(见附录5)。
5课程设计总结及其感想
这个课程设计是设计一个钩子程序,实现两个内容,第一是通过调用鼠标钩子来适时获取鼠标所在的窗口标题;第二是通过调用键盘钩子来获取键盘输入的信息。
这个程序是用C++语言在VisualC++6.0编程软件上编程实现的。
整个程序包括两个模块,一个是KSHook.dll模块,它是把钩子函数集成在动态链接库中,利用动态链接库可以实现全局的钩子程序,它是程序的核心部分,里面包含钩子的创建、具体实现、撤消方面的内容,在创建时用到函数SetWindowsHookEx,在具体实现时用到函数MouseProc、函数KeyboardProc、函数CallNextHookEx,在撤消时用到函数UnhookWindowsHookEx来卸载钩子;另一个模块是Hook.exe模块,它是程序的入口,也是实现对话界面的,在运行过程中要调用KSHook.dll模块,来实现程序的功能。
在本次课程设计中,自己付出了很多的时间,不仅在课程安排时间里认真的做,而且在课余时间也开了很多的时间。
从不知道钩子什么开始,到现在能自己编写了一个简单的鼠标键盘钩子程序,我的收获是很大的。
这次用到的是VisualC++编程软件,在此以前,都没有用过这个软件,在学习C++时用的也不是这个软件,因此在开始做设计的前几天也花了一些时间去学习这个软件的应用,现在自己已经初步掌握了这个软件的应用了,但是要想熟练的应用还需进一步的学习。
从这次课程设计中,我深刻的体会到重在坚持的意义,很多的东西一开始我们并不会的,但是只要坚持的看进去,一遍一遍的不厌其烦看,会发觉慢慢的就懂了,因此,无论做什么事都要有决心和恒心。
6参考文献
[1]王育坚.VisualC++面向对象编程教程(第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,28
(1):
28-30.
附录1:
(钩子函数的具体实现)
//鼠标钩子函数
LRESULTWINAPIMouseProc(intnCode,WPARAMwparam,LPARAMlparam)
{
LPMOUSEHOOKSTRUCTpMouseHook=(MOUSEHOOKSTRUCTFAR*)lparam;
if(nCode>=0)
{
HWNDglhTargetWnd=XYZWindowFromPoint(NULL,pMouseHook->pt);
if(glhTargetWnd!
=glhPrevTarWnd)
{
charszCaption[100];
GetWindowText(glhTargetWnd,szCaption,100)//取目标窗口标题
if(IsWindow(glhDisplayWnd))
SendMessage(glhDisplayWnd,WM_SETTEXT,0,(LPARAM)(LPCTSTR)szCaption);
glhPrevTarWnd=glhTargetWnd;//保存目标窗口
}
}
returnCallNextHookEx(glhmouse,nCode,wparam,lparam);//继续传递消息
}
//键盘钩子函数
LRESULTCALLBACKKeyboardProc(intnCode,WPARAMwParam,LPARAMlParam)
{
charch=0;
FILE*fl;
if(((DWORD)lParam&0x40000000)&&(HC_ACTION==nCode))//有键按下
{
fl=fopen("key.txt","a+");//输出到key.txt文件
if(wParam<=0x2f||wParam>=0x100)
ch='';
else
{
BYTEks[256];
GetKeyboardState(ks);
WORDw;
UINTscan=0;
ToAscii(wParam,scan,ks,&w,0);
//ch=MapVirtualKey(wParam,2);//把虚键代码变为字符
ch=char(w);
}
fwrite(&ch,sizeof(char),1,fl);
fclose(fl);
}
returnCallNextHookEx(glhkey,nCode,wParam,lParam);
}
附录2:
(类KSHook的成员函数的具体实现)
CKSHook:
:
CKSHook()
{
}
CKSHook:
:
~CKSHook()
{
if(glhmouse&&glhkey)
{
UnhookWindowsHookEx(glhmouse);
UnhookWindowsHookEx(glhkey);
}
}
//安装钩子并设定接收显示窗口句柄
BOOLCKSHook:
:
StartHook(HWNDhWnd)
{
BOOLbResult=FALSE;
glhmouse=SetWindowsHookEx(WH_MOUSE,MouseProc,glhInstance,0);
glhkey=SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,glhInstance,0);
if(glhmouse!
=NULL&&glhkey!
=NULL)
bResult=TRUE;
glhDisplayWnd=hWnd;//设置显示目标窗口标题编辑框的句柄
returnbResult;
}
//卸载钩子
BOOLCKSHook:
:
StopHook()
{
BOOLaResult=FALSE;
BOOLbResult=FALSE;
if(glhmouse&&glhkey)
{
aResult=UnhookWindowsHookEx(glhmouse);
bResult=UnhookWindowsHookEx(glhkey);
if(bResult&&aResul
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 鼠标 钩子 设计 报告