• 钩子学习心得


    闲来无事,自己花了一天时间学习了下钩子在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);

  • 相关阅读:
    linux自动清理30天之前的文件
    Oracle树查询及相关函数
    jackson循环引用导致序列化stackOverFlow的解决
    java核心技术36讲笔记
    Quartz学习
    Quartz学习
    java核心技术36讲
    git常用命令
    CTCall简介(后续会继续补充)
    自定义导航栏,隐藏导航栏底部的灰色线条
  • 原文地址:https://www.cnblogs.com/chengxin1982/p/1355574.html
Copyright © 2020-2023  润新知