Android Dex文件格式(一):https://blog.csdn.net/p312011150/article/details/80501690
dex文件分析(第三部分):https://blog.csdn.net/tabactivity/article/details/78950379
Android安全-Dex文件格式详解:https://www.cnblogs.com/kexing/p/8890162.html
Dalvik 和Art、JIT、AOT、燕麦、dex、odex:https://www.colabug.com/4516410.html
官方文档:https://source.android.com/devices/tech/dalvik/dex-format
一. Android Dex文件整体结构:
java程序编译成class后,需要使用dx工具将所有class文件整合成一个dex文件。目的是各个类可以共享数据,一定程度上减少了冗余,也让文件结构更加清晰。经过仔细分析,实验表明,dex文件的大小约为传统jar文件的50%左右。
1.整体结构:
在此处插入图像描述
2.详细描述:
名称格式描述headerheader_item header string_idsstring_id_item[] 字符串标识符列表。这些是该文件使用的所有字符串的标识符,用于内部命名(例如类型描述符)或用作代码引用的常量对象。该列表必须使用UTF-16 代码点值(以非区域设置敏感的方式)按字符串内容排序,并且不得包含任何重复条目。 type_idstype_id_item[] 类型标识符列表。这些是该文件引用的所有类型(类、数组或基元)的标识符(无论是否在文件中定义)。该列表必须按string_id 索引排序,并且不得包含任何重复的条目。 proto_idsproto_id_item[] 方法原型标识符列表。这些是该文件引用的所有原型的标识符。该列表必须按返回类型(按type_id 索引排序)按主顺序排序,然后按参数列表(各个参数按type_id 索引排序,按字典顺序排序)。该列表不得包含任何重复的条目。 field_idsfield_id_item[] 字段标识符列表。这些是该文件引用的所有字段的标识符(无论是否在文件中定义)。该列表必须排序,定义类型(按type_id 索引排序)为主要顺序,字段名称(按string_id 索引排序)为中间顺序,类型(按type_id 索引排序)为次要顺序。该列表不得包含任何重复的条目。 method_idsmethod_id_item[] 方法标识符列表。这些是该文件引用的所有方法的标识符(无论它们是否在文件中定义)。该列表必须进行排序,其中定义类型(按type_id 索引排序)为主要顺序,方法名称(按string_id 索引排序)为中间顺序,方法原型(按proto_id 索引排序)为次要顺序。该列表不得包含任何重复的条目。 class_defsclass_def_item[] 类定义列表。必须对类进行排序,以便指定类的超类和实现的接口比引用的类更早出现在列表中。另外,在此列表中多次出现的同名类的定义是无效的。 call_site_ids call_site_id_item[] 呼叫站点标识符列表。这些是此文件引用的所有调用站点的标识符(无论它们是否在文件中定义)。该列表必须按call_site_off 的升序排序。 method_handlesmethod_handle_item[] 方法句柄列表。该文件引用的所有方法句柄的列表(无论它们是否在文件中定义)。该列表未排序,并且可能包含逻辑上对应于不同方法句柄实例的重复项。 dataubyte[] 数据区域包含上面列出的表的所有支持数据。不同的物品有不同的对齐要求;如有必要,在每个项目之前插入填充字节以实现所需的对齐。 link_dataubyte[]静态链接文件中使用的数据。本文档没有规定本节数据的格式。在未链接的文件中,此部分为空,运行时实现可以在适当的情况下使用此数据。
3. 采用010editor查看dex1文件:
在此处插入图像描述
详情请参考https://source.android.com/devices/tech/dalvik/dex-format查看各项的定义和状态。
还可以查看dex相关代码来梳理一下结构:
https://android.googlesource.com/platform/dalvik/+/master/dx/src/com/android/dx/dex/file/DexFile.java
/art/libdexfile/简单来说,dex是一个收集apk中使用的class文件信息的文件,同时也包含了很多jar包中的类。
dex文件针对class文件中的各种函数表、变量表等进行了优化,整体大小小于class文件的总和。
二. Android Odex,Oat,Vdex , art文件
2.1 odex文件概述( 5.0之前 )
全称是Optimized DEX,即优化的DEX。
当Apk被安装(安装程序)时,它将被验证和优化。目的是验证代码的合法性,优化代码执行速度。经过验证和优化后,将生成ODEX文件。运行Apk时,ODEX将直接加载以避免重复。经过验证和优化以加快Apk 响应时间。
注意:优化过程会根据不同设备上的Dalvik虚拟机版本、不同Framework库等因素而有所不同。已在一台设备上优化的ODEX 文件在复制到另一台设备时可能无法运行。
ODEX格式及生成过程:https://www.jianshu.com/p/242abfb7eb7f
整体结构盗图如下:
在此处插入图像描述
2.2. oat文件(5.0及5.0之后)
参考博客:
Android运行时ART加载OAT文件的过程分析:https://blog.csdn.net/luoshengyang/article/details/39307813
燕麦格式(1):https://shaomi.github.io/2017/08/18/oat%E6%A0%BC%E5%BC%8F/
从Android 运行时开始,我们创建脱壳工件:
https://www.feiworks.com/wy/drops_html/%E4%BB%8EAndroid%E8%BF%90%E8%A1%8C%E6%97%B6%E5%87%BA%E5%8F%9 1%EF% BC%8C%E6%89%93%E9%80%A0%E6%88%91%E4%BB%AC%E7%9A%84%E8%84%B1%E5%A3%B3% E7%A5% 9E%E5%99%A8.html
2.2.1 oat文件概述
oat 文件是ART 运行的文件。它是ELF格式的二进制可执行文件,包括DEX文件和编译后的本地机器指令文件。由于oat文件包含DEX文件,因此它们比ODEX文件占用更多的空间。
由于安装时打包的classes.dex文件会被dex2oat工具翻译成本地机器指令,最终会得到ELF格式的OAT文件。 ART加载OAT文件后,无需处理即可直接运行。将字节码转换为机器代码的过程,使其运行速度更快。
检查微信等第三方应用的安装包如下:
这里插入图片描述,为什么还是odex,这个art文件是什么,这个vdex是什么,==
官方答案:https://source.android.com/devices/tech/dalvik/configure
.vdex:包含APK的未压缩DEX代码,以及一些旨在加速验证的元数据。
.odex:包含APK中AOT编译的方法代码。
.art(可选):包含APK 中列出的某些字符串和类的ART 内部表示,用于加快应用程序启动速度。使用file命令查看这个base.odex
在此插入图片描述
看到这个base.odex文件是ELF格式封装的,所以这里的odex其实就是oat文件,只是还是叫odex后缀。查看系统内置的应用程序,如system/priv-app/,apk在system/app/,最终的oat文件存放在/data/dalvik-cache/:
在此插入图片描述
这里的dex文件也是一个oat文件,只不过是以dex为后缀命名的。 /data/dalvik-cache/下还有以oat为后缀命名的oat文件,通过上面的file命令可以看到。
2.2.2 readelf 查看oat文件结构
由于微信安装包中的oat文件是elf格式封装的,所以可以使用readelf命令查看文件信息,如下:
chenang@mi:~$ readelf -a "/home/chenang/Documents/apk_dex_struct/com.tencent.mm-GzKZdK2dYHRkCVqs-p_ZVA==/oat/arm/base.odex"
ELF 头:
魔术: 7f 45 4c 46 01 01 01 03 00 00 00 00 00 00 00 00
:级ELF32
Data: 2 的补码,小端
版本: 1(当前)
操作系统/ABI: UNIX - GNU
ABI 版本: 0
类型: DYN(共享目标文件)
机器:ARM
版本:0x1
入口点地址:0x0
程序头开始: 52(字节到文件中)
节头的开头: 4261112(文件中的字节)
标志:0x5000000,版本5 EABI
该标头的大小: 52(字节)
程序头大小: 32(字节)
程序头数量: 8
节头大小: 40(字节)
节标题数量: 11
节头字符串表index: 10
节标题:
[编号] 名称类型地址关闭尺寸ES Flg Lk Inf Al
[0] 空00000000 000000 000000 00 0 0 0
[1] .rodata PROGBITS 00001000 001000 1c9000 00 A 0 0 4096
[2] .text PROGBITS 001ca000 1ca000 22f98c 00 AX 0 0 4096
[3] .bss 诺比特003fa000 000000 0079b8 00 A 0 0 4096
[4] .dex 诺比特00402000 000000 40dacf4 00 A 0 0 4096
[5] .dynstr STRTAB 044dd000 3fa000 00006d 00 A 0 0 4096
[6] .dynsym DYNSYM 044dd070 3fa070 0000a0 10 A 5 1 4
[7] .hash 哈希044dd110 3fa110 000034 04 A 6 0 4
[8].动态动态044de000 3fb000 000038 08 A 5 0 4096
[9] .gnu_debugdata PROGBITS 00000000 3fc000 0144a4 00 0 0 4096
[10].shstrtab STRTAB 00000000 4104a4 000051 00 0 0 1
Flags: 的关键
W(写入)、A(分配)、X(执行)、M(合并)、S(字符串)
I(信息)、L(链接顺序)、G(组)、T(TLS)、E(排除)、x(未知)
O(需要额外的操作系统处理)o(特定于操作系统)、p(特定于处理器)
该文件中没有节组。
程序头:
类型偏移VirtAddr PhysAddr FileSiz MemSiz Flg 对齐
PHDR0x0000340x000000340x000000340x001000x00100 R0x4
加载0x0000000x000000000x000000000x1ca0000x1ca000 R0x1000
加载0x1ca0000x001ca0000x001ca0000x22f98c0x22f98c 读0x1000
加载0x0000000x003fa0000x003fa0000x000000x079b8 读写0x1000
加载0x0000000x004020000x004020000x000000x40dacf4 R0x1000
加载0x3fa0000x044dd0000x044dd0000x001440x00144 读0x1000
加载0x3fb0000x044de0000x044de0000x000380x00038 读写0x1000
动态0x3fb0000x044de0000x044de0000x000380x00038 读写0x1000
节到段映射:
分段部分.
00
01.罗数据
02.文字
03.bss
04.dex
05 .dynstr .dynsym .hash
06.动态
07.动态
偏移量0x3fb000 处的动态部分包含7 个条目:
标签类型名称/值
0x00000004(哈希)0x44dd110
0x00000005(STRTAB)0x44dd000
0x00000006(SYMTAB)0x44dd070
0x0000000b(SYMENT)16(字节)
0x0000000a(STRSZ)109(字节)
0x0000000e (SONAME) 库soname: [base.odex]
0x00000000(空)0x0
此文件中没有重定位。
该文件中没有展开部分。
符号表“.dynsym”包含10 个条目:
Num: 值大小类型绑定Vis Ndx 名称
0: 00000000 0 无类型本地默认值
1: 000010000x1c9000 对象全局默认1 oatdata
2: 001ca000 0 对象全局默认2 oatexec
3: 003f9988 4 对象全局默认2 oatlastword
4: 003fa000 8456 对象全局默认3 oatbss
5: 003fa000 8456 对象全局默认3 oatbssmethods
6: 003fc108 22704 对象全局默认3 oatbssroots
7: 004019b4 4 对象全局默认3 oatbsslastword
8: 00402000 0 对象全局默认4 oatdex
9: 044dccf0 4 对象全局默认4 oatdexlastword
桶列表长度直方图(总共1 个桶):
长度数量占总覆盖率的百分比
0 1 (100.0%)
在此文件中找不到版本信息。
2.2.3 oat文件结构大致如图:在这里插入图片描述
如上图,你应该知道:
1、oat文件中有完整的dex文件,而oat数据部分对应的是真正的oat文件,即外层是elf,里面包含了oat,oat中包含了dex。
2、符号oatdata和oatlastword分别指定了oat文件在elf文件中的头和尾位置,符号oatexec指向可执行段的位置;
3、oat文件有自己的头和格式,内部包含完整的dex文件。
4.oat实际上是一个Elf格式的二进制文件。与Elf文件不同的是,它多了几个额外的符号,如oatdata、oatexec、oatlastword等。 oatdata的起始位置相对于文件头固定为0x1000字节,而我们通过oatdump反编译时得到的地址是从0x1000开始的,所以这就是为什么我们在计算backtrace中的地址时最后减去0x1000的原因。只有这样你才能在转储中找到相应的地址。
在此插入图片描述
oat文件格式如图所示。这里0x1000是oatdata相对于文件头的偏移量,后面跟的是oatdata的大小,也就是oatdump中的executable_offset。该值存储在Oat 文件的OatHeader 中。然后是oatexec段,它是机器码。如果进程运行过程中发生异常并挂在oat文件中,那么它的pc一定在oatexec段中。
2.3. art文件
可以看到上面有一个art文件。art 是一些类/字段/方法。当应用程序启动时,它会直接映射到内存。它是从odex 中分离出来的。 art文件主要是为了加速“热代码”的加载和应用。缓存
2.4. vdex文件
Google 在Android 8.0 中添加了新的vdex 文件,其中包含APK 的未压缩DEX 代码,以及一些旨在加快验证速度的元数据。
VDEX 文件有助于提高软件更新的性能和用户体验。 VDEX 文件存储包含验证器依赖项的预先验证的DEX 文件,以便ART 在系统更新期间不需要再次解压和验证DEX 文件。无需执行任何操作即可实现此功能。该功能默认启用。要禁用此功能,请将ART_ENABLE_VDEX 环境变量设置为false。
定义结构:art/runtime/vdex_file.h
34 //VDEX文件包含提取的DEX文件。 VdexFile 类将文件映射到
35 //内存并提供访问其各个部分的工具。
36//
37//文件格式:
38//VdexFile:VerifierDepsHeader 定长头
39 //Dex文件校验和
40//
41//可选:
42//VdexFile:DexSectionHeader 定长头
43//
44 //将quicken_table_off[0]偏移到DEX[0]偏移表的QuickeningInfo部分中。
45//输入DEX文件的DEX[0]数组,字节码可能已被加速。
46//q
uicken_table_off[1] 47// DEX[1] 48// ... 49// DEX[D] 50// 51// VerifierDeps 52// uint8[D][] verification dependencies 53// 54// Optionally: 55// QuickeningInfo 56// uint8[D][] quickening data 57// uint32[D][] quickening data offset tables三. 概括总结:在这里插入图片描述
四.工具使用:
4.1.dx 和 dexdump工具:
在sdk目录:~/Android/Sdk/build-tools/ 下有dex 打包工具:dx 解析dex的工具:dexdump; 源码目录下prebuilts下也有该工具; 手机中也有该工具: system/bin/dexdump4.2. oatdump工具:
在手机中有该工具: /system/bin/oatdump,可以解析oat文件。4.3.objdump工具
对于android开发是源码下对应的arm-linux-androideabi-objdump而非电脑系统的objdump:关于Android操作系统指南:全面解读与深入剖析和的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。
【Android操作系统指南:全面解读与深入剖析】相关文章:
2.米颠拜石
3.王羲之临池学书
8.郑板桥轶事十则
用户评论
Android系统的艺术?这个概念很有趣!
有11位网友表示赞同!
想知道怎么把代码变成艺术作品。
有10位网友表示赞同!
期待看到一些创新设计和交互体验。
有18位网友表示赞同!
或许可以用动画、视觉效果来展现Android的美感?
有8位网友表示赞同!
能不能用代码创作一些有趣的图形或者音乐呢?
有19位网友表示赞同!
我很喜欢Android的开源特性,这让人们可以自由地发挥创意。
有12位网友表示赞同!
Android艺术应该能体现出科技感和人性化!
有8位网友表示赞同!
希望看到更多开发者将艺术融入Android应用开发中。
有9位网友表示赞同!
这种结合艺术和技术的理念非常吸引人!
有15位网友表示赞同!
我觉得代码本身就是一种艺术形式,更不用说用它来创作了。
有11位网友表示赞同!
我很好奇什么样的艺术作品会出现在Android上?
有5位网友表示赞同!
这会不会是一个新的艺术流派?
有18位网友表示赞同!
应该可以举办一些Android艺术展,展示这些作品!
有20位网友表示赞同!
我相信会有很多创意的作品呈现出来!
有8位网友表示赞同!
这个方向很有发展潜力,期待看到未来带来的惊喜!
有16位网友表示赞同!
希望这个概念能够鼓励开发者更加注重用户体验和美感。
有16位网友表示赞同!
我觉得使用Art(艺术)来定义Android是个很好的选择,因为它体现了其自由性和创造力。
有14位网友表示赞同!
这种结合能为人们带来全新的视觉和交互体验!
有10位网友表示赞同!
我想成为这个领域的一部分,尽我所能将艺术融入到我的Android作品中。
有18位网友表示赞同!
这是一个很有趣的探索,期待看到更多关于Android[art] 的信息。
有12位网友表示赞同!