能力值:
( LV6,RANK:90 )
2 楼
学习啊,等这一篇很久啦
能力值:
( LV2,RANK:10 )
3 楼
学习下
能力值:
( LV9,RANK:370 )
4 楼
code的识别好象是最难的了,因为CPU中有几个个code,要对这些code进行识别的确不容易,而且CPU中的code还一直呈现出增长趋势,而且每个code对应不同的操作数个数,这些操作数的寻址方式也各异...... 如果你的"计算机体系结构"知识还没有还给老师的话,你应该知道,CPU在设计时,为了提高比特位的利用率,也为了保证一个code不是另一个code的前缀(否则CPU也无法译码),code的编码采用的是哈夫曼算法。利用这个特性,code及其后继的操作数等信息的识别,应该很容易了吧。 code的最大长度是3个字节,当然可以是1个字节,也可以是2个字节,另外,对于某些特定的code,还有3个比特的信息也会用来表示code.这3比特在ModR/M的3、4和5位。当然每个code也最多只能有三个operand哦。 对code的识别一般都是采用二维表格来驱动的。二维表格中记录了给各code的详细信息。这样code的识别就变成了查表,爽吧。这个表格建的怎么样,取决于你的需求。 下面举一个例子来说明表格的信息,及其code的识别过程(拿call指令为例): 查看Intel官方手册(A-M卷),你会发现call指令有四个code,手册列出分别为: E8 cw call re/16 E8 cd call re/32 F2 /2 call re/m16 F2 /2 call re/m32 F2 /2 call re/m64 9A cd call ptr16:16 9A cp call ptr16:32 FF /3 call m16:16 FF /3 call m16:32 关于它们的详细信息请查看Intel的官方手册,上面所列表明call的code占用一个字节,并且指令只有一个操作数,在手册上详细说明了E8是后面的操作数表示相对于下条指令的偏移,F2、FF和9A后面带的操作数是要调用的绝对地址。 根据code的编码规则以及Intel的手册信息,可以用如下结构体来组织数据: typedef tagCodeInfo { long lMask; //掩码 long lCode; //code int nCodeLen; //code的长度 int nBitFeature; //特殊code标识 int nArg0; //第一个operand的寻址方式,这个地方用enum来定义最好,这里只是为了说明算法,就用int来定义了 int nArg1; //第二个operand的寻址方式,用0表示没有这个operand int nArg2; //第三个operand的寻址方式 std::string strCodeName; //code的助记符 }CodeInfo, *PCodeInfo; 通过上面的结构体定义,可以很容易得到4个call的code对应的结构体数据定义了,如下: { 0x0000FF, 0x0000E8, 1, 0, 1, 0, 0, "call" }, { 0x0038FF, 0x0010FF, 1, 0, 2, 0, 0, "call" }, { 0x0000FF, 0x00009A, 1, 0, 3, 0, 0, "call" }, { 0x0038FF, 0x0018FF, 1, 0, 4, 0, 0, "call" }, 上面4个{}里的第一项和第二项看晕了吧,在说明这个问题时,先说说用这个数据结构是怎么进行code的识别的,设传进来要识别的code为 opCode,那么用这个计算公式可以识别code,(opCode ^ lCode) & lMask,只要这个家伙不为zero,就是我们千辛万苦要找的东东了。这里说下上面opCode的求法,opCode并不是传进来的buffer,因为每个code最多只有三个字节,而我们定义的结构体中用long来表示mask这些信息了,所以我们的opCode也要是long型的,很简单,只要传进来的buffer够长的话,用memcpy((char *)&opCode, buffer, 3),如果不够3个字节了,有几个字节就把几个字节copy到(char *)&opCode处,另外说明的是,repeat prefixes是比较讨厌的,如果有这个东西在带反汇编的机器码中,opCode的求法还要加个opCode = (opCode << 8) | repeat prefixes。 下面说那两个项是怎么计算的了。 mask的计算方法:有指令的地方用FF,如果这个code用到了ModR/M中的那3个比特位,这ModR/M对应字节用38. lCode的计算方法:它对应的code照搬,如果这个code用到了ModR/M中的那3个比特位,/2和/3应该看到了吧,这它们乘以8 放ModR/M对应字节,为什么是8,是因为它ModR/M字节中表示code信息的那3个bits后面还有3个bits. 到这里code就识别完了,通过以上的那个结构体,我们连code对应的每个operand的寻址方式的求出来了,后面那几个域的识别就方便了,没有难度了。
上面的是网络上的关于od用的那个反汇编引擎指令表的构建部分的知识。本打算对已有反汇编引擎的指令表设计方式总结一下的,但是水平实在有限。
目前,正在尽自己最大的努力打造一个“好”反汇编引擎,倒不是为了重新造轮子,只是觉得好玩而已,希望能弄出来。使用的话,目前的反汇编引擎已经很多了,“好”的也不少
。
能力值:
( LV9,RANK:170 )
5 楼
你图中用红圈标识的有误
纵向是高4位,横向是低4位
能力值:
( LV9,RANK:370 )
6 楼
呵呵,犯糊涂了,已经修改了,谢谢!
能力值:
( LV2,RANK:10 )
7 楼
要是写完这些学习报告后,楼主能把OD的反汇编引擎搞个源代码分析就好了
能力值:
(RANK:10 )
8 楼
我还看不懂先收藏!
能力值:
( LV2,RANK:85 )
9 楼
等这一篇很久
能力值:
( LV5,RANK:60 )
10 楼
顶了你 我再慢慢看 啊 哈哈 等你好久了
^_^
能力值:
( LV2,RANK:10 )
11 楼
我建了驱动开发群,群号:67181435
能力值:
( LV3,RANK:20 )
12 楼
大爷能不能总结到一个帖子????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
能力值:
( LV2,RANK:10 )
13 楼
俺还不懂,楼主辛苦了
能力值:
( LV2,RANK:10 )
14 楼
学习了,好东西呀,谢谢楼主
能力值:
( LV9,RANK:150 )
15 楼
从7到8,有一段时间了,呵呵,持续关注中…………
谢谢楼主
能力值:
( LV2,RANK:10 )
16 楼
本人想实现一个linux运行简单dos程序的模拟器,现在只是在头脑中有个大概的想法,首先要有加载模块,然后是命令解释模块,命令解释模块会参考楼主的这个反汇编引擎
,不过后面还有很多问题要考虑,比如中断什么的,不知道大家有什么建议。
能力值:
( LV2,RANK:10 )
17 楼
偶然看到此帖,大有裨益,神作啊
能力值:
( LV2,RANK:10 )
18 楼
拜读完毕,开始整理知识和思路,自己也构建个简单的。
能力值:
( LV2,RANK:10 )
19 楼
看完了,本来还想debug几只虫子的,算了算了...
谢谢楼主,楼主辛苦了...