Intel x86-64架构ROP攻击中,仅用movl等指令如何保留寄存器原值?
问题分析与结论
首先咱们先明确你的场景限制:你在ROP攻击中,只能使用movl、andb、orb、cmpb、testb这些指令,不能用movq这类64位传送指令,现在想把%rsp的完整64位值从%rax转移到%rdx——但执行movl %eax, %edx后,%rdx的高32位会被清零,你需要恢复这部分内容。
很遗憾的是,仅用你提供的指令集,无法完成这个目标,原因如下:
movl的局限性:movl是32位传送指令,在x86-64中,当它以64位寄存器的32位子寄存器为目标时,会自动将对应64位寄存器的高32位清零。也就是说,你没办法用movl直接写入%rdx的高32位——任何movl操作到%edx都会把%rdx的高32位抹成0,更别提把%rax的高32位传进去了。- 字节操作指令的不足:
andb、orb只能处理单个字节,而且x86-64的寄存器设计里,%rax的高32位(字节4到字节7)没有对应的8位子寄存器(比如%al、%ah只能访问%rax的低16位)。你没办法用这些字节指令读取%rax的高32位内容,自然也没法把这些字节写到%rdx的高32位位置上。 - 测试指令无修改能力:
cmpb和testb只负责修改标志寄存器(比如ZF、SF),不会改变通用寄存器的值,所以对恢复%rdx的高32位没有任何帮助。
补充:特殊场景的例外
如果你的运行环境中,用户空间的栈地址(%rsp)高32位本身就是0(这在大多数现代x86-64系统中是成立的,因为用户空间地址通常只使用低48位),那movl %eax, %edx后的%rdx其实已经等于%rsp的原始值了——因为高32位本来就是0,清零后也没变化。但这是依赖环境的特殊情况,不是通用解决方案。
内容的提问来源于stack exchange,提问作者Devam Shroff
相关产品推荐
相关产品推荐

