在内联汇编中调用函数时如何保留堆栈?

时间:2017-05-06 22:16:00

标签: c++ winapi assembly

我有一个执行内联汇编的钩子函数:

__declspec(naked) int hookConnect()
{
    __asm
    {
        pushad;
        pushfd;

        push [esp + 0x2C];
        pop sockAddrBackup;

        push[esp + 0x2C];
        push[esp + 0x2C];
        call mConnect;

        popfd;
        popad;

        call connectTramp;

        ret;
    }
}

它保存了寄存器和标志。然后将其中一个args保存到变量中,最后推送2个args并调用我的自定义函数,该函数只记录args。

之后,它恢复寄存器,标志。这时我想打电话给蹦床:

蹦床:

5 original bytes  
jmp (original func + 5 bytes)

执行前5个字节,跳转到原始函数并执行它,然后返回到我的钩子函数。

此时,我想返回原始func的调用者,但是因为函数结束时调用了leave,它会打破堆栈吗?

如何通过执行保留堆栈?在致电之前保存退货地址?

1 个答案:

答案 0 :(得分:2)

通过调用trampoline,您将在原始参数上方放置另一个堆栈帧,这意味着它们不是原始代码期望找到它们的位置(堆栈上有两个返回地址而不是一个)。 / p>

你必须

  1. 跳到蹦床(你的钩子将无法结束)
    1. 在调用trampoline之前将原始参数复制到堆栈中,并在它返回后进行清理,小心保留返回值。