钩子学习心得

闲来无事,自己花了一天时间学习了下钩子在DELPHI中的使用,这只是一个局部变量的钩子,
1 首先定义钩子的基本变量
type
THookDataOutputProc = procedure(PBuffer: PChar);stdcall;

THookData = record
Installed: Boolean;
Hhk: HHook;
CallBackProc: THookDataOutputProc;
Code: Integer;
Wparam: WPARAM;
Lparam: LPARAM;
end;

2 使用钩子前,必须安装钩子到系统中的钩链去,使用

procedure InstallHooks(HookDataOutputProc: THookDataOutputProc); stdcall;
begin
try
HooksData[WH_MOUSE].hhk := SetWindowsHookEx(WH_MOUSE, @MouseProc, 0, GetCurrentThreadId()); //将MouseProc函数挂到钩链中去处理消息
HooksData[WH_MOUSE].CallbackProc := HookDataOutputProc; //指定回调函数此函数是调用EXE的函数做为参数传递进来
HooksData[WH_MOUSE].Installed := True;
except
on E: Exception do
begin
UninstallHooks();
MessageDlg('Error in ''HookDll.dll''', mtError, [mbOk], 0);
end;
end;
end;

//此函数是钩子中最重要的函数
function MouseProc(Code: Integer; Wparam: WPARAM; Lparam: LPARAM): LRESULT;stdcall;
const
pFmt = '鼠标钩子回调:事件: %s ; 信息:%s; 鼠标位置: (%d %d)';
var
pMsg: PChar;
pCode: PChar;
PBuffer: array[0..127] of Char;
MouseInfo: TMouseHookStruct;
begin
try
if Code < 0 then
begin
//如果CODE小于0。也要将它与下一个钩链起来
Result := CallNextHookEx(HooksData[WH_MOUSE].Hhk, Code, Wparam, Lparam);
Exit;
end;
//判断是否有回调函数
if Assigned(HookSData[WH_Mouse].CallbackProc) then
begin
//Code参数表示钩码,其值取决于钩过程的类型
case Code of
HC_ACTION: pCode := 'Hc_ACtion';
HC_NOREMOVE: pCode := 'Hc_NoreMove'
else
pCode := 'UnKnown';
end;
WMToPChar(Wparam, PMsg); //其实是一个转换过程,Wparam其实就是WM消息,将其转成字符
MouseInfo := TMouseHookStruct(Pointer(Lparam)^);//获得消息的附加值
StrLFmt(pBuffer, 128, pFmt, [pCode, pMsg, MouseInfo.pt.X, MouseInfo.pt.Y]);//格式化字符,不用我说了吧
HooksData[Wh_Mouse].CallBackProc(PBuffer);
//调用回调函数,其实就EXE传进来的那个
end;
Result := CallNextHookEx(HooksData[WH_MOUSE].Hhk, Code, Wparam, Lparam);
except
on E: Exception do
begin
Result := CallNextHookEx(HooksData[WH_MOUSE].hhk, code, wparam, lparam);
MessageDlg('Error in ''HookDll.dll''', mtError, [mbOk], 0);
end;
end;
end;

//这段不用解释,白痴都能看懂
procedure UninstallHooks(); stdcall;
var
I: Integer;
begin
try
for I := WH_MIN to WH_MAX do
begin
if HooksData[I].Installed then
begin
UnhookWindowsHookEx(HooksData[I].hhk);
HooksData[I].Installed := False;
end;
end;
except
on E: Exception do
MessageDlg('Error in ''HookDll.dll''', mtError, [mbOk], 0);
end;
end;

{ Entry point of 'HookDll.dll' }
procedure HookDllEntryPoint(dwReason: DWORD); stdcall;
var
I: Integer;
begin
case dwReason of
DLL_PROCESS_ATTACH:
begin
for I := WH_MIN to WH_MAX do
HooksData[I].Installed := False;
end;
DLL_PROCESS_DETACH:
begin
UninstallHooks();
end;
DLL_THREAD_ATTACH: ;
DLL_THREAD_DETACH: ;
end;
end;

其中有一句解释: { Called whenever DLL entry point is called } 我的理解是: 每当调用 DLL 文件时将会调用 DLLProc 指向的方法, 应该是用作 DLL 中某些值的初始化, 有点类似与类的 ...

然后就是
exports
InstallHooks, UninstallHooks, MouseProc;

begin
DllProc := @HookDllEntryPoint;
//DLLPROC我查帮助一直没查到,({ Called whenever DLL entry point is called }DELPHI帮助里是这么写的)
我的理解是:每当调用 DLL 文件时将会调用 DLLProc 指向的方法
DllProc(DLL_PROCESS_ATTACH);
end.

到这里钩子DLL代码就完了,下边是EXE代码,都不用解释了
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
THookDataOutputProc = procedure (pBuffer: PChar); stdcall;
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
procedure UninstallHooks(); stdcall;external 'HookDll.dll' name 'UninstallHooks';
procedure InstallHooks(HookDataOutputProc: THookDataOutputProc); stdcall; external 'HookDll.dll' name 'InstallHooks';

procedure AddString(Sender: PChar);stdcall;

implementation

{$R *.dfm}
procedure AddString(Sender: PChar); stdcall;
begin
Form1.Memo1.Lines.Add(Sender);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
InstallHooks(AddString);
end;

end.

 

2

