如何从SetWindowShookex回调中调用Fuction-Pointer
How to call fuction-pointer from SetWindowsHookEx callback
我尝试从dll调用一个函数点,该函数在屏幕上显示的所有窗口上挂上WM_LBUTONDOND或WM_TOUCH消息。
我有以下DLL源代码:
typedef void (*PtrFonct)(int nCode, WPARAM wParam, LPARAM lParam);
PtrFonct pf;
HHOOK global;
extern "C" __declspec(dllexport) LRESULT WINAPI procedure(int nCode, WPARAM wParam,LPARAM lParam)
{
if (nCode == HC_ACTION){
MSG* pMSG = (MSG*)lParam;
if (pMSG->message == WM_LBUTTONDOWN){
pf(nCode, wParam, lParam);
}
}
return CallNextHookEx(global, nCode, wParam, lParam);
}
extern "C" __declspec(dllexport) BOOL setCallback(void ((*callbackFunc)(int, WPARAM, LPARAM))){
pf = callbackFunc;
if (pf)
return TRUE;
return FALSE;
}
和我的侦听器源代码是以下:
MSG message;
HMODULE lib = LoadLibrary(L"C:/HookTouch.dll");
if (lib) {
HOOKPROC procedure = (HOOKPROC)GetProcAddress(lib, "_procedure@12");
dllFunct fonctionCallback = (dllFunct)GetProcAddress(lib, "setCallback");
if (fonctionCallback)
fonctionCallback(MyCallback);
if (procedure)
hook = SetWindowsHookEx(WH_GETMESSAGE, procedure, lib, 0);
}
else
printf("Can't find dll!n");
while (GetMessage(&message, NULL, 0, 0))
{
TranslateMessage(&message);
DispatchMessage(&message);
}
FreeLibrary(lib);
UnhookWindowsHookEx(hook);
我自己的回调显示"你好单击"是:
void MyCallback(int nCode, WPARAM wParam, LPARAM lParam)
{
printf("Hello Clickn");
}
我知道我的钩子正在工作,因为我可以通过使用消息框而不是pf(nCode, wParam, lParam)
在单击上显示一条消息,但是当我使用此功能销钉时,不会触发myCallback。我检查了我的功能是否受到PF功能点的影响,似乎还可以。
您知道为什么pf(nCode, wParam, lParam)
的呼叫不会触发侦听器的myCallback函数?
您仅针对在过程中加载的DLL调用setCallback
。SetWindowsHookEx
将在所有其他过程中注入的DLL将没有回调集。最重要的是,MyCallback
仅在您自己的过程中定义。在其他过程中注入的DLL没有访问它的微不足道的方式。
由于您不知道Windows为您注入了哪些过程,因此您将需要DLL将其"位置"传播给您,例如。命名管。一旦将每个DLL的进程ID注入了注入的DLL,就可以使用CreateRemoteThread
在DLL中调用函数,例如setCallback
..仍然需要做一些工作,以便DLL可以直接致电您回调:您将需要将dll从模块群提供确切的回调偏移,然后DLL将需要使用CreateRemoteThread
本身发出呼叫。这一切都很快变得太乏味了,您将明智地使用命名的管道通信而不是发出直接函数呼叫。
提示:从其他过程中记录事物的一种简单方法是使用OutputDebugString
。或者,写入文件。
这种方法将行不通。
一个消息挂钩在挂钩的每个线程的上下文中运行。每个连接过程都将获得您自己的DLL注入其中的副本。因此,只有最初安装的钩子的副本才能具有有效的功能指针集。此外,无论如何,您都不能跨进程范围调用回调函数。
您需要使用其他IPC机制让您的注射钩子回到主要应用程序过程中。
例如,您可以创建一个隐藏的HWND
并将其存储在全局共享存储器的块中,然后每个注入的挂钩都可以将窗口消息发送到它,例如WM_COPYDATA
。或者,您的主应用程序可以打开一个命名的管道,每个注射钩可以连接到并将数据发送到。
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 函数调用中参数的顺序重要吗
- OpenGL - 在抛出"__gnu_cxx::recursive_init_error"实例后终止调用?
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 在c++类上调用void函数
- 为什么 std::unique 不调用 std::sort?
- 调用专用模板时出错"no matching function for call to [...]"
- 选择要调用的构造函数
- C++为什么尽管我调用了void函数,它却不起作用
- 构造函数正在调用一个使用当前类类型的函数
- 变量没有改变?通过向量的函数调用
- 没有为自己的结构调用列表推回方法
- 调用'begin(int [n])'没有匹配函数
- 什么时候调用析构函数
- 如何用参数值调用函数(仅在运行时已知)
- std::cout.imbue()多重调用
- 如何从SetWindowShookex回调中调用Fuction-Pointer