参考学习博客:

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, oat, 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.详细描述:

名称 格式 说明
header header_item 标头
string_ids string_id_item[] 字符串标识符列表。这些是此文件使用的所有字符串的标识符,用于内部命名(例如类型描述符)或用作代码引用的常量对象。此列表必须使用 UTF-16 代码点值按字符串内容进行排序(不采用语言区域敏感方式),且不得包含任何重复条目。
type_ids type_id_item[] 类型标识符列表。这些是此文件引用的所有类型(类、数组或原始类型)的标识符(无论文件中是否已定义)。此列表必须按 string_id 索引进行排序,且不得包含任何重复条目。
proto_ids proto_id_item[] 方法原型标识符列表。这些是此文件引用的所有原型的标识符。此列表必须按返回类型(按 type_id 索引排序)主要顺序进行排序,然后按参数列表(按 type_id 索引排序的各个参数,采用字典排序方法)进行排序。该列表不得包含任何重复条目。
field_ids field_id_item[] 字段标识符列表。这些是此文件引用的所有字段的标识符(无论文件中是否已定义)。此列表必须进行排序,其中定义类型(按 type_id 索引排序)是主要顺序,字段名称(按 string_id 索引排序)是中间顺序,而类型(按 type_id 索引排序)是次要顺序。该列表不得包含任何重复条目。
method_ids method_id_item[] 方法标识符列表。这些是此文件引用的所有方法的标识符(无论文件中是否已定义)。此列表必须进行排序,其中定义类型(按 type_id 索引排序)是主要顺序,方法名称(按 string_id 索引排序)是中间顺序,而方法原型(按 proto_id 索引排序)是次要顺序。该列表不得包含任何重复条目。
class_defs class_def_item[] 类定义列表。这些类必须进行排序,以便所指定类的超类和已实现的接口比引用类更早出现在该列表中。此外,对于在该列表中多次出现的同名类,其定义是无效的。
call_site_ids call_site_id_item[] 调用站点标识符列表。这些是此文件引用的所有调用站点的标识符(无论文件中是否已定义)。此列表必须按 call_site_off 的升序进行排序。
method_handles method_handle_item[] 方法句柄列表。此文件引用的所有方法句柄的列表(无论文件中是否已定义)。此列表未进行排序,而且可能包含将在逻辑上对应于不同方法句柄实例的重复项。
data ubyte[] 数据区,包含上面所列表格的所有支持数据。不同的项有不同的对齐要求;如有必要,则在每个项之前插入填充字节,以实现所需的对齐效果。
link_data ubyte[] 静态链接文件中使用的数据。本文档尚未指定本区段中数据的格式。此区段在未链接文件中为空,而运行时实现可能会在适当的情况下使用这些数据。

3. 采用010editor查看dex1文件:


具体可以参考https://source.android.com/devices/tech/dalvik/dex-format,查看每项的定义即情况
也可以查看dex相关的code进行结构的梳理:
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在安装(installer)时,就会进行验证和优化,目的是为了校验代码合法性及优化代码执行速度,验证和优化后,会产生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
oat格式(1):https://shaomi.github.io/2017/08/18/oat格式/
从Android运行时出发,打造我们的脱壳神器:
https://www.feiworks.com/wy/drops_html/从Android运行时出发,打造我们的脱壳神器.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 (optional):其中包含 APK 中列出的某些字符串和类的 ART 内部表示,用于加快应用启动速度。

使用file命令查看这个base.odex

看到这个base.odex文件是ELF格式封装的,所以这里的odex其实就是oat文件,只是还是叫odex后缀。

查看系统自带应用,比如system/priv-app/,system/app/中的apk,最终oat文件存放在/data/dalvik-cache/ 中:

这里的dex文件也是oat文件,只是以dex为后缀命名,/data/dalvik-cache/ 下也有以oat为后缀命名的oat文件,通过如上的file命令就可以看出来。

2.2.2 readelf 查看oat文件结构

微信的安装包中的oat文件由于是elf格式封装,可以使用readelf命令查看文件信息如下:

