WH_CALLWNDPROC钩子在xp下可以正常截获消息,但在win7下只能截获自己的消息是怎么回事?

解决方案 »

  1.   

    麻烦各位大神 告知问题出在哪里?win7需要做特殊处理吗 
      

  2.   

    1 Hook其它进程的 需要做成DLL
    2 如果64位系统 可能需要编译成64位
    3 检查钩子是否安装成功
      

  3.   

    WinAPIOverride http://jacquelin.potier.free.fr/winapioverride32/
      

  4.   


    钩子的确是做成的dll,win764位32位都尝试了还是只能获取自己进程的消息,从SetWindowsHookEx返回值看是安装成功了。
    总之就是只能在自己进程中有效果,应该是没注入其他进程空间中。但是在xp下一切正常。
      

  5.   

    附上简单demo伪代码 ,帮忙看看有什么问题钩子dll的头文件HookDll.h
    #ifdef KEYHOOKLIB_EXPORTS 
    #define KEYHOOKLIB_API extern "C" __declspec(dllexport)                 //导出宏 
    #else 
    #define KEYHOOKLIB_API extern "C" __declspec(dllimport)               //导入宏 
    #endif 
    #include <windows.h>
    #include <string>
    #include <vector>
    using namespace std;// 自定义与主程序通信的消息 
    #define HM_MYHOOK WM_USER + 105                   //自定义消息 
    // 声明要导出的函数 
    KEYHOOKLIB_API BOOL SetHook(BOOL bInstall, DWORD dwThreadId = 0, HWND hWndCaller = NULL);
    钩子dll的cpp文件HookDll.cpp:
    #define KEYHOOKLIB_EXPORTS
    #include "HookDll.h"
    #pragma data_seg("MyShared")  
    HWND g_hWndCaller = NULL; // 保存传入dll的exe中主窗口句柄
    HHOOK g_hHook = NULL;   // 保存生成的钩子句柄 
    #pragma data_seg() HINSTANCE g_hCwInst;///////////////////////////////////////////////////////////////////////////////
    int WriteLog1(const char * str)
    {
    FILE * log;
    log = fopen("C:\\log_msghook.txt", "a+");
    if (log == NULL)
    return -1; fprintf(log, "%s\n", str);
    fclose(log);
    return 0;
    }
    ///////////////////////////////////////////////////////////////////////////////
    LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
    char szTemp[MAX_PATH] = {0};
    if (nCode < 0)
    {
    return CallNextHookEx(g_hHook, nCode, wParam, lParam);
    }
    PCWPSTRUCT msg; 
    msg = (PCWPSTRUCT)lParam;
    //tagMSG* msg;
    //msg = (tagMSG*)lParam;
    DWORD idProcess;
    DWORD Idthread = GetWindowThreadProcessId(msg->hwnd, &idProcess);
    sprintf(szTemp, "消息类型是:%d而nCode是:%d而窗口句柄是:%x而线程id是:%d而进程id是:%d", msg->message, nCode, msg->hwnd, Idthread, idProcess);
    WriteLog1(szTemp);
    if (nCode == HC_ACTION && (msg->message == WM_CLOSE) && msg->hwnd != g_hWndCaller)
    {
    sprintf(szTemp, "截获消息的窗口句柄%d而被截获消息的进程id是:%d", (int)g_hWndCaller, idProcess);
    WriteLog1(szTemp);
    ::PostMessageW(g_hWndCaller, HM_MYHOOK, wParam, (LPARAM)msg->hwnd);
    return CallNextHookEx(g_hHook, nCode, wParam, (LPARAM)msg);
    }
    return CallNextHookEx(g_hHook, nCode, wParam, lParam);
    }KEYHOOKLIB_API BOOL SetHook(BOOL bInstall, DWORD dwThreadId, HWND hWndCaller)
    {
    BOOL bOk;
    g_hWndCaller = hWndCaller;
    char szTemp[MAX_PATH] = { 0 };
    sprintf(szTemp, "传进来的窗口句柄%d", (int)hWndCaller);
    WriteLog1(szTemp);
    if (bInstall)
    {
    g_hHook = ::SetWindowsHookEx(WH_CALLWNDPROC, HookProc,
    g_hCwInst, dwThreadId);   //安装钩子 
    bOk = (g_hHook != NULL);
    if (bOk)
    {
    WriteLog1("安装钩子成功");
    }
    }
    else
    {
    bOk = ::UnhookWindowsHookEx(g_hHook);
    g_hHook = NULL;
    }
    return bOk;
    }
    BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
    )
    {
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    g_hCwInst = hModule;
    break;
    case DLL_THREAD_ATTACH:
    break;
    case DLL_THREAD_DETACH:
    break;
    case DLL_PROCESS_DETACH:
    break;
    }
    return TRUE;
    }钩子dll的描述文件Source.def:
    LIBRARY HookDll
    EXPORTS
       SetHook
    SECTIONS
       MyShared   Read Write Shared
    调用程序的源文件MainWnd.cpp:#include "HookDll.h" //钩子dll的头文件
    #include <stdio.h>
    #include <tchar.h>
    #pragma comment(lib,"HookDll.lib")//钩子dll项目生成的引入库文件
    #define MAX_LOADSTRING 100// 全局变量: 
    HINSTANCE hInst; // 当前实例
    TCHAR szTitle[MAX_LOADSTRING] = {_T("hookmsg")}; // 标题栏文本
    TCHAR szWindowClass[MAX_LOADSTRING] = { _T("hookmsg") };; // 主窗口类名// 此代码模块中包含的函数的前向声明: 
    ATOM MyRegisterClass(HINSTANCE hInstance);
    BOOL InitInstance(HINSTANCE, int);
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    HWND g_wnd;
    int WINAPI WinMain(_In_ HINSTANCE hInstance,
    _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPSTR    lpCmdLine,
    _In_ int       nCmdShow)
    {
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine); // TODO:  在此放置代码。
    MSG msg; MyRegisterClass(hInstance); // 执行应用程序初始化: 
    if (!InitInstance(hInstance, nCmdShow))
    {
    return FALSE;
    } // 主消息循环: 
    while (GetMessage(&msg, NULL, 0, 0))
    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }
    ::SetHook(FALSE);//取消安装钩子
    return (int)msg.wParam;
    }//
    //  函数:  MyRegisterClass()
    //
    //  目的:  注册窗口类。
    //
    ATOM MyRegisterClass(HINSTANCE hInstance)
    {
    WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = LoadIcon(hInstance, NULL);
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = szWindowClass;
    wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDC_ARROW)); return RegisterClassEx(&wcex);
    }//
    //   函数:  InitInstance(HINSTANCE, int)
    //
    //   目的:  保存实例句柄并创建主窗口
    //
    //   注释: 
    //
    //        在此函数中,我们在全局变量中保存实例句柄并
    //        创建和显示主程序窗口。
    //
    BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    {
    HWND hWnd; hInst = hInstance; // 将实例句柄存储在全局变量中 hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
    g_wnd = hWnd;
    if (!hWnd)
    {
    return FALSE;
    } ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd); return TRUE;
    }//
    //  函数:  WndProc(HWND, UINT, WPARAM, LPARAM)
    //
    //  目的:    处理主窗口的消息。
    //
    //  WM_COMMAND - 处理应用程序菜单
    //  WM_PAINT - 绘制主窗口
    //  WM_DESTROY - 发送退出消息并返回
    //
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    PAINTSTRUCT ps;
    HDC hdc; switch (message)
    {
    case WM_PAINT:
    hdc = BeginPaint(hWnd, &ps);
    // TODO:  在此添加任意绘图代码...
    EndPaint(hWnd, &ps);
    break;
    case WM_DESTROY:
    PostQuitMessage(0);
    break;
    case WM_CREATE:
    {
      if (!hWnd)
      {
      MessageBoxA(NULL, "121212", "", 0);
      }
      if (!SetHook(TRUE, 0, hWnd))
          MessageBox(NULL, L"安装钩子失败!", L"", 0);
    }
    break;
    case HM_MYHOOK:
    {
      char szTemp[MAX_PATH] = { 0 };
      HWND msg;
      msg = (HWND)lParam;
      DWORD idprocess;
      DWORD Idthread = GetWindowThreadProcessId(msg, &idprocess);
      sprintf(szTemp, "id为%d的进程要关闭窗口,线程id为%d", idprocess, Idthread);
      MessageBoxA(NULL, szTemp, "截获到消息:", 0);
    }
    break;
    default:
    return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
    }
      

  6.   

    SPY++ 试试看 是否有WM_CLOSE消息?
      

  7.   

    WinAPIOverride是开源的。