反汇编引擎实现——流程分析

目录

         指令格式及操作数解析归类

         对于不同类别如何处理

         MOD=0

         MOD=1/2/3

         SIB解析

         前缀解析

         关于ESP和EBP为什么被用来特殊寻址


指令格式及操作数解析归类

  指令格式一般是按照intel给出的指令格式作为基础,然后再扩充一些反编译过程中会用到的元素,诸如源和目的操作数的顺序,反编译时候的地址等信息。

  至于操作数类别,还是按照intel手册上的分类来的,诸如E、G、I等种类。对于不同种类需要做不同的处理。

图1指令格式及操作数解析归类

  至于右上角那个数组,是为了方便编程。因为最后要用汇编语言来表示结果,恰好各个寄存器也是顺序编号的,就用数组来索引了。


对于不同类别如何处理

 

图2 对于不同类别如何处理1

 

图3 对于不同类别如何处理2

对于不同的操作数类别做不同的处理,流程图中应该很详细了。

如果有的操作数需要MODR/M和SIB域该怎么处理呢?像E这个类别


MOD=0

 

图4 MOD=0如何处理

  根据是否有前缀做分类处理

  根据R/M的值做分类,比较特殊的是R/M==4和R/M==5的,也就是轮到esp和ebp了,要搞特殊化了。后面会说原因的。


MOD=1/2/3

 

图5 MOD=1/2/3如何处理

  还是根据前缀是否存在和R/M的特殊值来做处理。比较奇怪的是R/M==5,也就是ebp这个时候倒正常了。


SIB解析

 

图6 SIB解析

  可以看到SIB的处理里面特殊的情况比较多,只能一条条慢慢实现了。


前缀解析

图7 前缀解析

  前缀的处理出要要关注两点,一个是前缀不可能无限多,第二个就是要处理重复的前缀。像右下角的例子,group1出现了两次,那么重复的前缀及其之前的前缀都无效了。


关于ESP和EBP为什么被用来特殊寻址

 

图8 关于ESP和EBP为什么被用来特殊寻址

  这个是我在邓志的个人主站上找到答案的。非常感谢。膜拜大神。

  对ebp做的特殊处理就是ebp不能单独以[ebp]形式参与寻址,要么用立即数取代,要么用[ebp+disp]形式。

  而关于esp做的特殊处理,我想完全是因为找不到合适的寄存器了,才让[esp]这种形式承担SIB的义务。但是[esp]这种形式承担了SIB的义务,那么编译器就想用[esp]这种形式怎么办,你说不给我[ebp]这种形式,是因为他是基址寄存器,不让单独用,我接受这个理由了。难道[esp]你还来一个规定吗?intel没有做特殊规定,为了表示出[esp]这种形式,让index==4(即ESP)时,scale*index=0,这样base==4(ESP)时候,就存在[esp]这样的形式了。


比较low的opcode map表

 

图9 opcode_map表

  其实上面说了那么多,就是为了这一张表,按照intel的map表转化为自己的程序能识别的格式,我这个比较low,完全是照着intel的表格抄了一份。

原文地址:https://www.cnblogs.com/shangye/p/6183597.html