chengang@mi:~$ readelf -a '/home/chengang/Documents/apk_dex_structure/com.tencent.mm-GzKZdK2dYHRkCVqs-p_ZVA==/oat/arm/base.odex'
ELF Header:Magic:   7f 45 4c 46 01 01 01 03 00 00 00 00 00 00 00 00 Class:                             ELF32Data:                              2's complement, little endianVersion:                           1 (current)OS/ABI:                            UNIX - GNUABI Version:                       0Type:                              DYN (Shared object file)Machine:                           ARMVersion:                           0x1Entry point address:               0x0Start of program headers:          52 (bytes into file)Start of section headers:          4261112 (bytes into file)Flags:                             0x5000000, Version5 EABISize of this header:               52 (bytes)Size of program headers:           32 (bytes)Number of program headers:         8Size of section headers:           40 (bytes)Number of section headers:         11Section header string table index: 10Section Headers:[Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al[ 0]                   NULL            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              NOBITS          003fa000 000000 0079b8 00   A  0   0 4096[ 4] .dex              NOBITS          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             HASH            044dd110 3fa110 000034 04   A  6   0  4[ 8] .dynamic          DYNAMIC         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
Key to Flags:W (write), A (alloc), X (execute), M (merge), S (strings)I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)O (extra OS processing required) o (OS specific), p (processor specific)There are no section groups in this file.Program Headers:Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg AlignPHDR           0x000034 0x00000034 0x00000034 0x00100 0x00100 R   0x4LOAD           0x000000 0x00000000 0x00000000 0x1ca000 0x1ca000 R   0x1000LOAD           0x1ca000 0x001ca000 0x001ca000 0x22f98c 0x22f98c R E 0x1000LOAD           0x000000 0x003fa000 0x003fa000 0x00000 0x079b8 RW  0x1000LOAD           0x000000 0x00402000 0x00402000 0x00000 0x40dacf4 R   0x1000LOAD           0x3fa000 0x044dd000 0x044dd000 0x00144 0x00144 R   0x1000LOAD           0x3fb000 0x044de000 0x044de000 0x00038 0x00038 RW  0x1000DYNAMIC        0x3fb000 0x044de000 0x044de000 0x00038 0x00038 RW  0x1000Section to Segment mapping:Segment Sections...00     01     .rodata 02     .text 03     .bss 04     .dex 05     .dynstr .dynsym .hash 06     .dynamic 07     .dynamic Dynamic section at offset 0x3fb000 contains 7 entries:Tag        Type                         Name/Value0x00000004 (HASH)                       0x44dd1100x00000005 (STRTAB)                     0x44dd0000x00000006 (SYMTAB)                     0x44dd0700x0000000b (SYMENT)                     16 (bytes)0x0000000a (STRSZ)                      109 (bytes)0x0000000e (SONAME)                     Library soname: [base.odex]0x00000000 (NULL)                       0x0There are no relocations in this file.There are no unwind sections in this file.Symbol table '.dynsym' contains 10 entries:Num:    Value  Size Type    Bind   Vis      Ndx Name0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 1: 00001000 0x1c9000 OBJECT  GLOBAL DEFAULT    1 oatdata2: 001ca000     0 OBJECT  GLOBAL DEFAULT    2 oatexec3: 003f9988     4 OBJECT  GLOBAL DEFAULT    2 oatlastword4: 003fa000  8456 OBJECT  GLOBAL DEFAULT    3 oatbss5: 003fa000  8456 OBJECT  GLOBAL DEFAULT    3 oatbssmethods6: 003fc108 22704 OBJECT  GLOBAL DEFAULT    3 oatbssroots7: 004019b4     4 OBJECT  GLOBAL DEFAULT    3 oatbsslastword8: 00402000     0 OBJECT  GLOBAL DEFAULT    4 oatdex9: 044dccf0     4 OBJECT  GLOBAL DEFAULT    4 oatdexlastwordHistogram for bucket list length (total of 1 buckets):Length  Number     % of total  Coverage0  1          (100.0%)No version information found in this file.

2.2.3 oat文件结构大致如图:

如上图应知:

1.oat文件中有完整的dex文件,oat data section 中对应着真正的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,才能去dump里面找对应的地址。


oat文件格式如图所示,这里0x1000是oatdata相对于文件头的偏移,接着就是oatdata的大小,也就是oatdump中的executable_offset,这个值保存在Oat文件的OatHeader里面。然后就是oatexec段,也就是机器码。而进程运行过程中异常如果挂在oat文件中,那么其pc一定是在oatexec段内。

2.3. art文件

看到上面有art文件,.art是一些类/filed/方法,app启动直接map到内存,从odex中拆分出来的,art文件主要为了加快应用的对“热代码”的加载与缓存

2.4. vdex文件

google在android8.0新增加了vdex文件,其中包含 APK 的未压缩 DEX 代码,另外还有一些旨在加快验证速度的元数据。

VDEX 文件有助于提升软件更新的性能和用户体验。VDEX 文件会存储包含验证程序依赖项且经过预验证的 DEX 文件,以便 ART 在系统更新期间无需再次解压和验证 DEX 文件。无需执行任何操作,即可实现该功能。该功能默认处于启用状态。要停用该功能,请将 ART_ENABLE_VDEX 环境变量设为 false。

定义结构:art/runtime/vdex_file.h

34// VDEX files contain extracted DEX files. The VdexFile class maps the file to
35// memory and provides tools for accessing its individual sections.
36//
37// File format:
38//   VdexFile::VerifierDepsHeader    fixed-length header
39//      Dex file checksums
40//
41//   Optionally:
42//      VdexFile::DexSectionHeader   fixed-length header
43//
44//      quicken_table_off[0]  offset into QuickeningInfo section for offset table for DEX[0].
45//      DEX[0]                array of the input DEX files, the bytecode may have been quickened.
46//      quicken_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/dexdump

4.2. oatdump工具:

在手机中有该工具: /system/bin/oatdump,可以解析oat文件。

4.3.objdump工具

