You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

x64架构调用函数时RSP未必需16字节对齐?技术求证

x64架构函数调用的RSP对齐误区解析

测试现象回顾

  • 针对callme程序的ROP payload中添加ret指令(意图对齐栈指针):进入system函数时RSP未按16字节对齐,但代码正常执行;
  • payload中不添加ret指令:进入system函数时RSP是16字节对齐,却在do_system函数中因movaps指令触发段错误崩溃。

核心结论:x64调用规范仍要求调用者保证RSP对齐

x64 System V调用规范明确规定:调用者在执行call指令前,必须确保RSP是16字节对齐的。因为call指令会将8字节的返回地址压入栈中,所以被调用函数入口处的RSP会是原RSP-8(即8字节偏移的未对齐状态)。正规实现的函数会在入口处通过sub rsp, 8之类的指令恢复16字节对齐,再执行后续操作。

反常现象的原因拆解

  1. 加ret后未对齐却正常运行
    ret指令会弹出栈上8字节的返回地址到RIP,相当于RSP增加8。此时执行call system前的RSP处于未对齐状态,进入system时RSP虽未对齐,但system函数内部在使用movaps这类要求对齐的指令前,已经主动调整了栈指针(比如额外执行sub rsp, 16),兼容了入口处的未对齐状态,因此代码能正常运行。

  2. 不加ret时对齐却崩溃
    进入system时RSP是16字节对齐的,但system内部调用do_system时,call do_system会将8字节返回地址压栈,导致do_system入口处的RSP变为对齐RSP-8(即未对齐状态)。而do_system的实现中没有额外处理栈对齐,直接使用movaps访问栈上的未对齐内存,触发了段错误。

总结

x64的调用规范并没有失效,只是不同函数的内部实现对栈对齐的处理方式不同:有些函数会兼容入口处的未对齐状态,有些则严格依赖调用者提前做好对齐。你遇到的反常识现象,本质是不同函数栈对齐处理逻辑差异导致的。

内容的提问来源于stack exchange,提问作者talsim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 13:57:29