硬编码逆向分析——手动解析指令

发布时间 2023-04-17 10:56:33作者: bonelee

手动解析指令

现在有一个指令为:0x88 0x01,用如上那张表和我们所学的ModR/M的知识对该指令进行一步步解析。

首先我们知道第一个字节是0x88,再根据官方文档知道其有Gx或Ex这样的参数,那就表示它有ModR/M这个字节,也就表示它是一个变长指令,所以Opcode和ModR/M如下所示:

Opcode

ModR/M

0x88 - MOV Eb, Gb

0x01

接着我们要拆分ModR/M为三个部分,先将其转为2进制:0000 0001,然后拆分:

Mod

Reg/Opcode

R/M

0

0

0

0

0

0

0

1

接着我们对照着表来进行解析就得出了汇编代码:MOV BYTE PTR DS:[ECX], AL

images/download/attachments/21791281/image2021-11-1_22-9-1.png

Reg/Opcode

之前我们了解到ModR/M结构可以拆分为三部分,其中Reg/Opcode的描述了G的意义(通用寄存器),但其并不仅仅用来表示寄存器,有时候也可以用来表示Opcode。

在官方文档的Table A-2中,有0x80、0x81、0x82、0x83这几个编码没有给出具体的指令,我们可以看见在原来指令的位置变成了Immediate Grp 1(1A):

images/download/attachments/21791281/image2021-11-1_22-18-27.png

首先这个1A我们可以查文档的Table A-1中有描述:

images/download/attachments/21791281/image2021-11-1_22-40-34.png

其表示在ModR/M字节的3、4、5位可以作为Opcode的拓宽,也就可以认为其不用来表示通用寄存器了。

而当你看见Immediate Grp的时候就需要带入ModR/M字节的3、4、5位去看Table A-6这张表的内容,才能知道具体的指令是什么:

images/download/attachments/21791281/image2021-11-1_22-42-31.png

手动解析指令

现在有一个指令为:0x80 0x65 0x08 0xFF,用如上那张表和我们所学的ModR/M的知识对该指令进行一步步解析。

首先我们知道第一个字节是0x80,再根据官方文档知道其有Gx或Ex这样的参数,那就表示它有ModR/M这个字节,也就表示它是一个变长指令,所以Opcode和ModR/M如下所示:

Opcode

ModR/M

0x80 - XXX Eb, Ib

0x65

接着我们要拆分ModR/M为三个部分,先将其转为2进制:0110 0101,然后拆分:

Mod

Reg/Opcode

R/M

0

1

1

0

0

1

0

1

Mod与R/M字段查Table 2-2得到对应的结构:[EBP+DIS8(8位偏移量)],Reg/Opcode字段根据上文所示那张表就可以得到对应的指令为:AND。

所以最终我们变成了这样的指令:AND [EBP+DIS8], Ib,再带入最后的两个字节(这也是最开始我们了解硬编码结构中的最后2部分)替换DIS8和Ib变成:AND BYTE PTR SS:[EBP+0x08], 0xFF

SIB

根据之前的了解我们可以知道ModR/M字段是用来进行内存寻址的,可当地址形如DS:[EAX + ECX*2 + 12345678]时,仅仅靠ModR/M字段,是描述不出来的,这时就在ModR/M后面增加一个SIB字节,其与ModR/M字段共同描述。

当你手动解析某一个指令的时候发现出现如下这三种情况,有“[--]”的存在就表示ModR/M字段无法描述出来这段地址,你就需要SIB字节来填充这些“[--]”,也就表示在ModR/M字段之后一定存在SIB。

Effetive Address

Mod

R/M

[--][--]

00

100

[--][--]+disp8

01

100

[--][--]+disp32

10

100

SIB字节的8个位被分成了三部分:

images/download/attachments/21791281/image2021-11-1_23-3-58.png

在例子 DS:[EAX + ECX*2 + 12345678] 中,Scale描述2的1次方,Index描述ECX, Base描述EAX,而12345678由ModR/M字段决定,所以SIB字段的描述方式为:

Base + Index * 2的Scale次方 (只能为 *1 *2 *4 *8)

而你要想查询三部分每个对应着什么内容就要去查看Table 2-3:

images/download/attachments/21791281/image2021-11-1_23-14-2.png

手动解析指令

现在有一个指令为:0x88 0x84 0x48,其对应的Opcode、ModR/M、SIB如下:

Opcode

ModR/M

SIB

0x88 - MOV Eb, Gb

0x84

0x48

ModR/M转为二进制:1000 0100,拆分如下:

Mod

Reg/Opcode

R/M

1

0

0

0

0

1

0

0

Mod与R/M字段查Table 2-2得到对应的结构:[--][--]+disp32,这就表示需要SIB来进行补充。

SIP转为二进制:0100 1000,拆分如下:

Scale

Index

Base

0

1

0

0

1

0

0

0

接着查Table 2-3,Base对应着EAX,Base和Index就是[ECX*2],最终得到[EAX + ECX*2]。

最终指令就是:MOV [EAX + ECX * 2 + disp32], AL