【问题标题】:Does function stack save the return address?函数堆栈是否保存返回地址?
【发布时间】:2017-12-19 16:49:58
【问题描述】:

我正在使用 Linux x86 系统学习基于汇编的函数堆栈。

我读过一些文章,它告诉我函数堆栈(被调用者)会保存调用者调用它的返回地址,以便计算机可以知道函数返回时要继续的点。

这就是为什么会有一种攻击:堆栈粉碎。 栈粉碎是指如果我们可以溢出一个函数栈,特别是溢出一个设计好的返回地址,程序就会执行黑客的代码。

但是,今天我尝试使用 gdb 来检查一个简单的 c++ 程序,如下所示,但我在任何函数堆栈中都找不到任何保存的返回地址。 代码如下:

void func(int x)
{
    int a = x;
    int b = 0;  // set a breakpoint
}

int main()
{
    func(10);  // set a breakpoint
    return 0;
}

然后我使用 gdb 来获取它的程序集:

main:

func:

现在我们可以看到两个函数栈中都没有保存返回地址(至少这是我的看法)。

如果一个黑客想通过堆栈粉碎来破解这个程序,他会在函数堆栈中的哪个地址被他非法编辑?

【问题讨论】:

  • 在 x86 架构上,call 指令将返回地址放入堆栈。在其他架构上,等效指令可能会将其放入寄存器中,然后被调用者可以在必要时将其保存在堆栈中。
  • @Jester "call 指令将返回地址放入堆栈" --- 是否可以在两张图片中看到这一点?我只是想看看像0x00001234这样的真实地址。
  • 不,值在堆栈上。你可以看到它,例如通过在callq 之后执行x/a $rsp(即在func 的入口处,地址0x400687)。
  • 但是您的屏幕截图根本没有显示堆栈的内容。你到底想通过这些来证明什么?为什么要查看代码而不是查看堆栈?
  • Jester 写的内容加上检查 rspcall 之前/之后的值(我猜是在 gdb 中的“print $rsp”?),看看它是如何做到的 rsp-=8(与push rax 会改变它)。 “堆栈”内存就像任何其他常规内存一样,rsp 几乎就像任何其他寄存器一样,所有“堆栈”魔法只是 push/pop/call/ret/leave/enter/.. 指令使用 rsp 值作为指向内存的指针隐式。 IE。 push rax 几乎等于 sub rsp,8 mov [rsp],rax,它只是更原子,并且不影响标志。 (和“堆栈粉碎”= 更改 rsp 地址周围的内存内容)。

标签: c++ assembly x86-64


【解决方案1】:

是的,有。检查callq 之前和之后的堆栈。你会发现callq之后的指令地址现在出现在栈顶,RSP减8了。

callq 指令导致下一条指令的地址被压入堆栈。反之,函数末尾的retq指令会导致堆栈上的地址被弹出到RIP中。

【讨论】:

  • 你的意思是RSP8 :)
  • 你能告诉我应该注意图片中的哪些指令行吗?
  • @Yves : CALL 指令将返回地址放在栈顶。
  • @jester 绝对:)。这周我进入了 32 位世界。
【解决方案2】:

现在我们可以看到两个函数栈中都没有保存返回地址(至少这是我的看法)。

您实际显示的是反汇编代码,而不是堆栈。

调用者通过callq 指令将返回地址压入堆栈。在进入 callee 函数的那一刻,它位于堆栈的顶部,即:此时,rsp 包含存储 返回地址 的地址。


使用 GDB 检查堆栈

  • p/x $rsp显示rsp寄存器的值,即:栈顶的地址,因为rsp指向栈顶。

  • x/x $rsp显示位于栈顶的内存内容(即:位于rsp指向的地址的内容)。

记住这些信息,您可以在进入被调用函数时(在其他任何东西被压入堆栈之前)运行命令x/x $rsp 以获得返回地址。

您还可以使用命令info frame 来检查当前的堆栈帧。名称为saved rip 的显示字段对应于当前函数的返回地址。但是,您需要在当前函数的堆栈帧创建之后和销毁之前运行此命令(即:在被调用者内部 mov %rsp,%rbp 之后但在 pop %rbp 之前)。

【讨论】:

  • 对不起,我是这方面的新手。我只是使用 gdb 的命令:disassemble 来获取屏幕截图。那么如果我想展示堆栈,我该怎么做呢?
猜你喜欢
  • 2017-02-24
  • 2014-04-21
  • 2016-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-26
相关资源
最近更新 更多