2012-09-03 106 views
0

我正在使用帶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內部?你傳遞給它什麼參數? –

回答

1

這在物理上是不可能的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位鉤子。期。 –