我有一段代码可以将要调用的函数更改为我的新函数,但我不想只调用我的新函数,我还想调用旧函数。 这是一个例子,所以你可以明白我在说什么:
如果我反汇编我的.exe,我会看看这部分:
L00123456:
mov eax, [L00654321] //doesn't matter
mov ecx, [eax+1Ch] //doesn't matter
push esi //the only parameter
0x123 call SUB_L00999999 //this is the function I wanna overwrite
//...
(0x123是该行的地址) 所以,我使用了这段代码:
DWORD old;
DWORD from = 0x123;
DWORD to = MyNewFunction;
VirtualProtect(from, 5, PAGE_EXECUTE_READWRITE, &old);
DWORD disp = to - (from + 5);
*(BYTE *)(from) = 0xE8;
*(DWORD *)(from + 1) = (DWORD)disp;
现在,它不再调用 SUB_L00999999,而是调用 MyNewFunction...
那么...关于如何仍然调用旧函数有什么想法吗?
我尝试了这样的事情(在很多方面),但它使我的应用程序崩溃了:
int MyNewFunction(int parameter)
{
DWORD oldfunction = 0x00999999;
_asm push parameter
_asm call oldfunction
}
注意:我使用 Visual Studio C++ 2010,这些代码位于 .exe 中加载的 .dll 中。
谢谢。
不久前我也遇到过这样的问题。不管怎样,
_asm call dword ptr [oldfunction]
对我有用。
ret
期望栈顶参数是要返回的地址。您可以通过将旧函数地址压入新函数中的 ret
指令之前的堆栈来利用此漏洞。当调用返回(或者更确切地说,分支到旧函数)时,堆栈指针将移动以将原始返回地址(此处为 0x128)保留在顶部,因此堆栈将显示未损坏。 (如果你不绕路的话应该是一样的)。