zoukankan      html  css  js  c++  java
  • 读书 Delphi下深入Windows核心编程 第二天

    技术交流,DH讲解.

    今天进入这书第二章 钩子(HOOK).
    先说说钩子是什么?
    钩子其实就在你环境中加上一层过滤,在特殊情况下就触发钩子回调函数.
    比如说我们安装了全局的键盘钩子,那么当我们按动键盘上面的键的时候,钩子的回调函数就会触发.
    我们也能看到本来是直来直往的,结果现在中间安装了一层过滤,系统的效率肯定会有所下降的.
    要了解,我们只需要知道3个函数:
    1 上钩函数:

    function SetWindowsHookEx(
    	idHook: Integer;//钩子的类型 
    	lpfn: TFNHookProc; //回调函数指针
    	hmod: HINST; //一般为0或者Instance
    	dwThreadId: DWORD//全局钩子就为0,不然就为指定进程id
    		): HHOOK; stdcall;//成功就返回一个值,不成功就为0

    其中钩子类型有:

    {$EXTERNALSYM WH_MIN}
      WH_MIN = -1;
      {$EXTERNALSYM WH_MSGFILTER}
      WH_MSGFILTER = -1;
      {$EXTERNALSYM WH_JOURNALRECORD}
      WH_JOURNALRECORD = 0;
      {$EXTERNALSYM WH_JOURNALPLAYBACK}
      WH_JOURNALPLAYBACK = 1;
      {$EXTERNALSYM WH_KEYBOARD}
      WH_KEYBOARD = 2;
      {$EXTERNALSYM WH_GETMESSAGE}
      WH_GETMESSAGE = 3;
      {$EXTERNALSYM WH_CALLWNDPROC}
      WH_CALLWNDPROC = 4;
      {$EXTERNALSYM WH_CBT}
      WH_CBT = 5;
      {$EXTERNALSYM WH_SYSMSGFILTER}
      WH_SYSMSGFILTER = 6;
      {$EXTERNALSYM WH_MOUSE}
      WH_MOUSE = 7;
      {$EXTERNALSYM WH_HARDWARE}
      WH_HARDWARE = 8;
      {$EXTERNALSYM WH_DEBUG}
      WH_DEBUG = 9;
      {$EXTERNALSYM WH_SHELL}
      WH_SHELL = 10;
      {$EXTERNALSYM WH_FOREGROUNDIDLE}
      WH_FOREGROUNDIDLE = 11;
      {$EXTERNALSYM WH_CALLWNDPROCRET}
      WH_CALLWNDPROCRET = 12;
      {$EXTERNALSYM WH_KEYBOARD_LL}
      WH_KEYBOARD_LL = 13;
      {$EXTERNALSYM WH_MOUSE_LL}
      WH_MOUSE_LL = 14;
      {$EXTERNALSYM WH_MAX}
      WH_MAX = 14;
      {$EXTERNALSYM WH_MINHOOK}
      WH_MINHOOK = WH_MIN;
      {$EXTERNALSYM WH_MAXHOOK}
      WH_MAXHOOK = WH_MAX;

    具体作用基本上就看名字就知道,个别的我也不知道,具体的大家看MSDN吧.这个是个葵花宝典.
    2 卸钩函数:

    function UnhookWindowsHookEx(
    	hhk: HHOOK//上钩函数返回的句柄
    		): BOOL; stdcall;

    3 具体的钩子回调函数:

    TFNHookProc = function (code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT stdcall;

    好的说了这么多,看例子:

    Var
      H: HHOOK;
    
    Function MyKeyBoardHookProc(Code: Integer; Wparam: WPARAM;
      Lparam: LPARAM): LRESULT Stdcall;
    Begin
      If Code = HC_ACTION Then
      Begin
        // wparam是virtal code
        // lparam要分字节
        ShowMessage(Format('点击%D键%D次', [Wparam, Lparam And $0000FFFF]));
      End;
      // 一定要记得调用下一个钩子,因为我们要知道可能这个东西不只是你要处理,别人也要处理,
      // 如果你处理,就不往下传了,我也米有办法...算你BT
      Result := CallNextHookEx(H, Code, Wparam, Lparam);
    End;
    
    Procedure TForm2.Button1Click(Sender: TObject);
    Begin
      H := SetWindowsHookEx(WH_KEYBOARD, MyKeyBoardHookProc, 0, GetCurrentThreadId);
    End;
    
    Procedure TForm2.Button2Click(Sender: TObject);
    Begin
      UnhookWindowsHookEx(H)
    End;


    image
    这个钩子的例子,只对自己进程有效,如果我们想全局都有效,就是对别人的进程也有效,那么我们需要将钩子代码写到Dll里面去.

    接下来就演示全局钩子吧.

    Var
      H: HHOOK;
      ExeHandle: Cardinal; // 这个handle一定能要用内存映射出来,因为全局键盘钩子话,
      // 只要程序一按键,dll就会加载到这个进程里面了,所以就形成多进程情况,这里我就不弄了
    
    Function MyKeyBoardProc(Code: Integer; Wparam: WPARAM;
      Lparam: LPARAM): LRESULT Stdcall;
    Begin
      If Code = HC_ACTION Then
        PostMessage(ExeHandle, WM_HOTKEY, Wparam, Lparam); // 这里偷懒了,直接转发出去
      Result := CallNextHookEx(H, Code, Wparam, Lparam)
    End;
    
    Function HookOn(AHandle: Cardinal): Boolean; Export; // 导出它
    Begin
      ExeHandle := AHandle;
      H := SetWindowsHookEx(WH_KEYBOARD, MyKeyBoardProc, HInstance, 0);
      // 最后一个参数一定是0
      Result := H <> 0; // 判断是否成功
    End;
    
    Function HookOff(): Boolean;export;
    Begin
      Result := UnhookWindowsHookEx(H)
    End;

    其他的api hook以后再讲,这里就大致讲了下钩子如何使用.希望能有点儿帮助.

  • 相关阅读:
    ORA-00119: invalid specification for system parameter LOCAL_LISTENER
    local_listener参数的作用!
    DDL为什么不能rollback?
    LGWR和DBWn的触发条件
    修改spfile位置
    初识oracle重做日志文件
    ORACLE AUDIT 审计
    Oracle SQL_TRACE使用小结
    Web API(六):使用Autofac实现依赖注入
    JavaScript:属性的操作
  • 原文地址:https://www.cnblogs.com/huangjacky/p/1653717.html
Copyright © 2011-2022 走看看