我不了解该操作的计算方式取决于
这是我的意思的一个例子
让我说我想为指令随机选择一个寄存器
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进行OR运算,以获取正确的寄存器操作码。那么我的问题是作者是如何得出结论的呢?
我要说SHL REG,3等于REG * 8,即最大寄存器数吗?但是为什么我们需要与05进行“或”运算呢?是因为该指令的起始操作码是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
没有指令前缀。
ADD
的操作码是01
(在此处检查)指令的第二个字节,即
ModR/M
是0D
。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/M
,即0D
为二进制。您将得到。+-----+------------+-----+
| Mod | Reg/Opcode | R/M |
+-----+------------+-----+
| 00 | 001 | 101 |
+-----+------------+-----+
Mod
和R/M
字段分别是00
和101
。这表示仅位移寻址模式。请参见下表。对于所有指令,均使用该寻址方式,因此
OR
设置为5(二进制101)的原因是为了设置该特定地址。位模式。进入
Reg/Opcode
字段,它表示一个寄存器。 001
是ECX
的寄存器索引。 对于第一个指令,即
0105 00000000 ADD DWORD PTR DS:[0],EAX
,该字段为
000
代表EAX
。您可以通过将05
转换为二进制来进行检查。请参见从此处获取的下表中的更多内容。
所以基本上寄存器值是用3将其移动到正确的位置。 Reg / Opcode字段从右边起3位。最后最后4个字节是
SHL
。在此示例中,这表示位移为零。