• 《VC++深入详解》学习笔记 第二十章 HOOK和数据库访问


    匆匆百年,碌碌匆匆

    钩子过程

      系统传递消息的路径上安装一个钩子,勾取特定消息

    安装钩子  

    HHOOK SetWindowsHookEx(
    int idHook, // 要安装的钩子的类型
    HOOKPROC lpfn, //  钩子函数的地址
    HINSTANCE hMod, //  包含钩子函数模块的句柄
    DWORD dwThreadId //  要安装钩子的线程的PID
    );

      钩子链中,最前的钩子最先响应,最后安装的钩子在钩子链的最前面

    进程钩子

    安装键鼠钩子

      1、定义键盘鼠标钩子过程  

    LRESULT CALLBACK KeyboardProc(
    int nCode,           //消息处理方式
    WPARAM wParam,       //传递虚拟键值
    LPARAM lParam        //传递组合键
    )
    {
      if(VK_SPACE == wParam)  //传递键值为空格键
        return 1;        //钩子捕获,不处理,返回非0值,系统将不会再将消息传递给目标窗口过程
      else
        return CallNextHookEx(g_hKeyboard, nCode, wParam, lParam);  //非目标消息,将消息传递给下一个钩子,接下来没有钩子将消息传递给程序窗口

      if(VK_F4 == wParam && (1==(lParam>>29 &1)))  //Alt+F4组合键 lParam参数的第29位Alt按下为1。
        return 1;
      if(VK_F2 == wParam)
        ::SendMessage(g_hWnd,WM_CLOSE,0,0);  //钩子过程中向程序发送消息时,窗口句柄,在窗口初始化中将窗口句柄赋值给预先定义的全局句柄变量g_hWnd,之后再发送消息(因为钩子过程是全局函数)

    }

      2、声明存放钩子句柄变量 HHOOK g_hKeyboard= NULL; ...

      注:1、2步在源文件中消息处理程序之前定义,无需再头文件声明

      3、安装钩子

    g_hKeyboard= SetWindowsHookEx(
    WH_KEYBOARD,          //键盘消息类型
    KeyboardProc,          //钩子过程
    NULL,             //当前线程
    GetCurrentThreadId()   //当前线程ID
    );
    ...

      4、移除钩子

        BOOL UnhookWindowsHookEx(HHOOK hhk);  参数为目标钩子句柄

    全局钩子

      采用动态链接库的方式实现全局钩子

    编写钩子DLL

      1、定义钩子句柄  HHOOK g_hMouse = NULL;

      2、定义钩子过程  MouseProc(...)

      3、定义安装钩子过程函数  void SetHook(){...}

    g_hMouse= SetWindowsHookEx(
    WH_MOUSE,            //键盘消息类型
    MouseProc,            //钩子过程
    GetModuleHandle("Hook"), //获取安装钩子DLL句柄,获取Hook.dll在地址空间中映射句柄
    0                        //所有进程
    );           

      4、编写.def文件

    创建运行DLL工程

      1、声明DLL输入函数

        _declspec(dllimport) void SetHook();

      2、链接DLL库

        #pragma comment(lib,"Hook.lib");

      3、链接目录,将相关文件移动到工程目录下,或者将链接器添加索引

      4、编译,完成

    实现全进程中均能关闭钩子进程

      DLL库被多个进程调用时是被共享的,但其中数据是独享的,通过写入时复制机制实现,可以通过在共享节中声明对象实现关闭进程

      1、创建新的节  在新节中创建需要共享对象

    #pragma data_seg("MySec")    //创建新节名,名称不超过八个字符
    HWND g_hWnd = NULL;    //节内数据,需要初始化
    #pragma data_seg()    //新节结尾

      2、配置新节属性

        #pragma comment(linker,"/section:MySec,RWS")  linker:指令类型为指定链接选项  /section:MySec,RWS:将MySec这节设置为读(R)写(W)共享(S)

      3、配置模块定义文件

        添加:SECTIONS           //关键字

            MySec read write shared  //节名 属性(大小写不敏感,不能缩写)

      4、说明:在按键钩子中设定,按下F2将钩子线程关闭,其中发送关闭消息时候采用的句柄需要将其共享,即在任意进程中触发的关闭发送句柄均为钩子进程句柄

     

  • 相关阅读:
    检查型异常(Checked Exception)与非检查型异常(Unchecked Exception)
    maven跳过单元测试-maven.test.skip和skipTests的区别
    java JFR
    Docker常用命令
    关键字group by 、 Having的 用法
    css特效
    sql
    初识Hibernate之理解持久化类
    Hibernate 搭建
    基本 SQL 之增删改查
  • 原文地址:https://www.cnblogs.com/sepmaple/p/9529912.html
Copyright © 2020-2023  润新知