dex2jar这个源码包,听名字是用来将dex文件转换为java文件,在githup上面的地址是https://github.com/pxb1988/dex2jar

但我们分析这个源码可以看到,里面的功能不只是将dex转换为jar包,也可以转换dex为smail文件等,这个后面在分析

dex2jar就是将dex文件转换为class文件,然后class文件打成jar包

dex转换为class文件过程中会先转换为一种IR的中间指令格式

dex2jar源码解析之总体介绍(一)_指令格式

大概的转换流程是上面这样子的


中间主要 调用的函数接口如下

dex2jar源码解析之总体介绍(一)_bakSmali_02

上面的是相应的Visitor访问者,具体的处理都是调用里面的visitor相关的函数进行处理

然后看看主要的类图

dex2jar源码解析之总体介绍(一)_指令格式_03

DexFileReader开始从dex文件中读取内容,并调用里面的相应的函数处理读取到的数据,如acceptClass会解析一个类等

dex2jar源码解析之总体介绍(一)_指令格式_04

这里的话主要是一个Visitor相关的类关系图

dex2jar源码解析之总体介绍(一)_bakSmali_05

Dalvik指令格式

一段Dalvik汇编代码由一系列Dalvik指令组成,指令语法由指令的位描述与指令格式标识来决定。位描述约定如下

Dalvik指令对语法做了一些说明,它约定如下:

● 每条指令从操作码开始,后面紧跟参数,参数个数不定,每个参数之间采用逗号分开。

● 每条指令的参数从指令第一部分开始,op位于低8位,高8位可以是一个8位的参数,也可以是两个4位的参数,还可以为空,如果指令超过16位,则后面部分一次作为参数

● 如果参数采用 “vX” 的方式表示,表示它是一个寄存器,如v0、v1等。这里采用v而不用r是为了避免与基于该虚拟机架构本身的寄存器名字产生冲突,如ARM架构寄存器命名采用r开头。

● 如果参数采用 “#+X” 的方式表示,表明它是一个常量数字。

● 如果参数采用 “+X” 的方式表示,表明它是一个相对指令的地址偏移。

● 如果参数采用 “kind@X” 的方式表示,表明它是一个常量池的索引值。其中kind表示常量池类型,它可以是 “string” 字符串常量池索引)、“type”(类型常量池索引)、“field”(字段常量池索引)或者 “meth”(方法常量池索引)。● 每16位的字采用空格分隔开来。

● 每个字母表示4位,每个字母按顺序从高字节开始,排列到低字节。每4位之间可能使用竖线 “|” 来表示不同的内容。

● 顺序采用 A ~ Z 的单个大写字幕作为一个4位的操作码,op表示一个8位的操作码。

● “Φ” 来表示这字段所有位为0值。

以指令格式 “A|G|op BBBB F|E|D|C” 为例

指令中间有两个空格,每个分开的部分大小为16位,所以这条指令由三个16位的字组成。

第一个16位是 “A|G|op”,高8位由A与G组成,低字节由操作码op组成。

第二个16位由 BBBB 组成,它表示一个16位的偏移值。

第三个16位分别由F、E、D、C 共4个4字节组成,在这里他们表示寄存器参数。



单独使用位表示还无法确定一条指令,必须通过指令格式标识来指定格式的格式编码。它的约定如下:

● 指令格式标识大多由三个字符组成,前两个是数字,最后一个是字母。

● 第一个数字是表示指令有多少个16位的字组成。

● 第二个数字是表示指令最多使用寄存器的个数。特殊标记 “r” 标识使用一定范围内的寄存器。

● 第三个字母为类型码,表示指令用到的额外数据的类型。取值见如下表。

助记符 位大小 说 明

b 8 8位有符号立即数

c 16,32 常量池索引

f 16 接口常量(仅对静态链接格式有效)

h 16 有符号立即数(32位或64位数的高值位,低值位为0)

i 32 立即数,有符号整数或32位浮点数

l 64 立即数,有符号整数或64位双精度浮点数

m 16 方法常量(仅对静态链接格式有效)

n 4 4位的立即数

s 16 短整型立即数

t 8, 16, 32 跳转,分支

x 0 无额外数据

以指令格式标识22x 为例:

第一个数字2表示有2个16位字组成,第二个数字2表示指令使用到2个寄存器,第三个字母x表示没有使用到额外的数据。

dex2jar源码解析之总体介绍(一)_源码解析_06

这里是dex转ir用到的相关的一个类

dex2jar源码解析之总体介绍(一)_Dex2Smali_07

这是转换的指令,解析dex文件中的相应指令 转换为这里的一个中间指令

dex2jar源码解析之总体介绍(一)_Dex2Smali_08

这里是中间指令 转为jvm中的指令,里面都有accept方法

dex2jar源码解析之总体介绍(一)_源码解析_09

这里用来把解析的dex转换,用到Asm

dex2jar源码解析之总体介绍(一)_Dex2Jar_10

这里是dex文件解析之后转换为中间指令IR文件用到的visitor,前面的visitor是访问dex文件的。

大概的类就上面这么多,画这个图主要是了解各个类之间的关系,要不然后面会有点糊涂。