我们Windows系统是建立在消息传递的事件驱动的机制上。用钩子可以截获并处理送给其他应用程序的消息,来完成普通应用程序难以实现的功能。键盘记录者的原理就是使用键盘钩子截获键盘消息。当然,并非键盘记录一定要使用钩子,比如WinEggDrop的无钩子键盘记录者。
一般书上都会说:“全局钩子函数必须包含在DLL中,而线程专用钩子还可以包含在可执行文件中”。即如果钩子过程在应用程序中实现,只对该程序起作用;如果钩子过程在DLL中实现,程序在运行中动态调用它,它能对整个系统进行监控。我们做键盘记录当然希望是针对整个系统的了,所以我们发现很多键盘记录者或者带键盘记录功能的木马服务端里都包含用来支持键盘记录的DLL文件。多了DLL文件既增加了程序的体积,也容易因为丢了DLL文件而丧失了键盘记录的功能。本文要讲的是,并非全局键盘钩子一定要在DLL文件中实现,程序中亦可以实现全局钩子。本文的方法来自著名木马BO2000,下面将会向大家详细解说如何实现既使用键盘钩子而又无DLL键盘记录者。
先说点基础知识。实现一个键盘钩子,必须调用API函数SetWindowsHookEx来安装这个钩子函数,这个函数的原型为:HHOOK SetWindowsHookEx(int idHook,HOOKPROC lpfn,HINSTANCE hMod,DWORD dwThreadId);其中,第一个参数是钩子的类型;第二个参数是钩子函数的地址;第三个参数是包含钩子函数的模块句柄;第四个参数指定监视的线程。我们要实现一个全局钩子,所以第四个参数需设置为空。得到控制权的钩子函数在完成对消息的处理后,调用API函数CallNextHookEx来传递该消息。关于钩子的详细介绍读者可参考其它书籍。
本文使用的编程工具为VC++6.0。具体实现步骤和代码解析如下:
1、生成一个基于对话框的程序SEUKBSpy。打开SEUKBSpyDlg.cpp文件。加入下面的全局变量和键盘钩子函数。
2、下面是本程序的精华所在。添加按钮[开始记录]及其响应函数OnStart()并在该函数中卸载钩子:
这里用GetModuleHandle(NULL)来把自身作为一个保存钩子处理函数的dll,非常巧妙实用,也是这个本程序的精华所在。
3、添加按钮[开始记录]及其响应函数OnStop()并在该函数中卸载钩子:
通过上面几步就可以实现一个无DLL文件的键盘记录者,测试一下就可以得到类似于“SEU_2006_5_3.log”文件名的键盘记录日志文件。再加上隐藏窗口和邮件发送功能是不是就成了一个很实用的键盘记录者?赶快动手打造自己的键盘记录者吧。