卡在 x87 FLD 指令中

逆向工程 拆卸 转储 amd64
2021-06-24 21:37:27

我一直在为我的最终项目工作,这是一个 AMD64 指令集的反汇编程序,我试图手动反汇编机器代码以正确理解它。但是我被 x87 指令卡住了。

指令的机器码为: dd 04 c5 60 40 08 08...

我已经检查了 AMD64 手册 vol3,它说 DD 是一条 x87 指令,并且在 ModRM 字节的帮助下,即0b00000100我的 ModRM.reg 字段是,000并且在此信息手册中,该说明的含义是“FLD mem64real”。但是因为我已经为 i386 目标架构编译了这段代码,所以我认为我不应该有 64 位内存地址。

但最有趣的部分是当我用 objdump 检查二进制文件时,它说这个字节对应,fldl 0x8084060(,%eax,8)但我找不到任何关于 FLDL 指令的信息,也找不到 objdump 是如何找到的。

所以我的问题是我做错了什么吗?

objdump 如何认为指令是 FLDL 但手册说它的 FLD ?

二进制的目标机器是 i386。

我使用 AMD64 手册第 3 卷查看说明

objdump 的版本是 GNU objdump (GNU Binutils for Debian) 2.26.1

这是二进制的 readelf 输出

ELF Header
Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
Class:                             ELF32
Data:                              2's complement, little endian
Version:                           1 (current)
OS/ABI:                            UNIX - System V
ABI Version:                       0
Type:                              EXEC (Executable file)
Machine:                           Intel 80386
Version:                           0x1
Entry point address:               0x80482c0
Start of program headers:          52 (bytes into file)
Start of section headers:          3744 (bytes into file)
Flags:                             0x0
Size of this header:               52 (bytes)
Size of program headers:           32 (bytes)
Number of program headers:         8
Size of section headers:           40 (bytes)
Number of section headers:         31
Section header string table index: 28
2个回答

所以这个答案只关注@Efe的第二个问题:如何+eax*8构造。

您可以通过以下步骤确定 SIB 偏移量。我们分析04 c5整个指令的前两个字节

dd 04 c5 60 40 08 08

首先,我们只关注MOD-REG-R/M Byte(详情请看这里

MOD-REG-R/M Byte = 04
--------------------------------------------------
04   0000 0100
MOD  00          Meaning: SIB with no displacement
REG  000         Meaning: eax (32-Bit)
R/M  100         Meaning: SIB with no displacement

其次,我们分析指令的SIB Byte(详情请看这里)。Scaled indexed 寻址模式使用MOD-REG-R/M 之后的第二个字节(即SIB 字节)。

SIB Byte = C5
--------------------------------------------------
c5    1100 0101
Scale 11    Meaning: Index*8
Index 000   Meaning: eax register
Base  101   Meaning: Displacement only

MOD 和 Base 的组合导致(查看此处了解详细信息)

MOD = 00 and BASE field = 101:
--------------------------------------------------
disp + eax*n

fldl只是涉及长(4 字节)寄存器的“FLD”指令AT&T 语法这相当于

fld     qword ptr [eax*8 + 8084060h]

在英特尔语法中。

您可以指示 objdump使用该-M intel标志发出 Intel 语法


虽然 i386 不支持 64 位地址,但它确实可以在给定地址的情况下读取 64 位。“FLD m64fp”指令从输入地址(0x8084060 + eax*8在本例中)读取 8 个字节,将其解释为浮点数 (a double),然后将其压入 FPU 寄存器堆栈。

在这种情况下0x8084060,可能是全局数组的地址,double并且eax是从数组中获取值的索引。