我编写了一个简单的程序,该程序可以执行3件事:
它使用文本“ NOT HOOKED”调用MessageBoxA(MBA)
然后,它会加载我创建的dll文件,该文件会钩住MBA函数并以文本“ HOOKED”调用MBA。
之后,它将再次使用相同的文本(“ NOT HOOKED”)调用MBA。 当然,应该挂断第二个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;
}
当我在Debug模式下构建并运行时,它在第二次MBA调用时崩溃(当然在.cpp文件中):
它像应显示的那样显示带有“ HOOKED”字样的钩住的MBA,然后崩溃,在下面打印错误,程序退出并显示代码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:
如果我处于“释放”模式,则只要在FreeLibrary调用之前,我就可以根据需要调用任意数量的MBA调用,所有这些调用都将被.dll文件挂接,并且程序将正确退出。
但是,如果我尝试在FreeLibrary调用之后 之后调用MBA函数-程序因以下错误而崩溃:
Exception thrown at 0x50011000 in ProgrammingTask.exe: 0xC0000005: Access violation executing location 0x50011000.
注意2:
我尝试使用DetourDetouch分离dll,但无法解决问题,也许是我做错了。
另外,我尝试阅读有关CreateRemoteThread的内容,但对我来说太混乱了。
谢谢。
答案 0 :(得分:0)
发现了!
忘记将__stdcall添加到HookedMessageBox函数中。
因此,而不是
int HookedMessageBoxA
我将其重写为:
int __stdcall HookedMessageBoxA
感谢您的帮助! <3