对于android开发是源码下对应的arm-linux-androideabi-objdump而非电脑系统的objdump:

./prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin/arm-linux-androideabi-objdump -S ~/Documents/f3b/symbol/out/target/product/pyxis/symbols/vendor/lib/hw/camera.qcom.so | tee camera.qcom.asm
用来反编译symbol文件为汇编指令用于问题定位。

4.4. Vdex Extractor工具:

Vdex Extractor:从Vdex文件反编译和提取Android Dex字节码的工具:https://www.freebuf.com/sectool/185881.html

Android[art]-Android dex,odex,oat,vdex,art文件结构学习总结相关推荐

  1. linux apk 拆分 odex,android平台下,apk、jar、dex、odex、vdex、art文件相互转换,编译和反编译...

    apk.jar.dex.odex.vdex相互转换java 1. ? to jar 1.1 odex to jar 1.2 dex to jar 1.3 apk to jar 输出结果可能有损 1). ...

  2. Android .dex、.odex、Dalvik、ART、AOT、OAT

    文章来源:https://www.jianshu.com/p/e52b7e460748 https://zhuanlan.zhihu.com/p/53723652 目的 理清 .dex..odex.A ...

  3. 快速理清 .dex、.odex、ART、AOT、OAT 逻辑关系

    目的 理清 .dex..odex.ART.AOT.OAT 等近似名称的概念和意义. APK 生成 apk的打包过程 最终 apk 内的代码文件为 .dex 文件. APK 安装运行 基础概念 AOT: ...

  4. android oat如何提取dex文件字节码,Android: 使用oatdump反编译oat文件

    网上经常看到有通过apktool将apk中的dex反编译成smali格式的文件,以便分析功能实现与破-解,确没怎么看到oat文件反通过oatdump反编译的,所以就写了一篇这样的文档.声明一下oat文 ...

  5. odex vdex art区别

    原址 一.vdex package 直接转化的 可执行二进制码 文件: 1.第一次开机就会生成在/system/app/<packagename>/oat/下: 2.在系统运行过程中,虚拟 ...

  6. android 4.4 art模式,安卓4.4的ART模式怎么打开 安卓4.4开启art模式方法图解

    ART模式是Android系统新增的一个新的底层运行模式,目前仅有Android 4.4系统才拥有ART模式,与传统的安卓Dalvik模式有很大的区别.通过在ART模式运行程序应用,可以达到省电.节约 ...

  7. Android P去掉DEX优化编译

    Android P的系统编译中,采用了DEX优化编译. 单个apk或者jar去Dex编译 在系统中编译出来的文件如下: oat -arm64 -SystemUI.odex -SystemUI.vdex ...

  8. odex to dex boot.oat

    更新 Android 5.x (Lollipop) 之后的 framework/services.jar 星期三, 2015-12-30 10:05 - qyb 先记录一下,https://githu ...

  9. ART世界探险(12) - OAT文件分析(2) - ELF文件头分析(中)

    ART世界探险(12) - OAT文件分析(2) - ELF文件头分析(中) 段(section)的概念 一块内存分配给应用程序之后,从代码的组织上,我们就有将它们分段的需求. 比如,可以分为代码段, ...

最新文章

  1. python有道api-python 调用有道api接口的方法
  2. JZOJ 5922. 【NOIP2018模拟10.23】sequence
  3. python输入整数_Python中实现输入一个整数的案例
  4. [NodeJs] 如果发现node_modules中有个模块代码有bug,你该怎么办?
  5. 代码中有个get是啥意思_是时候秀一波了,甩掉get和set,Lombok让代码更简洁
  6. OSGi运行环境下java反序列化问题的解决方式
  7. vue脚手架项目中引入jquery
  8. STL--queue
  9. R语言系统教程(一):向量及其相关操作
  10. 5步绘制软件开发流程图
  11. js获取ip地址的私有地址 或者公有地址
  12. 结合百度地图城市编码的数据表
  13. 多种语言打印Hello World
  14. 让zheng支持activiti工作流
  15. android缩放组件,Android可放大缩小的图片浏览缩放控件
  16. 计算机文化基础0008 17秋在线作业1,【在线】《计算机文化基础0008》17秋在线作业2.doc...
  17. vscode 侧边栏源代码管理不见了
  18. 使用Audacity对清浊音进行频谱分析
  19. ACM里的生成函数初探
  20. java实现阿拉伯数字转人民币大写(精确到分)

热门文章

  1. N多计算机精品免费视频下载网址
  2. 九头蛇(Hydra)安装与使用
  3. SuperMap画圆的周边查询
  4. ETag, Eric的UBB代码实现方案Sample源码
  5. 【第一次机房收费系统优化】-登录窗体
  6. 文本框只允许输入数字
  7. 火狐安卓版支持油猴了!后面将支持更多扩展插件
  8. only whitespace content allowed before start tag and not
  9. The method getRealPath(String) from the type ServletRequest is deprecated
  10. 在 Zend Studio 12.5 里下断点调试运行 PHP 源代码