【发布时间】:2012-08-28 11:16:36
【问题描述】:
我正在使用带有 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 不起作用。
我在网上没有找到解决方案,也没有找到解决这个奇怪问题的起点。
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!
【问题讨论】:
-
显然操作系统很生气,因为您为键盘挂钩编写了 MouseProc() 并决定反转所有内容。
-
好吧,我也是个怪人!我会尝试向操作系统道歉,但我认为它不会解决问题。
-
您需要显示更多代码。您对 SetWindowsHookEx() 的调用在哪里?它是在应用程序内部还是在 DLL 内部?你传递给它什么参数?
-
您的代码中有一些错误。您需要将
HHOOK句柄存储在共享内存块中。您可以为此使用CreateFileMapping()和MapViewOfFile()。但更重要的是,应用程序中的callIt()回调没有使用__stdcall调用约定,但 DLL 期望它使用。如果您的代码是类型安全的,您就会发现该错误。InstallMouseHook()的function参数需要声明为CALLIT而不是void*。 -
另一个问题是您正在安装一个回调函数指针,该指针属于一个进程,但可能由被挂钩的进程执行。更好的解决方案是使用
HWND代替函数指针,并让钩子向窗口发送消息,而不是直接调用函数指针。这样会更安全。
标签: dll hook c++builder 32bit-64bit setwindowshookex