当挂钩函数被调用 C++ 时,使用 MS Detours 挂钩会崩溃
Hooking with MS Detours crash when hook function is called C++
我写了一个简单的程序来做三件事:
它用文本 "NOT HOOKED"
调用 MessageBoxA (MBA)
然后它加载我创建的一个 dll 文件,该文件挂钩 MBA 函数并使用文本 "HOOKED".
调用 MBA
之后,它再次使用相同的文本调用 MBA ("NOT HOOKED")。
当然,应该挂接第二个 MBA 调用并显示带有 "HOOKED" 文本的消息。
最终它调用 FreeLibrary 并退出。
这是 .cpp 文件:
#include <iostream>
#include <Windows.h>
using namespace std;
int main()
{
//Place the path of the dll file here, "DLLs\HookDLL.dll" is the default path.
char dllPath[] = "HookDLL.dll";
//Display a pop-up message with the "NOT HOOKED" message and title.
MessageBoxA(NULL, "NOT HOOKED", "NOT HOOKED", MB_OK);
//Load the dll file
HMODULE hModule = LoadLibraryA((LPCSTR)dllPath);
//If hModule is null, then the dll wasn't loaded.
//An error message will be printed out to the console.
if (!hModule) {
cout << "Couldn't load the DLL file!" << endl;
return 1;
}
//This is the tricky part.
//This should display a pop-up message like before with the "NOT HOOKED" message and title,
//but the dll that was loaded should hook MessageBoxA function,
//and call a new one with a "HOOKED" message and title instead.
MessageBoxA(NULL, "NOT HOOKED", "NOT HOOKED", MB_OK);
FreeLibrary(hModule);
return 0;
}
这里是 .dll 文件:
#include "pch.h"
#include "detours.h"
#include <iostream>
#include <Windows.h>
using namespace std;
typedef int(WINAPI* MBA)(HWND, LPCSTR, LPCSTR, UINT);
MBA originalMBA = NULL;
int HookedMessageBoxA(
HWND hWnd,
LPCSTR lpText,
LPCSTR lpCaption,
UINT uType
) {
return originalMBA(NULL, "HOOKED", "HOOKED", MB_OK);
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD reason,
LPVOID lpReserved
)
{
if (reason == DLL_PROCESS_ATTACH) {
DetourRestoreAfterWith();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
originalMBA = (MBA)DetourFindFunction("user32.dll", "MessageBoxA");//Pointer the the original MBA (MessageBoxA) function.
DetourAttach(&(PVOID&)originalMBA, (PVOID)HookedMessageBoxA);
DetourTransactionCommit();
}
return TRUE;
}
当我在调试模式下构建和 运行 时,它在第二次 MBA 调用时崩溃(当然是在 .cpp 文件中):
它显示挂钩的 MBA,其中包含 "HOOKED",就像它应该的那样,然后它崩溃,在下面打印错误,程序退出,代码为 3:
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call.
This is usually a result of calling a function declared with one calling convention with a function
pointer declared with a different calling convention.
我已经检查了这个错误和退出代码,并找到了很多有用的帖子和解决方案,但我无法让它们中的任何一个为我工作(也许我做错了什么)。
注1:
如果我处于 Release 模式,我可以调用任意多的 MBA 调用 只要它们先于 FreeLibrary 调用,并且所有这些调用都将被 .dll 文件很好地挂钩,程序将正确退出。
但是,如果我尝试在调用 FreeLibrary 之后调用 MBA 函数 - 程序会因以下错误而崩溃:
Exception thrown at 0x50011000 in ProgrammingTask.exe: 0xC0000005: Access violation executing location 0x50011000.
注2:
我尝试使用DetourDetouch分离dll,但没有解决,可能我做错了。
另外,我尝试阅读有关 CreateRemoteThread 的内容,但对我来说太乱了。
提前致谢。
找到了!
忘记将 __stdcall 添加到 HookedMessageBox 函数。
所以,而不是
int HookedMessageBoxA
我改写成这样:
int __stdcall HookedMessageBoxA
感谢大家的帮助! <3
我写了一个简单的程序来做三件事:
它用文本 "NOT HOOKED"
然后它加载我创建的一个 dll 文件,该文件挂钩 MBA 函数并使用文本 "HOOKED".
之后,它再次使用相同的文本调用 MBA ("NOT HOOKED")。 当然,应该挂接第二个 MBA 调用并显示带有 "HOOKED" 文本的消息。
最终它调用 FreeLibrary 并退出。
这是 .cpp 文件:
#include <iostream>
#include <Windows.h>
using namespace std;
int main()
{
//Place the path of the dll file here, "DLLs\HookDLL.dll" is the default path.
char dllPath[] = "HookDLL.dll";
//Display a pop-up message with the "NOT HOOKED" message and title.
MessageBoxA(NULL, "NOT HOOKED", "NOT HOOKED", MB_OK);
//Load the dll file
HMODULE hModule = LoadLibraryA((LPCSTR)dllPath);
//If hModule is null, then the dll wasn't loaded.
//An error message will be printed out to the console.
if (!hModule) {
cout << "Couldn't load the DLL file!" << endl;
return 1;
}
//This is the tricky part.
//This should display a pop-up message like before with the "NOT HOOKED" message and title,
//but the dll that was loaded should hook MessageBoxA function,
//and call a new one with a "HOOKED" message and title instead.
MessageBoxA(NULL, "NOT HOOKED", "NOT HOOKED", MB_OK);
FreeLibrary(hModule);
return 0;
}
这里是 .dll 文件:
#include "pch.h"
#include "detours.h"
#include <iostream>
#include <Windows.h>
using namespace std;
typedef int(WINAPI* MBA)(HWND, LPCSTR, LPCSTR, UINT);
MBA originalMBA = NULL;
int HookedMessageBoxA(
HWND hWnd,
LPCSTR lpText,
LPCSTR lpCaption,
UINT uType
) {
return originalMBA(NULL, "HOOKED", "HOOKED", MB_OK);
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD reason,
LPVOID lpReserved
)
{
if (reason == DLL_PROCESS_ATTACH) {
DetourRestoreAfterWith();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
originalMBA = (MBA)DetourFindFunction("user32.dll", "MessageBoxA");//Pointer the the original MBA (MessageBoxA) function.
DetourAttach(&(PVOID&)originalMBA, (PVOID)HookedMessageBoxA);
DetourTransactionCommit();
}
return TRUE;
}
当我在调试模式下构建和 运行 时,它在第二次 MBA 调用时崩溃(当然是在 .cpp 文件中):
它显示挂钩的 MBA,其中包含 "HOOKED",就像它应该的那样,然后它崩溃,在下面打印错误,程序退出,代码为 3:
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
我已经检查了这个错误和退出代码,并找到了很多有用的帖子和解决方案,但我无法让它们中的任何一个为我工作(也许我做错了什么)。
注1:
如果我处于 Release 模式,我可以调用任意多的 MBA 调用 只要它们先于 FreeLibrary 调用,并且所有这些调用都将被 .dll 文件很好地挂钩,程序将正确退出。
但是,如果我尝试在调用 FreeLibrary 之后调用 MBA 函数 - 程序会因以下错误而崩溃:
Exception thrown at 0x50011000 in ProgrammingTask.exe: 0xC0000005: Access violation executing location 0x50011000.
注2:
我尝试使用DetourDetouch分离dll,但没有解决,可能我做错了。
另外,我尝试阅读有关 CreateRemoteThread 的内容,但对我来说太乱了。
提前致谢。
找到了!
忘记将 __stdcall 添加到 HookedMessageBox 函数。
所以,而不是
int HookedMessageBoxA
我改写成这样:
int __stdcall HookedMessageBoxA
感谢大家的帮助! <3