4

我有一个代码可以将要调用的函数更改为我的新函数,但我不想只调用我的新函数,我也想调用旧函数。这是一个例子,所以你可以理解我在说什么:

如果我反汇编我的 .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 中。

谢谢。

4

2 回答 2

2

ret期望栈顶参数是要返回的地址。ret您可以通过在新函数中的指令之前立即将旧函数地址推入堆栈来利用这一点。随着调用返回(或者更确切地说,分支到旧函数),堆栈指针将移动以将原始返回地址(此处为 0x128)留在顶部,因此堆栈将看起来完好无损。(如果你没有绕道,它应该是一样的)。

于 2010-07-13T02:28:18.547 回答
2

前段时间我遇到过这样的问题。无论如何,_asm call dword ptr [oldfunction]为我工作。

于 2010-07-13T04:26:00.540 回答