我做了一个非常简单的程序,创建一个窗口并显示"随机数是:[从0到9的随机数]"在左上角。显示数字的功能如下所示:
void DisplayThings(HDC hdc, HWND hWnd, int randomNum)
{
std::stringstream text;
text << "Random number is: " << randomNum;
TextOut(hdc, 0, 0, text.str().c_str(), text.str().length());
}
在OllyDBG中,我发现它位于地址0x11211A0:
接下来,我创建了一个试图在Microsoft Detour的帮助下绕过DisplayThings函数的dll,这是dll的样子:
#pragma comment(lib, "detours.lib")
#include <Windows.h>
#include <detours.h>
#include <tchar.h>
#include <sstream>
typedef void (*pDisplayThingsFunc)(HDC hdc, HWND hWnd, int randomNum);
void DisplayThingsFunc(HDC hdc, HWND hWnd, int randomNum)
{
printf("function is being detoured\n");
TextOut(hdc, 0, 20, L"detoured", 8);
}
pDisplayThingsFunc DisplayThingsFuncToDetour = (pDisplayThingsFunc)(0x11211A0);
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved )
{
//DWORD *hiddenValueAdress = (DWORD*)(*(DWORD*)0x020FAB8);
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
AllocConsole();
freopen("CONOUT$", "w", stdout);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)DisplayThingsFuncToDetour, DisplayThingsFunc);
DetourTransactionCommit();
break;
case DLL_PROCESS_DETACH:
FreeConsole();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)DisplayThingsFuncToDetour, DisplayThingsFunc);
DetourTransactionCommit();
break;
}
return TRUE;
}
一旦我注入了dll,地址就会被JMP正确替换为我的新功能,但随后发生了一些奇怪的事情......控制台继续打印&#34;功能正在被绕开&#34;但TextOut函数无法显示任何内容......
任何帮助将不胜感激!
答案 0 :(得分:-1)
编译器正在优化代码,因为它推断出它可以安全地为此函数执行此操作。
您可以更改其中一项(例如,通过导出符号,将其分配给函数指针等)。
或者您可以尝试按原样挂钩。
首先,你需要推断出你感兴趣的论点在哪里被传递,which is most likely a register. 最简单的方法是分析对TextOut的调用并追溯hdc参数。 如果你很幸运并且只是通过快速调用来优化它,可以将函数和函数指针的类型更改为fastcall,然后完成。
如果你没那么幸运,你可能不得不从内联汇编的额外寄存器中获取它。