引
Dalvik 字节码格式的官方说明:(相关网站不一定能打开,我直接放网盘了)
链接: https://pan.baidu.com/s/1bq27bbx 密码: pirc
之前有介绍过指令字节码如何反编译的,参考文章最后部分:
用python一步步解剖dex文件(二)https://www.jianshu.com/p/f8e1c80b913a
每段指令字节码的第一个字节就是指令码,指令码的范围在[0x00 - 0xff],就是256个以内。
每个指令码都对应一个格式解析说明,该说明详细指出了该段字节指令码占用了几个字节,使用几个寄存器,以及如何读取的。
以这个指令格式说明为基础,我设计了反汇编框架,代码地址:
https://github.com/callmejacob/dexfactory/tree/master/disassemble
指令字节数组的最小单位解析
指令字节数组的最小单位,只有一个指令码,后面跟着对应的指令数据。
以'4rcc'指令格式为例子,它的格式说明如下:
4rcc格式说明
它占用了4 * 2 = 8个字节,这8个字节可以按照最左侧的格式进行分解,得到AA, BB, CCCC, HHHH,继而算出 NNNN = CCCC + AA - 1。
反编译出来的代码如下:
op> , meth@BBBB, proto@HHHH
其中op就是字节码; CCCC, NNNN, BBBB,HHHH是解析或者计算好的数值。
而meth是一种kind类型,表示一种常量池的索引,而且每个指令码对应的kind类型可能不一样(后面有详细说明)。
最后的proto是固定的,表示proto类型的常量池。
我们把这个反编译出来的用格式化表示:
总格式: '%s> , %s, %s' % (op_map[op], CCCC, NNNN, '%s', '%s')
最后两个为什么用%s呢? 因为也把kind类型的和proto类型的做格式化处理,最后合并到上面的总格式中。
这两个格式都用下述格式表示:
kind格式: '%s@%.4x'
它的第一个参数是kind类型,第二个就是kind类型的数值,比如
meth@0003
代表method常量池的第3个子项。
我们用代码实现如下:
解析过程
上面的desc就是我们说的总格式,而kind_x, proto_x都是用来形成kind格式的数值。
如果我们拼接好kind格式之后,使用下面的方法汇总到总格式:
总格式拼接
打印方法:
打印方法
上面的例子中,'4rcc'格式比较有代表性,它包含了[op, 变量,kind, proto]四个重要的信息。
下面我们介绍通用的解码过程(decode)。
decode会根据指令码和对应的说明格式进行一一解析,这需要建立一些指令码类型的映射集合,详细如下。
指令码集合(片段):
指令码集合
常量池类型定义(kind):
常量池类型定义
指令码对应的kind类型映射(片段):
指令码和kind的映射
指令码到解释格式的映射集合(片段):
指令码到解释格式的映射
利用op_map可以获取到指令码描述;
利用format_map可以获取到指令码说明格式,并根据该格式进行变量解析;
利用kind_map可以获取到拼接kind格式的类型。
最后,根据上述信息,汇总到总格式字符串中。
这样,一个最小单位的指令字节码就解析完成了。
我们将上述方法都封装到类InsnsItem中,它能够解析一个最基本的指令字节码,并且能够打印出来相关的反汇编代码。
代码片段如下:
类InsnsItem
指令字节码全段解析
指令字节数组可以分解为若干个最小单位的指令字节码,形成一个item_list。
指令字节数组全解码
其中的InsnsItem中的kind格式信息,还是最原始的,比如meth@0003。
为了获取它实际信息,我们定义一个kind到对应section信息的一个映射和获取方法:
kind到section的映射信息
在上述映射的基础上,我们可以把item信息转换成真实的反汇编信息。
打印过程:
指令字节码反汇编打印
其中的context,就是包含section信息的上下文,通过它我们把kind和proto两个格式字符串格式化,获取到kind_desc和proto_desc(它们包含了真实信息),最终再填充到总格式化字符串中。
最后我们把这两个过程封装到类Insns中,它以指令字节数组为参数,可以反编译出对应的指令代码。
反汇编和Dex解析框架
我们把这个反汇编框架和之前的dex格式解析框架结合起来。
先在Context类中,定义一个变量来代表反编译类的class,并提供设置方法。
context的insns类
然后在code_item段中,对于解析出来的每段insns字节码数组进行反汇编:
字节码反汇编
反汇编测试
测试代码
其中"#反汇编"这段不是必要的,因为后面反汇编类挂接到context中后,也能够直接反汇编解析,这里是为了测试。
这段的打印结果如下: (格式是字节码数组和反汇编解释)
反汇编测试
使用反汇编的类信息打印如下:
带反汇编信息的类信息
待续
领取专属 10元无门槛券
私享最新 技术干货