请选择 进入手机版 | 继续访问电脑版
查看: 6132|回复: 3514

[C/C++] Visual Studio2013 设置全局钩子遇到的问题

[复制链接]
  • TA的每日心情
    无聊
    2016-12-7 09:31
  • 签到天数: 179 天

    [LV.7]常住居民III

    发表于 2016-6-21 15:34:50 | 显示全部楼层 |阅读模式
    本帖最后由 小圈圈 于 2016-6-21 15:38 编辑

    1.Hook简介:作用是拦截某些消息,关键函数是SetWindowsHookEX()
    2实例:编写一个屏蔽所有进程和所有线程的钩子程序。钩子函数在DLL中,要被某个程序调用才行。
      1.新建一个DLL工程名为0616Hook
      2.增加0616Hook.cpp
      3.代码如下:
    #include <windows.h>包含头文件

    HHOOK g_hMouse=NULL;
    HHOOK g_hKeyboard=NULL;

    #pragma data_seg("MySec")新建了一个节,用于将下 面的这个变量设为全局共享。
    HWND g_hWnd=NULL;这个变量是全局共享的。
    #pragma data_seg()

    //#pragma comment(linker,"/section:MySec,RWS")
    /*HINSTANCE g_hInst;

    BOOL WINAPI DllMain(
       HINSTANCE hinstDLL,  // handle to the DLL module
       DWORD fdwReason,     // reason for calling function
       LPVOID lpvReserved   // reserved
    )
    {
      g_hInst=hinstDLL;
    }*/

    LRESULT CALLBACK MouseProc(
       int nCode,      // hook code
       WPARAM wParam,  // message identifier
       LPARAM lParam   // mouse coordinates
    )
    {
      return 1;拦截了鼠标消息。
    }

    LRESULT CALLBACK KeyboardProc(
       int code,       // hook code
       WPARAM wParam,  // virtual-key code
       LPARAM lParam   // keystroke-message information
    )
    {
      if(VK_F2==wParam)如果是F2键,则退出。
      {
       SendMessage(g_hWnd,WM_CLOSE,0,0);
       UnhookWindowsHookEx(g_hMouse);当退出时将钩子卸掉。
       UnhookWindowsHookEx(g_hKeyboard);
      }
      return 1;
    }

    void SetHook(HWND hwnd)此函数设置了钩子。
    {
      g_hWnd=hwnd;注意这种传递调用它的进程的句柄的方法,比较巧妙!
      g_hMouse=SetWindowsHookEx(WH_MOUSE,MouseProc,GetModuleHandle("Hook"),0);
      g_hKeyboard=SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,GetModuleHandle("Hook"),0);
    }

    0616Hook.DEF的代码如下:
    LIBRARY Hook
    EXPORTS
    SetHook  @2
    SEGMENTS
    MySec READ WRITE SHARED  也可以设置节的属性。
        4.新建一个工程调用此钩子函数。工程名为0619HookTest,基于对话框的。在OnInitDialog()中调用SetHook(),要事先声明_declspec(dllimport) void SetHook(HWND hwnd);
          然后在右键工程->属性->链接器->输入 加入0616Hook.lib,并将0616Hook.dll和0616Hook.lib拷贝到当前目录。
    int cxScreen,cyScreen;
    cxScreen=GetSystemMetrics(SM_CXSCREEN);
    cyScreen=GetSystemMetrics(SM_CYSCREEN);
    SetWindowPos(&wndTopMost,0,0,cxScreen,cyScreen,SWP_SHOWWINDOW);将窗口保持在最前面。
    SetHook(m_hWnd);
    但是最终运行的时候出现一个问题:窗口能正常打开关闭,但是写入的钩子函数没起作用,想要调试定位,但是……

    由于dll是自己写的,调试的时候要加载编译dll生成的pdb文件,但问题是不知道怎么把这个pdb加载进来(下面的浏览并查找0616Hook.pdb试过了,没用的)
    这时改造函数,让SetHook函数有返回值,根据返回值MessageBox弹出不同窗口。
    bool SetHook(HWND hwnd)
    {
        g_hwnd = hwnd;
        g_hMouse = ::SetWindowsHookEx(WH_MOUSE, MouseProc, GetModuleHandle("0616Hook.dll"), 0);
        g_hKeyboard = ::SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, GetModuleHandle("0616Hook.dll"), 0);
        if (g_hMouse)
            return true;
        else
            return false;
    }
    窗口测试程序修改为
    if (!SetHook(m_hWnd))
        {
            MessageBox("创建钩子失败!");
        }
    最终定位到
    ::SetWindowsHookEx(WH_MOUSE, MouseProc, GetModuleHandle("0616Hook.dll"), 0);
    ::SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, GetModuleHandle("0616Hook.dll"), 0);
    这两个函数返回的是空指针
    那么问题来了,0616Hook.dll和0616Hook.lib已经放在测试程序的根目录下了,.lib文件也链接了,但SetWindowsHookEx函数就是不生效。问了一下冰琥珀,说把GetModuleHandle("0616Hook.dll")单拎出来看返回值,没想到奇迹出现了


    全局钩子竟然生效了,虽然还有些许问题,想必这是第一次看到360报警还这么激动吧!
    这次学会了两个东西:1、debug的时候思路要灵活,没有de不掉的bug 2、有些bug就是这么稀里糊涂的被de掉的,谁也说不清楚为什么。。

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?注册

    x
    回复

    使用道具 举报

    该用户从未签到

    发表于 2016-6-21 16:30:25 | 显示全部楼层
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2016-6-21 18:52:05 | 显示全部楼层
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2016-6-21 20:36:53 | 显示全部楼层
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2016-6-21 23:56:41 | 显示全部楼层
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2016-6-22 00:51:55 | 显示全部楼层
    支持,看起来还是可以的
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2016-6-22 01:40:39 | 显示全部楼层
    谢谢楼主的分享
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2016-6-22 03:32:01 | 显示全部楼层
    谢谢楼主的分享
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2016-6-22 03:45:47 | 显示全部楼层
    谢谢楼主的分享
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2016-6-22 05:45:04 | 显示全部楼层
    非常感谢
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    快速回复 返回顶部 返回列表