来自this question,将返回地址推送到特定的堆栈寄存器会不会更安全,这样我们就无法利用堆栈溢出?
call
)推送到return address stack register
。ret
将return address stack register
的值弹出到RIP
/ EIP
。答案 0 :(得分:2)
在寄存器中而不是在堆栈中传递返回地址在大多数情况下都没有帮助。
大多数RISC ISA已使用链接寄存器执行此操作,其call
等效项为跳转链接(MIPS jal
)或ARM bl
)。如果要调用子函数,被调用者必须将返回地址保存在堆栈上,因为jal
会破坏链接寄存器。 (因此,他们最终通过将返回地址加载到寄存器并使用跳转到寄存器指令来返回。)
这与x86没有根本的不同,其中ret
基本上是pop rip
。唯一的区别是叶子函数,其中返回地址永远不会进入内存,除非被调用者溢出/重新加载它以获得额外的临时寄存器。