奇怪的挂钩行为32/64位
我正在使用带ms字(OpusApp)的本地挂钩(WH_KEYBOARD)
。那么,据我所知,一个32bit DLL
32位应用程序必须只与32bit target applications
工作。奇怪的是,该程序只适用于64位应用程序!就是这样,只有64bits APPS
!例如,it works with IE 64 but not with IE 32!
该应用程序和dll
是用radstudio XE2
编译的32位,我确认版本到PE标头。 在32位操作系统中,应用程序和dll不起作用。奇怪的挂钩行为32/64位
我在网上找不到解决方案,也没有看到解决这个奇怪问题的起点。
该DLL的代码:
// Exported functions
extern "C" __declspec(dllexport)bool __stdcall InstallMouseHook(unsigned long, void *);
extern "C" __declspec(dllexport)bool __stdcall RemoveMouseHook();
// Callback Procedure Declaration
LRESULT CALLBACK HookProc(int code, WPARAM wParam, LPARAM lParam);
// Global variables
HHOOK HookHandle;
HINSTANCE DllInstance;
typedef void (__stdcall *CALLIT)(int,WPARAM,LPARAM);
CALLIT callIt = NULL;
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)
{
DllInstance=hinst;
return 1;
}
bool __stdcall InstallMouseHook(unsigned long pid, void *function)
{
callIt = (CALLIT) function;
if (function == NULL) {
ShowMessage("function is null!");
} else if (callIt == NULL) {
ShowMessage("callIt is null!");
}
HookHandle=SetWindowsHookEx(WH_KEYBOARD ,reinterpret_cast<HOOKPROC> (HookProc),DllInstance,pid);
if (HookHandle==NULL)return false;
else return true;
}
bool __stdcall RemoveMouseHook()
{
if(UnhookWindowsHookEx(HookHandle)==0)
{
return false;
}
else return true;
}
LRESULT CALLBACK HookProc(int code, WPARAM wParam, LPARAM lParam)
{
if (code<0) {
return CallNextHookEx(HookHandle,code,wParam,lParam);
}
if (callIt != NULL) {
callIt(code,wParam,lParam);
} else {
ShowMessage("HookProc - no function to execute OR 32/64 bits problem!");
}
//Call the next hook in the chain
return CallNextHookEx(HookHandle,code,wParam,lParam);
}
的EXE调用代码:
void __fastcall TfrmMouseHook::btnHookAppDllClick(TObject *Sender)
{
HWND hWindow;
unsigned long pid;
String s = "MouseHookDLL.dll";
DllHandle=LoadLibrary(s.w_str());
MOUSEHOOKFCT_2 InstHook=reinterpret_cast<MOUSEHOOKFCT_2> (GetProcAddress(DllHandle,"InstallMouseHook"));
hWindow = FindWindow(ComboBox1->Text.w_str(),NULL);
if (!hWindow) {
msg("hWindow fail");
return;
}
pid = GetWindowThreadProcessId(hWindow ,0);
if (!pid) {
msg("pid fail");
return;
}
if(!InstHook(pid, (void *) callIt)) {
msg("Unable to install hook!");
} else {
msg(" #### hook INSTALLED! ####");
}
}
CALLIT callIt(code,wParam,lParam) {
frmMouseHook->msg("hook callit: code="+IntToStr(code) +" wparam="+IntToStr(wParam)+" lparam="+IntToStr(lParam));
}
Call IT is a function pointer to a hooker app function.
Any ideas will be very wellcome!
这在物理上是不可能的32位应用程序来安装一个32位钩DLL并具有它执行在64位进程。 32位DLL不能被注入到64位进程中。期。 MSDN在多个地方说明了这一点,包括在SetWindowsHookEx() documentation:
SetWindowsHookEx可用于将DLL注入到另一个进程中。 A 32位DLL无法注入到64位进程中,并且64位DLL 无法注入到32位进程中。如果应用程序需要在其他进程中使用钩子,则要求32位应用程序调用SetWindowsHookEx将32位DLL注入到32位 进程中,并且64位应用程序调用SetWindowsHookEx以注入 将64位DLL转换为64位进程。 32位和64位DLL必须有 不同的名称。
因为钩子在应用程序的上下文中运行,所以它们必须匹配应用程序的“位数” 。如果32位应用程序在64位Windows上安装了全局挂接,则将32位挂接注入到每个32位进程(通常的安全边界适用)中。在64位 进程中,线程仍被标记为“挂钩”。但是,由于32位应用程序必须运行该钩子代码,系统将在钩子应用程序的上下文中执行 挂钩;具体来说,在 调用SetWindowsHookEx的线程上。这意味着挂钩应用程序必须继续泵送消息,否则可能会阻止64位进程的正常运行。
如果在64位应用程序安装上的64位的Windows全局钩子,所述 64位钩被注入到每个64位处理,而所有32位 过程使用回调至位于钩应用。
事实上,你说你的应用程序和DLL在32位操作系统版本上不起作用,这表明你的钩子代码是有缺陷的。但是你没有显示足够的代码来诊断这种或那种方式。
很明显,操作系统被冒犯了,你为键盘钩子写了一个MouseProc()并决定颠倒一切。 –
好吧,我也是一个奇怪的人!我会尝试道歉操作系统,但我认为它不会解决问题。 – sgm
您需要展示更多代码。你打给SetWindowsHookEx()的地方在哪里?它是在应用程序内还是在DLL内部?你传递给它什么参数? –