c++ - 挂接到特定线程时,SetWindowsHookEx 返回 null

标签 c++ winapi hook setwindowshookex

我编写了以下两个应用程序(dll、exe)来将 dll 挂接到 putty 中以监听键盘事件。

一个应用程序是包含钩子(Hook)方法(meconnect)的Dll应用程序。

#include "stdafx.h"
#include <stdio.h>
#include <windows.h>

INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved) {
    /* open file */
    FILE *file;
    fopen_s(&file, "C:\\temp.txt", "a+");

    switch (Reason) {
    case DLL_PROCESS_ATTACH:
        fprintf(file, "DLL attach function called.\n");
        break;
    case DLL_PROCESS_DETACH:
        fprintf(file, "DLL detach function called.\n");
        break;
    case DLL_THREAD_ATTACH:
        fprintf(file, "DLL thread attach function called.\n");
        break;
    case DLL_THREAD_DETACH:
        fprintf(file, "DLL thread detach function called.\n");
        break;
    }

    /* close file */
    fclose(file);

    return TRUE;
}

extern "C" __declspec(dllexport) LRESULT  __stdcall meconnect(int code, WPARAM wParam, LPARAM lParam) {
    //FILE *file;
    //fopen_s(&file, "C:\\function.txt", "a+");
    //fprintf(file, "Function keyboard_hook called.\n");
    //fclose(file);

    OutputDebugString(L"function keyboard hook called. \n");
    //return 0;
    return(CallNextHookEx(NULL, code, wParam, lParam));
}

此处 meconnect 方法将在 PuTTY 应用程序上触发键盘事件时调用。

下面给出的是将上述 dll 注入(inject) PuTTY 应用程序的代码。

// program.exe.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <Windows.h>
#include <string>
#include  <io.h>

using namespace std;

void Usage()
{
    printf("Usage: InjectDLL pid path-to-dll [-privilege]");
}


int _tmain(int argc, char* argv[])
{



    /*
    * Load library in which we'll be hooking our functions.
    */
    HMODULE dll = LoadLibrary(L"C:\\drivers\\dllinject.dll");
    //HMODULE dll = LoadLibrary((LPCTSTR)buf);
    if (dll == NULL) {
        printf("The DLL could not be found.\n");
        getchar();
        return -1;
    }

    /*
    * Get the address of the function inside the DLL.
    */
    HOOKPROC addr = (HOOKPROC)GetProcAddress(dll, "_meconnect@12");
    if (addr == NULL) {
        printf("The function was not found.\n");
        getchar();
        return -1;
    }

    /*
    * Hook the function.
    */
    DWORD procID=0;
    HWND targetWnd = FindWindowA("PuTTYConfigBox","PuTTY Configuration" );
    //HWND windowHandle = FindWindowA(NULL, "Calculator.exe");
    DWORD threadID = GetWindowThreadProcessId(targetWnd, &procID);

    wchar_t msgBuf[1024] = L"";
    wchar_t msgBuf2[1024] = L"";
    wsprintf(msgBuf, L"the proc Id is %d", threadID);

    OutputDebugString(msgBuf);
    HHOOK handle = SetWindowsHookEx(WH_KEYBOARD, addr, dll, threadID);
    DWORD x = GetLastError();
    wsprintf(msgBuf2, L"the last error is %d", x);
    OutputDebugString(msgBuf2);
    if (handle == NULL) {
        printf("The KEYBOARD could not be hooked.\n");
    }
    else{
        printf("Program successfully hooked.\nPress enter to unhook the function and stop the program.\n");
    }

    /*
    * Unhook the function.
    */

    getchar();
    UnhookWindowsHookEx(handle);

    return 0;
}

当我运行上面的代码时,setWindowsHookEx 总是返回 null,这意味着 SetWindowsHookEx 没有挂接到 PuTTY 应用程序。谁能帮助我理解我在这里做错了什么。

最佳答案

你需要用下一种方式在dll中声明函数:

extern "C" LRESULT  __stdcall meconnect(int code, WPARAM wParam, LPARAM lParam) {
//...
}

#ifdef _X86_
#define EXP_meconnect "_meconnect@12"
#elif defined(_AMD64_)
#define EXP_meconnect "meconnect"
#else
#error "unknown platform"
#endif

__pragma(comment(linker, "/export:meconnect=" EXP_meconnect))

始终以名称“meconnect”导出它。另一种方式 - 使用 def file


或者如果你声明它为

extern "C" __declspec(dllexport) LRESULT  __stdcall meconnect(int code, WPARAM wParam, LPARAM lParam) {
//...
}

在dll中,你需要在exe中下一段代码:

#ifdef _X86_
#define EXP_meconnect "_meconnect@12"
#elif defined(_AMD64_)
#define EXP_meconnect "meconnect"
#else
#error "unknown platform"
#endif

HOOKPROC addr = (HOOKPROC)GetProcAddress(dll, EXP_meconnect );

关于c++ - 挂接到特定线程时,SetWindowsHookEx 返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42478817/

相关文章:

ldap - 如何在 liferay 6.1 中为 LDAPAuth 类创建 Hook

codeigniter - 如何解决 CodeIgniter 中的 post_controller_constructor Hooks 重定向问题

c++ - Boost:触发并忘记异步函数调用?

git - 使用预提交 Hook 停止特定作者的 git 提交

c++ - 是否可以在 Mac 上将 C++ 代码编译为 .exe?

c++ - 如何在 Windows 中更改语言键盘布局 (c++)

winapi - 将逻辑处理器映射到物理处理器

c++ - 如何绘制像阴影按钮一样的 Windows 7 任务栏

c++ - 为什么静态 ofstream 不起作用

c++ - 使用 graphics.h 的 Windows 错误