objdump 的(坏)操作码

逆向工程 拆卸 聚乙烯 转储 漂浮
2021-06-20 23:19:02

我正在尝试为 PE、PE+ 和 ELF 可执行文件编写自己的反汇编程序,但我在 PE 和 PE+ 可执行文件上遇到了一个大问题。

我正在通过将我的输出与 objdump 进行比较来检查我的工作,我发现反汇编程序中出现了一些(坏的)操作码。我立即查看了使用说明书来控制这些值;它们在使用说明书中显示为无效。一些例子:

来自 PE 文件的示例:

40dad1:       d6                      (bad)

其他:

402f1c:       ff                      (bad)
402f1d:       ff                      (bad)
402f1e:       ff                      (bad)
402f1f:       ff 01                   incl   (%ecx) #at last a valid instruction

当我查看手册时这些是有效的,但我无法理解这一点(它是一个 PE+ 文件,架构是 AMD64):

f0 db a5 4e 9c 95 68    lock (bad) [rbp+0x68959c4e]

f0 is lock prefix
db means its a x87 instruction
a5 is ModRM byte(10 100 101) and by looking mod and reg fields we can say it's an invalid instruction
4e 9c 95 68 is used as 4byte disp but why ?

我们是否假设它是一个无效的间接 x87 操作码并且我们继续阅读它作为一个有效的操作码?我想 objdump 选择了这条路。

这些(坏)指令是做什么用的?很明显,它们不是为了对齐;还是我做错了什么?

顺便说一句,我正在尝试反汇编我的旧项目和 FireFox 以检查我的程序是否有效。我是objdump -z -d -M intel XXYYZZ.exe用来拆机的。

1个回答

你是objdump对的,反汇编这样的指令实际上是错误的,只是将其标记为(bad)后期。

下面是它的工作原理:

db a5 4e 9c 95 68    lock (bad) [rbp+0x68959c4e]

db是 87 个 FPU 扩展之一,a5确实是 Mod/rm 字节。现在,对于 FPU 扩展,rm 部分对于所有其他 mod/rm 指令“照常”,但 mod 部分指示使用哪个指令,从这个小表中:

DB /0     FILD mem4i
DB /2     FIST mem4i
DB /3     FISTP mem4i
DB /5     FLD mem10r
DB /7     FSTP mem10r

其中/x数字表示在 mod/rm 字节的 mod 部分中编码的内容(为了完整性:db eX也形成了一些有效的操作码)。

因此,所有可用的代码,那些具有的MOD / RM模式..001.....100..并且..110...形式“坏”的代码-但你只知道这个之后解析MOD / RM字节,并检查该特定表的操作码DB

现在显然 objdump检查基本指令是否有效开始之前解析整个指令 - 包括 4 字节立即数我想这只是一张表,上面写着

"fild", "(bad)", "fist", "fistp", "(bad)", "fld", "(bad)", "fstp"

并且(bad)条目被使用,就好像它们实际上是有效的一样。

有人可能会争辩说这无关紧要,因为这两种方式都会得出操作码为“坏”的结论,但是使用 objdump 的方法,您不仅将第一个字节丢弃为“坏”,而且还丢弃了整个 6 个字节。它是至少在理论上可能的第一个字节(它导致整个下一个序列是无效的)是数据,但随后立即通过正确的代码,其然后将与序列开始a5 4e 9c 95 68-这是由完全objdump的跳过。

.. 这些(坏)指令是做什么用的?

我想,看看你展示的其他指令,你正在反汇编可执行文件的错误部分,这根本不应该是代码,而是数据。

您应该检查 PE/PE++ 标头以找到部分,然后仅尝试对在其Characteristics字段中标记为“代码”和/或“可执行文件”的部分进行反汇编即便如此,也有可能从“错误”位置(例如,在较长指令的中间)或内部数据(也可能位于某个.code部分内)开始。