反汇编显示带有 RIP 的“LEA”?

逆向工程 部件 x86 雷达2
2021-06-22 09:46:27

当我使用拆卸该指令pad对Radare我得到一个LEArip

[0x00000000]> pad 8d 15 c8 90 04 08
lea edx, [rip + 0x80490c8]

我从这篇文章中得到了这条指令here我很困惑为什么反汇编显示rip + 0x80490c8,当原始帖子声称它相当于mov? 这是正确的反汇编输出吗?为什么指令指针会在LEA? 这是一个隐含的基础,还是原始海报弄错了?

2个回答

这只是位的问题。在所示示例中,十六进制对是使用 64 位程序集反汇编的,您可能希望将其更改为 32 位程序集。只需告诉radare您正在使用32位,它就会为您完成工作:

[0x00000000]> pad 8d 15 c8 90 04 08
lea edx, [rip + 0x80490c8]

[0x00000000]> e asm.bits =32

[0x00000000]> pad 8d 15 c8 90 04 08
lea edx, [0x80490c8]

与被视为绝对地址(使用 32 位立即偏移寻址)的 32 位模式指令不同,64 位模式(又名长模式)通常使用从当前 RIP 开始的 32 位偏移,而不是像以前那样从 0x00000000 开始。这意味着你不必知道你想要引用的东西的绝对地址,你只需要知道它离当前正在执行的指令有多远。

很少有寻址模式使用完整的 64 位绝对地址。大多数寻址模式是相对于 64 位寄存器之一(通常是 RIP)的 32 位偏移。

32 位 x86 有 2 种冗余编码方式[disp32](没有寄存器):有和没有 SIB 字节。汇编程序当然会始终使用较短的形式,这就是您问题中的链接所显示的内容。

您正在反汇编为 64 位机器代码。

x86-64 将没有-SIB 的版本重新用于表示[RIP + rel32],让更长的有[sign_extended_disp32]-SIB版本仍然意味着当您使用带有 GP 寄存器的 disp32 时。(RIP-relative 不能与任何 GP 寄存器结合使用;只有这一种特定的 ModR/M 编码。)

在 NASM 语法中,[rel foo]vs [abs foo]. 或使用default rel.


AFAIK,lea r32, [disp32]而不是对mov r32, imm32我所知道的任何 CPU 上的性能都没有用,除了故意使指令更长而不是用 NOP 填充

lea静态地址的唯一用例是使用 RIP 相对 LEA 的 64 位代码。

有关 LEA 的更多信息,请参阅此规范答案,但实际上这个问题与 LEA 无关,并且会发生在任何使用以disp32错误模式解码ModR/M 寻址模式的指令中 您之所以遇到此问题,是因为您发现了一个示例,该示例将在 32 位模式下使用低效lea与高效mov-immediate 进行比较。