为一条指令随机选取一个 x86 寄存器

逆向工程 部件 x86 恶意软件 登记
2021-06-22 04:12:49

我遇到了一个正在分析的恶意软件,发现它使用某种数学方法随机选择特定指令的寄存器

我不明白这个操作是如何计算的取决于什么?

这是我的意思的一个例子

假设我想为指令随机选取一个寄存器

ADD DWORD PTR DS:[0],EAX

我们知道这条指令的操作码是 01 05 00 00 00 00

粗体数字代表该指令的寄存器

05 == EAX 0D == ECX

为了更好地解释这一点,这里是所有寄存器的指令

0041580B    0105 00000000   ADD DWORD PTR DS:[0],EAX
00415811    010D 00000000   ADD DWORD PTR DS:[0],ECX
00415817    0115 00000000   ADD DWORD PTR DS:[0],EDX
0041581D    011D 00000000   ADD DWORD PTR DS:[0],EBX
00415823    0125 00000000   ADD DWORD PTR DS:[0],ESP
00415829    012D 00000000   ADD DWORD PTR DS:[0],EBP
0041582F    0135 00000000   ADD DWORD PTR DS:[0],ESI
00415835    013D 00000000   ADD DWORD PTR DS:[0],EDI

恶意软件使用从 0 (EAX) 到 7 (EDI) 的寄存器索引

该数字首先与数字 3 进行 SHLed,然后与 5 进行或运算以获得正确的寄存器操作码。所以我的问题是作者是如何得出这个结论的?

我会说 SHL REG,3 等于 REG*8,即最大寄存器的数量?但是为什么我们需要用 05 来 OR 它呢?是不是因为这条指令的起始操作码是05?

有人对此有更好的解释吗?或任何提示词以更好地理解?

1个回答

为了更好地理解这一点,您需要针对此问题研究指令编码格式,即 x86。

x86 指令看起来像这样

+----------------------+--------+--------+-----+--------------+-----------+
| Instruction prefixes | Opcode | ModR/M | SIB | Displacement | Immediate |
+----------------------+--------+--------+-----+--------------+-----------+
|          0-4         |   1-3  |   0-1  | 0-1 |      0-4     |    0-4    |
+----------------------+--------+--------+-----+--------------+-----------+

第二行的数字表示相应部分的字节长度。

对于指令,

010D 00000000   ADD DWORD PTR DS:[0],ECX

没有指令前缀。的操作码ADD01检查这里

指令 ie 的第二个字节ModR/M0D. ModR/M字节提供有关指令的寻址信息。它指定操作数是在寄存器中还是在内存中;如果它在内存中,则字节中的字段指定要使用的寻址模式。

ModR/M字节可以分解为

+-----+------------+-----+
| Mod | Reg/Opcode | R/M |
+-----+------------+-----+
|  2  |      3     |  3  |
+-----+------------+-----+

这里第二行的数字表示相应部分的位长度。

Mod字段(2个比特)与结合R/M域(3个比特),以形成32个可能的值的8个寄存器和24种寻址模式。

Reg/Opcode字段(3 位)指定一个寄存器编号或另外三位操作码信息;r/m字段(3位)可以指定一个寄存器作为操作数的位置,或者它可以形成在用所述组合编码的寻址模式的一部分Mod字段。

现在,将ModR/Mie转换0D为二进制。你会得到。

+-----+------------+-----+
| Mod | Reg/Opcode | R/M |
+-----+------------+-----+
|  00 |     001    | 101 |
+-----+------------+-----+

ModR/M字段00101分别。这表示仅位移寻址模式。请参阅下表。

在此处输入图片说明

对于所有指令,都使用这种寻址模式,因此 OR使用 5(二进制 101)来设置该特定位模式的原因。

来到Reg/Opcode现场,这表示一个寄存器。
001是 的寄存器索引ECX

对于第一条指令,即
0105 00000000 ADD DWORD PTR DS:[0],EAX
该字段000代表EAX您可以通过转换05为二进制来检查

请参阅从此处获取的下表中的更多信息

在此处输入图片说明

所以基本上寄存器值被SHL编辑为 3 以将其移动到正确的位置。Reg/Opcode 字段位于右侧 3 位。

最后最后 4 个字节是00000000. 这表示在本例中为零的位移。