汇编堆栈存储器中的加法函数参数位置

逆向工程 拆卸
2021-07-08 10:35:03

所以我的 C 程序看起来像:

int main()
{
    int a = 5;
    int b = 1;
    int c = add(a, b);
    printf("%d", c);
    return 0;
}

int add(int a, int b){
    return a + b;
}

我试图了解参数如何传递到堆栈中的行为。为了做同样的事情,我将代码颠倒过来进行反汇编:

在此处输入图片说明

主功能

现在esp被复制到ebpadd功能,那么为什么添加812访问值51在下一行-应该不会是[ebp][ebp + 4h]我真的很困惑。

谢谢。

2个回答

在 x86 上,堆栈不仅用于传递参数。它还可以存储其他东西,例如函数的返回地址或需要临时保存的寄存器,以及局部变量。在您的示例中,push ebp调整esp了 4 个字节,因此在下一条指令中esp复制到ebp,堆栈帧如下所示:

 [ebp+0] old ebp value (pushed by "push ebp")
 [ebp+4] return address from the call (originally at [esp+0])
 [ebp+8] first argument (a)
 [ebp+C] second argument (b)

ebp 是一个地址,同样 esp ia 是一个类似 0x12345678 的地址

esp 不被复制

它被分配所以在 mov ebp, esp 之后
两者都将是相同的地址

在高级语言中,它就像 ebp = esp

现在因为 ebp 是一个地址,它可以保存一个值

即 ebp 可以容纳 0x12345678(ebp ,xxx 是指向底层数据的指针)

所以 ebp = 0x12345678 一个指针指向数据 0x12345678 一个数据变量(比如你的 5 和 1 )

ebp 12345678 持有 1 ebp +4 1234567c 持有 x evp+8 12345680 持有 y

由于 ebp 和 esp 相同,因此 esp+8 也将持有 y

这部分在函数构造中称为序言,并在堆栈中创建一个框架

方括号表示对底层数据的访问

所以如果你想访问 ebp +c 你可能需要

mov somereg ebp add samereg 0xc 现在这个寄存器将保存 0x12345680

如果你想访问 y 怎么办

你需要 ox12345680 周围的方括号

就像让我知道 [0x12345680] 取消引用的内容

那是 mov somereg [ebp + c]