前言
通过阅读8.0源码下dex解析的过程,自己实现相关文件解析器。
dex
系统的dex解析头文件
https://github.com/imbaya2466/art_read/blob/master/art/runtime/dex_file.h
文件格式
可以参考前文
https://xn--74q78i15hxv3arigm4e.cn/2018/04/08/dex%E6%96%87%E4%BB%B6%E6%A0%BC%E5%BC%8F/
官方:
https://source.android.com/devices/tech/dalvik/dex-format
细节方面直接参考官方即可,非常全面
|
|
Header
|
|
只有data的size表示字节数,data的size+off应该为文件末尾。ids都是索引,def是定义
索引区
string_ids
每项为一个结构体,描述偏移用的,位于索引区
每个偏移指向一个数据结构体
在data区的string数据结构体
数据使用MUTF-8编码,在MTUF-8中,它的头部存放的是由uleb128编码的字符的个数。描述字串的。
leb128格式,是基于 1 个 Byte 的一种不定长度的编码方式 。若第一个 Byte 的最高位为 1 ,则表示还需要下一个 Byte 来描述 ,直至最后一个 Byte 的最高位为 0。即计算一个leb128编码的字符字节数要从开始到最高位为0的字节。这是描述一个字符的。
将leb128编码的数字转换为可读数字的规则是:除去每个字节的最高位,将每个字节剩余的7个bits拼接在一起,即为数字。1-5个字节。
type_ids
这个数据结构中存放的数据主要是描述dex中所有的类型,比如类类型,基本类型,数组类型的名字
每项为一个结构体,描述字串索引,位于索引区
4字节描述类型的字串标号
字串表示类型还是使用:V-void B-byte C-char D-double F-float I-int J-long 类类型:LA/B/V; 数组:[类型- 类型[]
proto_ids
proto 的意思是 method prototype 代表 java 语言里的一个 method 的原型
简单表示原型字串索引、返回类型类型索引、参数类型表偏移,偏移为0时没有参数
参数类型表,位于data区
field_ids
描述类属性成员
|
|
method_ids
描述类的方法
|
|
类定义区
存放class的定义
|
|
这里文件的偏移一般都指向了data区
annotationsoff
|
|
class_dataoff
|
|
直接方法是指类的(type为某个类)所有实例构造器和private实例方法。反之protected或者public方法都叫做虚方法。
|
|
系统加载
最后都是使用 DexFile::OpenCommon(共同) 来解析加载到内存的dex
其一开始直接使用DexFile构造dex对象
实现解析器
详细细节参考官方
https://source.android.com/devices/tech/dalvik/dex-format#top_of_page
项目仓库:
https://github.com/imbaya2466/XFile
杂记:
- dalvik的字节码的以2字节为基础的变长码,见https://source.android.com/devices/tech/dalvik/instruction-formats.html
- try-catch块的实现就是直接指定try的区域、catch的列表。相关的数据结构:try_item encoded_catch_handler_list
- java的注解提供数据解释程序代码,定义注解只能有属性。使用时在目标位置运用注解即可为目标添加数据。该数据解析可在编译阶段或是运行阶段。编译阶段可使用javac的接口,运行阶段可使用反射。在dex中直接保存注解信息,相关数据结构:annotations_directory_item
- 类的static字段初始值是直接写在dex类信息中的。相关:static_values_off
- 一些有趣的java代码翻译为字节码的点(init clinit),可以阅读阿里技术的深入探索android热修复2.2节
odex
其中包含 APK 中已经过 AOT 编译的方法代码。
本质是一个oat文件,在系统中使用dlopen加载。也可以作为elf文件映射加载。
见下oat文件格式分析
vdex
其中包含 APK 的未压缩 DEX 代码,另外还有一些旨在加快验证速度的元数据。
系统加载
https://github.com/imbaya2466/art_read/blob/master/art/runtime/vdex_file.h
更详细的:
https://github.com/anestisb/vdexExtractor/tree/master/src/vdex
art\runtime\vdex_file.h
就是dex的集合
oat
可参考:https://bbs.pediy.com/thread-206230.htm
https://www.jianshu.com/p/e0929379cdc3
老罗:
https://blog.csdn.net/Luoshengyang/article/details/39307813
elf中导出了三个符号oatdata、oatexec和oatlastword,标明oat的位置,oat中又含dex
oat头指明dex文件的偏移、oat化的class信息
oat化的class信息指明了native代码位置