来自this question ,将返回地址推送到特定的堆栈寄存器,这样我们就无法利用堆栈溢出,不是更安全吗?
- 调用者将返回地址(通过
调用
)推送到返回地址堆栈寄存器
。 - 调用者推送参数。
- 被调用者插入本地人。
- 被调用者正在进行一些工作。
- 被调用者清理堆栈。
ret
将返回地址堆栈寄存器
的值弹出到RIP
/EIP
中。
最佳答案
在寄存器中而不是在堆栈中传递返回地址在大多数情况下没有帮助。
大多数 RISC ISA 已经使用链接寄存器来执行此操作,其call
等效项是跳转和链接 (MIPS jal
) 或 ARM bl
)。如果被调用者想要调用子函数,则必须自己将返回地址保存在堆栈上,因为 jal
会破坏链接寄存器。 (因此,它们最终通过将返回地址加载到寄存器并使用跳转到寄存器指令来返回。)
这与 x86 的做法并没有本质上的不同,其中 ret
基本上是直接pop rip
。唯一的区别是叶函数,其中返回地址永远不会进入内存,除非被调用者溢出/重新加载它以获得额外的暂存寄存器。
关于assembly - 我们可以添加并使用返回地址堆栈寄存器来防止堆栈溢出攻击吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50296235/