我试图挂钩一个进程的键盘,但是当我按任意键时,钩子的代码没有执行并且进程冻结。 我的代码基于以下帖子:How to hook external process with SetWindowsHookEx and WH_KEYBOARD
这是我的dll代码:
#include <windows.h>
#include <iostream>
#include <stdio.h>
HINSTANCE hinst = NULL;
#pragma data_seg(".shared")
HHOOK hhk = NULL;
#pragma data_seg()
#pragma comment(linker, "/SECTION:.shared,RWS")
LRESULT CALLBACK wireKeyboardProc(int code, WPARAM wParam, LPARAM lParam) {
return CallNextHookEx(hhk, code, wParam, lParam);
}
extern "C" __declspec(dllexport) void install(unsigned long threadID) {
hhk = SetWindowsHookEx(WH_KEYBOARD, wireKeyboardProc, hinst, threadID);
}
BOOL WINAPI DllMain(__in HINSTANCE hinstDLL, __in DWORD fdwReason, __in LPVOID lpvReserved) {
hinst = hinstDLL;
return TRUE;
}
编辑: 加载dll之后我执行函数install(),它会创建钩子,但由于某种原因,当按下键并且进程冻结时,函数wireKeyboardProc不会被执行。知道为什么会这样吗?
编辑2: 这也是我的exe代码:
unsigned long threadID = GetWindowThreadProcessId(hWnd, &ProcessId);
HINSTANCE hinst;
hinst = LoadLibrary(_T("hookKbd32.dll"));
if (hinst) {
typedef void(*Install)(unsigned long);
Install install = (Install)GetProcAddress(hinst, "install");
install(threadID);
}
答案 0 :(得分:0)
我在尝试向Nox播放器(Android仿真器)添加钩子时遇到了相同的问题。我已经在另一个模拟器上尝试了相同的代码,并且效果很好。
在此之后,我确定nox包括一个反钩子系统……可能与您的程序相同。在SetWindowsHookExA之后,Nox看起来冻结或退出,而根本没有捕获事件。
已编辑。我知道为什么要经过几个小时的检查。...64位应用程序需要64位dll,而32位应用程序需要32位dll。
来自:https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowshookexa
SetWindowsHookEx可用于将DLL注入另一个进程。一种 无法将32位DLL注入64位进程和64位DLL 无法注入到32位进程中。如果应用程序要求 在其他进程中使用钩子,则需要32位 应用程序调用SetWindowsHookEx将32位DLL注入32位 进程,以及调用SetWindowsHookEx的64位应用程序 将64位DLL转换为64位进程。 32位和64位DLL必须具有 不同的名字。
由于挂钩在应用程序的上下文中运行,因此它们必须匹配 应用程序的“位”。如果安装了32位应用程序 全局钩子在64位Windows上,将32位钩子注入到每个 32位进程(通常的安全边界适用)。在64位 进程中,线程仍标记为“已挂钩”。但是,因为 32位应用程序必须运行挂钩代码,系统才能执行 在挂钩应用程序的上下文中进行挂钩;具体来说,在线程上 称为SetWindowsHookEx。这意味着挂钩应用程序必须 继续发送消息,否则可能会阻止其正常运行 64位进程。如果64位应用程序安装了全局钩子 在64位Windows上,将64位挂钩插入到每个64位 进程,而所有32位进程都使用该挂钩的回调 应用。
在64位Windows的桌面上挂接所有应用程序 安装,请安装32位全局挂钩和64位全局挂钩, 每个都来自适当的流程,并确保不断发送消息 在挂钩应用程序中避免阻塞正常功能。如果 您已经有一个32位的全局挂钩应用程序,但是它没有 需要在每个应用程序的上下文中运行,您可能不需要创建 64位版本。
https://docs.microsoft.com/en-us/windows/win32/winprog64/process-interoperability
您可以使用以下命令在64位Windows上运行基于Win32的应用程序: 仿真层。 ARM上的Windows 10包含x86-on-ARM64仿真 层。有关更多信息,请参见运行32位应用程序。
在64位Windows上,64位进程无法加载32位动态链接 库(DLL)。此外,一个32位进程不能加载64位 DLL。但是,64位Windows支持远程过程调用(RPC) 在64位和32位进程之间(在同一台计算机上 跨计算机)。在64位Windows上,进程外的32位COM 服务器可以与64位客户端通信,并且进程外 64位COM服务器可以与32位客户端进行通信。因此,如果 您有一个不支持COM的32位DLL,可以将其包装在 进程外COM服务器,并使用COM封送往返于 64位进程。