SetWindowsHookEx() 方法失败,代码为:1428 - dll 注入
SetWindowsHookEx() method fails with code: 1428 - dll injection
我有以下代码:
LRESULT __stdcall HookCallback(int code,
WPARAM wParam,
LPARAM lParam)
{
...
return CallNextHookEx(_hook, code, wParam, lParam);
}
void SetHook()
{
HMODULE hmod = GetModuleHandle(0);
if (!(_hook = SetWindowsHookEx(WH_CALLWNDPROCRET, HookCallback, hmod, 0)))
{
OutputDebugString(TEXT("Failed to Install hook"));
}
OutputDebugString(TEXT("Exiting SETHOOK METHOD"));
}
void ReleaseHook()
{
UnhookWindowsHookEx(_hook);
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
OutputDebugString(TEXT("Entered DLL"));
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
SetHook();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
ReleaseHook();
break;
}
return TRUE;
}
我正在尝试设置一个钩子来对 window 操作做出反应。主要是windows的开闭。
我在 C++ 方面非常缺乏经验,所以我很难调试应用程序并理解我做错了什么。
在我的 SetHook()
方法中,SetWindowHookEx 方法总是失败,代码为 1428。因此永远不会调用回调方法(此处未显示)。
我做错了什么?
PS:我正在使用注册表将 .dll 注入到进程中:
路径:Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows
姓名:AppInit_DLLS
据我所知这是可行的,因为我收到了调试消息 "Failed to Install hook" 和 "Exiting SETHOOK METHOD".
您将 0(又名 NULL)传递给 GetModuleHandle()
,因此您正在检索 EXE 文件的 HMODULE
,您的 DLL 加载到该文件的进程中:
Parameters
lpModuleName
The name of the loaded module (either a .dll or .exe file) ...
If this parameter is NULL, GetModuleHandle returns a handle to the file used to create the calling process (.exe file).
您不能使用 HMODULE
安装 DLL 中的 SetWindowsHookEx()
挂钩回调。您需要使用 DLL 自己的 HMODULE
本身,即作为输入参数提供给您的 DllMain()
的那个,例如:
HHOOK _hook = NULL;
LRESULT __stdcall HookCallback(int code,
WPARAM wParam,
LPARAM lParam)
{
...
return CallNextHookEx(_hook, code, wParam, lParam);
}
void SetHook(HMODULE hModule) // <-- ADD THIS PARAM
{
if (!_hook)
{
_hook = SetWindowsHookEx(WH_CALLWNDPROCRET, HookCallback, hModule, 0); // <-- USE IT HERE
if (!_hook)
{
OutputDebugString(TEXT("Failed to Install hook"));
}
}
OutputDebugString(TEXT("Exiting SETHOOK METHOD"));
}
void ReleaseHook()
{
if (_hook)
{
UnhookWindowsHookEx(_hook);
_hook = NULL;
}
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
OutputDebugString(TEXT("Entered DLL"));
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hModule);
SetHook(hModule); // <-- PASS IT HERE
break;
case DLL_PROCESS_DETACH:
ReleaseHook();
break;
}
return TRUE;
}
也就是说,您正在尝试全局安装一个挂钩(hMod != NULL
和 dwThreadId == 0
),因此您只需要调用 1 次 SetWindowsHookEx()
,这没有意义在加载 DLL 的 每个 进程中调用它。您应该创建自己的 EXE,将 DLL 加载到内存中并为其调用 SetWindowsHookEx()
1 次,例如:
HMODULE _hmod = NULL;
HHOOK _hook = NULL;
// be sure to export your hook functions from the DLL..
LRESULT __stdcall HookCallback(int code,
WPARAM wParam,
LPARAM lParam)
{
...
return CallNextHookEx(_hook, code, wParam, lParam);
}
void SetHook()
{
if (!_hook)
{
_hook = SetWindowsHookEx(WH_CALLWNDPROCRET, HookCallback, _hmod, 0);
if (!_hook)
{
OutputDebugString(TEXT("Failed to Install hook"));
}
}
OutputDebugString(TEXT("Exiting SETHOOK METHOD"));
}
void ReleaseHook()
{
if (_hook)
{
UnhookWindowsHookEx(_hook);
_hook = NULL;
}
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
_hmod = hModule;
OutputDebugString(TEXT("Entered DLL"));
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hModule);
break;
}
return TRUE;
}
typedef void (*LPFN_SH)();
typedef void (*LPFN_RH)();
HMODULE hMod = LoadLibrary("my.dll");
LPFN_SH SetHook = (LPFN_SH) GetProcAddress(hMod, "SetHook");
LPFN_RH ReleaseHook = (LPFN_RH) GetProcAddress(hMod, "ReleaseHook");
...
SetHook();
...
ReleaseHook();
FreeLibrary(hMod);
然后,在 EXE 进程的生命周期内,您的 DLL 将自动注入每个 运行 与您的 DLL 位数相匹配的进程(这意味着您需要单独的 DLL 来挂接 32 位和 64 位进程)。根本不需要使用 AppInit_DLLS
注册表项。
否则,如果您真的想使用 AppInit_DLLS
将您的 DLL 注入每个位数匹配进程,那么最好让 DLL 在每个线程的基础上调用 SetWindowsHookEx()
(hMod == NULL
和 dwThreadId != 0
)而不是在全球范围内,例如:
__declspec(thread) HHOOK _hook = NULL;
LRESULT __stdcall HookCallback(int code,
WPARAM wParam,
LPARAM lParam)
{
...
return CallNextHookEx(_hook, code, wParam, lParam);
}
void SetHook()
{
if (!_hook)
{
DWORD dwThreadId = GetCurrentThreadId();
_hook = SetWindowsHookEx(WH_CALLWNDPROCRET, HookCallback, NULL, dwThreadId);
if (!_hook)
{
OutputDebugString(TEXT("Failed to Install hook"));
}
}
OutputDebugString(TEXT("Exiting SETHOOK METHOD"));
}
void ReleaseHook()
{
if (_hook)
{
UnhookWindowsHookEx(_hook);
_hook = NULL;
}
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
OutputDebugString(TEXT("Entered DLL"));
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
SetHook();
break;
case DLL_PROCESS_DETACH:
case DLL_THREAD_DETACH:
ReleaseHook();
break;
}
return TRUE;
}
那么就不需要使用单独的 EXE 加载器了。
我有以下代码:
LRESULT __stdcall HookCallback(int code,
WPARAM wParam,
LPARAM lParam)
{
...
return CallNextHookEx(_hook, code, wParam, lParam);
}
void SetHook()
{
HMODULE hmod = GetModuleHandle(0);
if (!(_hook = SetWindowsHookEx(WH_CALLWNDPROCRET, HookCallback, hmod, 0)))
{
OutputDebugString(TEXT("Failed to Install hook"));
}
OutputDebugString(TEXT("Exiting SETHOOK METHOD"));
}
void ReleaseHook()
{
UnhookWindowsHookEx(_hook);
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
OutputDebugString(TEXT("Entered DLL"));
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
SetHook();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
ReleaseHook();
break;
}
return TRUE;
}
我正在尝试设置一个钩子来对 window 操作做出反应。主要是windows的开闭。 我在 C++ 方面非常缺乏经验,所以我很难调试应用程序并理解我做错了什么。
在我的 SetHook()
方法中,SetWindowHookEx 方法总是失败,代码为 1428。因此永远不会调用回调方法(此处未显示)。
我做错了什么?
PS:我正在使用注册表将 .dll 注入到进程中:
路径:Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows
姓名:AppInit_DLLS
据我所知这是可行的,因为我收到了调试消息 "Failed to Install hook" 和 "Exiting SETHOOK METHOD".
您将 0(又名 NULL)传递给 GetModuleHandle()
,因此您正在检索 EXE 文件的 HMODULE
,您的 DLL 加载到该文件的进程中:
Parameters
lpModuleName
The name of the loaded module (either a .dll or .exe file) ...
If this parameter is NULL, GetModuleHandle returns a handle to the file used to create the calling process (.exe file).
您不能使用 HMODULE
安装 DLL 中的 SetWindowsHookEx()
挂钩回调。您需要使用 DLL 自己的 HMODULE
本身,即作为输入参数提供给您的 DllMain()
的那个,例如:
HHOOK _hook = NULL;
LRESULT __stdcall HookCallback(int code,
WPARAM wParam,
LPARAM lParam)
{
...
return CallNextHookEx(_hook, code, wParam, lParam);
}
void SetHook(HMODULE hModule) // <-- ADD THIS PARAM
{
if (!_hook)
{
_hook = SetWindowsHookEx(WH_CALLWNDPROCRET, HookCallback, hModule, 0); // <-- USE IT HERE
if (!_hook)
{
OutputDebugString(TEXT("Failed to Install hook"));
}
}
OutputDebugString(TEXT("Exiting SETHOOK METHOD"));
}
void ReleaseHook()
{
if (_hook)
{
UnhookWindowsHookEx(_hook);
_hook = NULL;
}
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
OutputDebugString(TEXT("Entered DLL"));
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hModule);
SetHook(hModule); // <-- PASS IT HERE
break;
case DLL_PROCESS_DETACH:
ReleaseHook();
break;
}
return TRUE;
}
也就是说,您正在尝试全局安装一个挂钩(hMod != NULL
和 dwThreadId == 0
),因此您只需要调用 1 次 SetWindowsHookEx()
,这没有意义在加载 DLL 的 每个 进程中调用它。您应该创建自己的 EXE,将 DLL 加载到内存中并为其调用 SetWindowsHookEx()
1 次,例如:
HMODULE _hmod = NULL;
HHOOK _hook = NULL;
// be sure to export your hook functions from the DLL..
LRESULT __stdcall HookCallback(int code,
WPARAM wParam,
LPARAM lParam)
{
...
return CallNextHookEx(_hook, code, wParam, lParam);
}
void SetHook()
{
if (!_hook)
{
_hook = SetWindowsHookEx(WH_CALLWNDPROCRET, HookCallback, _hmod, 0);
if (!_hook)
{
OutputDebugString(TEXT("Failed to Install hook"));
}
}
OutputDebugString(TEXT("Exiting SETHOOK METHOD"));
}
void ReleaseHook()
{
if (_hook)
{
UnhookWindowsHookEx(_hook);
_hook = NULL;
}
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
_hmod = hModule;
OutputDebugString(TEXT("Entered DLL"));
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hModule);
break;
}
return TRUE;
}
typedef void (*LPFN_SH)();
typedef void (*LPFN_RH)();
HMODULE hMod = LoadLibrary("my.dll");
LPFN_SH SetHook = (LPFN_SH) GetProcAddress(hMod, "SetHook");
LPFN_RH ReleaseHook = (LPFN_RH) GetProcAddress(hMod, "ReleaseHook");
...
SetHook();
...
ReleaseHook();
FreeLibrary(hMod);
然后,在 EXE 进程的生命周期内,您的 DLL 将自动注入每个 运行 与您的 DLL 位数相匹配的进程(这意味着您需要单独的 DLL 来挂接 32 位和 64 位进程)。根本不需要使用 AppInit_DLLS
注册表项。
否则,如果您真的想使用 AppInit_DLLS
将您的 DLL 注入每个位数匹配进程,那么最好让 DLL 在每个线程的基础上调用 SetWindowsHookEx()
(hMod == NULL
和 dwThreadId != 0
)而不是在全球范围内,例如:
__declspec(thread) HHOOK _hook = NULL;
LRESULT __stdcall HookCallback(int code,
WPARAM wParam,
LPARAM lParam)
{
...
return CallNextHookEx(_hook, code, wParam, lParam);
}
void SetHook()
{
if (!_hook)
{
DWORD dwThreadId = GetCurrentThreadId();
_hook = SetWindowsHookEx(WH_CALLWNDPROCRET, HookCallback, NULL, dwThreadId);
if (!_hook)
{
OutputDebugString(TEXT("Failed to Install hook"));
}
}
OutputDebugString(TEXT("Exiting SETHOOK METHOD"));
}
void ReleaseHook()
{
if (_hook)
{
UnhookWindowsHookEx(_hook);
_hook = NULL;
}
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
OutputDebugString(TEXT("Entered DLL"));
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
SetHook();
break;
case DLL_PROCESS_DETACH:
case DLL_THREAD_DETACH:
ReleaseHook();
break;
}
return TRUE;
}
那么就不需要使用单独的 EXE 加载器了。