我最近正在尝试在x64上进行堆栈溢出练习。在x86上执行此操作时,我希望将以下内容用作垃圾覆盖地址(例如'AAAA'):
ret
上,(被覆盖的)返回地址将(有效)弹出到EIP寄存器中在x64中,这似乎有所不同(除了上述步骤中的EIP与RIP交换之外)。当提供“ AAAAAAA”垃圾地址时,处理器似乎在弹出地址时进行了某些有效性检查。通过观察,在加载地址之前,似乎要求地址的两个最高有效字节为空。否则,将发生段故障。我相信这是由于在x64中使用了48位寻址,但是我给人的印象是,以0xFFFF开头的地址也是有效的,但这也会产生段错误。这是区别的准确描述吗?为什么在将数据加载到RIP寄存器之前执行此检查,而之后再执行其他有效性检查?这些说明之间还有其他区别吗?
编辑:为澄清我的见解,我注意到当提供8字节的返回地址时,RIP仍指向ret
指令的地址,而RSP仍指向segfault上被覆盖的返回地址。当提供6字节的返回地址时,观察到段错误时,已覆盖的地址已弹出到RIP中。
我最近正在尝试在x64上进行堆栈溢出练习。在x86上执行此操作时,我希望将以下内容用作垃圾覆盖地址(例如'AAAA'):我提供的数据溢出...
ret
指令试图将RIP设置为非规范地址。