因此,在反转 x64 二进制文件后,我在函数的开头发现了这个序列:
mov [rsp+8], rbx
mov [rsp+0x10], rbp
mov [rsp+0x18], rsi
push rdi
现在我从来没有真正在汇编中完成过这个(我只在 x86 上有经验)。对我来说,这只是局部变量初始化。
知道为什么会有函数序言这样的代码吗?
最佳答案
使用shadow space似乎是合理的(返回地址上方 32 个字节)为 saving some of the call-preserved registers ,而不是使用更多的堆栈空间来将它们全部推送。如果没有这个,您只需推送您想要使用的任何调用保留的寄存器(这样您就可以稍后恢复它们)。在这里,我猜想它们是通过在 ret
之前用 mov
重新加载它们来恢复的,而不是 pop
。
(在 Windows x64 中,RDI 和 RSI 是调用保留寄存器,与 x86-64 System V 不同,它们是调用破坏的参数传递寄存器。)
特别是如果它通过允许奇数次总推送来使堆栈对齐效果很好,并且没有 sub rsp, n
来保留更多堆栈空间。 (这可能就是它推送 RDI 而不是将其保存到 [rsp + 0x20]
的原因。)
关于windows - x64 mov 而不是推送序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67251826/