您的位置:首页 > 运维架构

一个简单的反汇编引擎的实现小记

2015-08-23 14:31 197 查看
根据在15PB所学的知识,做了一个简单的反汇编引擎,简记如下:

一、查手册时遇到的问题

1.sib表中的[*]列(手册的Table 2-3):

 在modrm的第一部分为00B时,此列相当于disp32

 否则,此列相当于EBP,代码如下

if (getMod () != 0x0)
{
assert (getMod () == 0x1 ||getMod () == 0x2);
addr->base = getRegName (getBase (), 4);			//normal
}
else
{
if (getBase () != 0x5)
addr->base = getRegName (getBase (), 4);		//normal
else
{
// treat 0x5 as disp32
addr->base = RegName::NONE;
addr->displacement = _reader.getDisplacement (4);
}
}


2.手册中表示操作数大小的字母:

 b:为1字节

 v:有前缀66H时为2字节,否则为4字节

3.存在前缀66H时,有些指令的名称会切换,比如:STOSD和STOSW

4.ESC(从D8H到DFH)不是指令名,其类似于Grp,也需要根据随后的部分来知道其指令名

 

二、解析一条指令的大致流程

1.读取前缀直到不是前缀为止

2.读取Opcode,直到Opcode完整

3.根据手册可知Opcode对应的指令名、操作数个数、每个操作数的类型和大小。

4.解析每个操作数,如果其类型是:

         a 寄存器类型:读取modrm

         b 内存/寄存器类型:读取modrm,再根据modrm来判断是否需要读取sib和偏移

         c 立即数类型:读取立即数

 

三、编码时遇到的问题

   1.类的划分

      ByteReader:读取1、2、4字节的数据

      InstructionReader:读取前缀、modrm、sib等

      Disassembler:对单条指令的解析

   2.保证正确性

      使用测试来保证每次修改代码后,依然能够对指定的Opcode正确解析。

  使用断言来加强对编程思路的表达和检查

四、还需改进的地方

 1.为了编写的方便,代码中throw和assert没有区分,测试表达式时使用了assert,无需测试的用了throw。

 2.没有做性能测试

 3.测试代码写的很乱,还需整理

 4.命名还需改进,比如类名

 5.其他

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  反汇编引擎 opcode