奇怪的挂钩行为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! 
+1

很明显,操作系统被冒犯了,你为键盘钩子写了一个MouseProc()并决定颠倒一切。 –

+0

好吧,我也是一个奇怪的人!我会尝试道歉操作系统,但我认为它不会解决问题。 – sgm

+0

您需要展示更多代码。你打给SetWindowsHookEx()的地方在哪里?它是在应用程序内还是在DLL内部?你传递给它什么参数? –

这在物理上是不可能的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位操作系统版本上不起作用,这表明你的钩子代码是有缺陷的。但是你没有显示足够的代码来诊断这种或那种方式。

+0

那么代码如下: – sgm

+0

我能说什么,上面的代码(用rad studio编译为32位)只能使用IE64,而不能使用IE32(与其他应用程序相同)。函数SetWindowsHookEx在DLL中。 – sgm

+0

绝对没有可能的方式IE64可以执行您的32位挂钩DLL。这实际上是不可能的。只有32位进程可以调用32位钩子。期。 –