function WindowsHook(Code: Integer; wParam: Integer; lParam: Integer): LRESULT; stdcall;
var
  pStruct: PCWPStruct;
begin
  pStruct := PCWPStruct(lParam);
  if (Code = HC_ACTION) and (pStruct^.message = WM_SETTINGCHANGE) then Exit;
  Result := CallNextHookEx(WH_CALLWNDPROC, Code, wParam, lParam);
end;

SetWindowsHookEx(WH_CALLWNDPROC, WindowsHook, hInstance, GetCurrentThreadId);

3 全局钩

 

unit Unit4;

interface

uses
  Windows, Messages, SysUtils, Unit3;

function HookProc(iCode: integer; wParam: wParam; lParam: lParam): LResult; stdcall;
function Keyhookresult(lP: integer; wP: integer): pchar;

implementation

function Keyhookresult(lP: integer; wP: integer): pchar;
begin
  result := '[Print   Screen]';
  case lp of
    14354: result := '[Alt]';                //不能识别
    10688: result := '`';
    561: Result := '1';
    818: result := '2';
    1075: result := '3';
    1332: result := '4';
    1589: result := '5';
    1846: result := '6';
    2103: result := '7';
    2360: result := '8';
    2617: result := '9';
    2864: result := '0';
    3261: result := '-';
    3515: result := '=';
    4177: result := 'Q';
    4439: result := 'W';
    4677: result := 'E';
    4946: result := 'R';
    5204: result := 'T';
    5465: result := 'Y';
    5717: result := 'U';
    5961: result := 'I';
    6223: result := 'O';
    6480: result := 'P';
    6875: result := '[';
    7133: result := ']';
    11228: result := '\';
    7745: result := 'A';
    8019: result := 'S';
    8260: result := 'D';
    8518: result := 'F';
    8775: result := 'G';
    9032: result := 'H';
    9290: result := 'J';
    9547: result := 'K';
    9804: result := 'L';
    10170: result := ';';
    10462: result := '''';
    11354: result := 'Z';
    11608: result := 'X';
    11843: result := 'C';
    12118: result := 'V';
    12354: result := 'B';
    12622: result := 'N';
    12877: result := 'M';
    13244: result := ',';
    13502: result := '.';
    13759: result := '/';
    13840: result := '[Right-Shift]';
    14624: result := '[Space]';
    283: result := '[Esc]';
    15216: result := '[F1]';
    15473: result := '[F2]';
    15730: result := '[F3]';
    15987: result := '[F4]';
    16244: result := '[F5]';
    16501: result := '[F6]';
    16758: result := '[F7]';
    17015: result := '[F8]';
    17272: result := '[F9]';
    17529: result := '[F10]';
    22394: result := '[F11]';
    22651: result := '[F12]';
    10768: Result := '[Left-Shift]';
    14868: result := '[CapsLock]';
    3592: result := '[Backspace]';
    3849: result := '[Tab]';
    7441:
      if wp > 30000 then
        result := '[Right-Ctrl]'
      else
        result := '[Left-Ctrl]';
    13679: result := '[Num   /]';
    17808: result := '[NumLock]';
    300: result := '[Print   Screen]';
    18065: result := '[Scroll   Lock]';
    17683: result := '[Pause]';
    21088: result := '[Num0]';
    21358: result := '[Num.]';
    20321: result := '[Num1]';
    20578: result := '[Num2]';
    20835: result := '[Num3]';
    19300: result := '[Num4]';
    19557: result := '[Num5]';
    19814: result := '[Num6]';
    18279: result := '[Num7]';
    18536: result := '[Num8]';
    18793: result := '[Num9]';
    19468: result := '[*5*]';
    14186: result := '[Num   *]';
    19053: result := '[Num   -]';
    20075: result := '[Num   +]';
    21037: result := '[Insert]';
    21294: result := '[Delete]';
    18212: result := '[Home]';
    20259: result := '[End]';
    18721: result := '[PageUp]';
    20770: result := '[PageDown]';
    18470: result := '[UP]';
    20520: result := '[DOWN]';
    19237: result := '[LEFT]';
    19751: result := '[RIGHT]';
    7181: result := '[Enter]';
  end;
end;

//钩子回调过程

function HookProc(iCode: integer; wParam: wParam; lParam: lParam): LResult;
  stdcall;
var
  s: string;
begin
  if (PEventMsg(lparam)^.message = WM_KEYDOWN) then
  begin
    //事件消息,键盘按下
    s := format('Down:%5d   %5d     ', [PEventMsg(lparam)^.paramL,
      PEventMsg(lparam)^.paramH]) + Keyhookresult(peventMsg(lparam)^.paramL,
      peventmsg(lparam)^.paramH);
    Form3.Memo1.Lines.Add(S);
  end
  else if (PEventMsg(lparam)^.message = WM_KEYUP) then
  begin
    //键盘按键
    s := format('     Up:%5d   %5d     ', [PEventMsg(lparam)^.paramL,
      PEventMsg(lparam)^.paramH]) + Keyhookresult(PEventMsg(lparam)^.paramL,
      PEventMsg(lparam)^.paramH);
    Form3.Memo1.Lines.Add(S);
  end;

CallNextHookEx(0,nCode,wParam,lParam);
end;

end.

调用

SetWindowsHookEx(WH_JOURNALRECORD,   HookProc,   HInstance,   0);

posted @ 2008-12-15 21:35  谭志宇  阅读(535)  评论(0编辑  收藏  举报