Android中dex文件的加载与优化流程

Android中dex文件的加载与优化流程目录1、dex文件分析…12、odex文件…22.1、odex文件结构…22.2、odex文件结构分析…33、dex文件的验证与优化…33.1dex文件加载流程…33.2dex文件优化加载流程图…4 1、dex文件分析逻辑上,可以把dex文件分成3个区,头文件、索引区和数据区。索引区的ids后缀为i

大家好,又见面了,我是你们的朋友全栈君。

目录

1、dex文件分析1

2、odex文件2

2.1、odex文件结构2

2.2、odex文件结构分析3

3、dex文件的验证与优化3

3.1 dex文件加载流程3

3.2 dex文件优化加载流程图4

 

1、dex文件分析

逻辑上,可以把dex文件分成3个区,头文件、索引区和数据区。索引区的ids后缀为identifiers的缩写。

Android中dex文件的加载与优化流程

header

dex文件里的header。除了描述.dex文件的文件信息外,还有文件里其他各个区域的索引。

Android中dex文件的加载与优化流程

(1)           magic value,这8个字节一般是常量,为了使.dex文件能够被识别出来,它必须出现在.dex文件的最开头的位置。

(2)           checksum和signature.文件校验码,使用alder32算法校验文件出去maigc,checksum外余下的所有文件区域,用于校验文件错误。Signature,使用SHA-1算法hash除去magic,checksum和signature外余下的所有文件区域。

(3)           file_size:Dex文件的大小。

其余的属性,因为在加固中没有用到。这里就不对它们进行过多解释。

2、odex文件

odex是OptimizedDEX的缩写,表示经过优化的dex文件。存放在/data/dalvik-cache目录下。由于Android程序的apk文件为zip压缩包格式,Dalvik虚拟机每次加载它们时需要从apk中读取classes.dex文件,这样会耗费很多cpu时间,而采用odex方式优化的dex文件,已经包含了加载dex必须的依赖库文件列表,Dalvik虚拟机只需检测并加载所需的依赖库即可执行相应的dex文件,这大大缩短了读取dex文件所需的时间。

不过,这个优化过程会根据不同设备上Dalvik虚拟机的版本、Framework库的不同等因素而不同。在一台设备上被优化过的ODEX文件,拷贝到另一台设备上不一定能够运行。

2.1、odex文件结构

Odex文件的结构可以理解为dex文件的一个超集。它的结构如下图所示,odex文件在dex文件头部添加了一些数据,然后在dex文件尾部添加了dex文件的依赖库以及一些辅助数据。

 
 

Android中dex文件的加载与优化流程

 

 

 

Dalvik虚拟机将dex文件映射到内存中后是Dalvik格式,在Android系统源码的dalvik/libdex/DexFile.h文件中它的定义如下。

DexFile结构中存入的多为其他结构的指针。DexFile最前面的DexOptHeader就是odex的头,DexLink以下的部分被成为auxillary section,即辅助数据段,它记录了dex文件被优化后添加的一些信息。然而,DexFile结构描述的是加载进内存的数据结构,还有一些数据是不会加载进内存的,经过分析,odex文件结构定义整理如下.

Android中dex文件的加载与优化流程

Struct ODEXFile{

           DexOptHeader             header;    /*odex文件头*/

           DEXFile                          dexfile;  /*dex文件*/

           Dependences              deps;        /*依赖库列表*/

           ChunkDexClassLookup    lookup;     /*类查询结构*/

           ChunkRegisterMapPool          mappool; /*映射池*/

           ChunkEnd                            end;    /*结束标志*/

};

2.2、odex文件结构分析

         ODEXFile的文件头DexOptHeader在DexFile.h文件中定义如下.

struct DexOptHeader{

         u1  magic[8];                  /*odex版本标识 */

         u4  dexOffset;            /* dex文件头偏移*/

         u4  dexLength;      /* dex文件总长度*/

         u4  depsOffset;      /*odex依赖库列表偏移*/

         u4  depsLength;     /*依赖库列表总长度*/

         u4  optOffset;       /*辅助数据偏移*/

         u4  optLength;       /*辅助数据总长度*/

         u4  flags ;                          /*标志*/

         u4  checksum;        /*依赖库与辅助数据的校验和*/

};

3、dex文件的验证与优化

3.1 dex文件加载流程 

Android提供了一个专门验证与优化dex文件的工具dexopt。其源码位于Android系统源码的dalvik/dexopt目录下,Dalvik虚拟机在加载一个dex文件时,通过指定的验证与优化选项来调用dexopt进行相应的验证与优化操作。

         dexopt的主程序为OptMain.cpp,其中处理apk/jar/zip文件中的classes.dex的函数为extractAndProcessZip(),extractAndProcessZip()首先通过dexZipFindEntry()函数检查目标文件中是否拥有class.dex,如果没有就失败返回,成功的话就调用dexZipGetEntryInfo()函数来读取classes.dex的时间戳与crc校验值,如果这一步没有问题,接着调用dexZipExtractEntryTo-File()函数释放classes.dex为缓存文件,然后开始解析传递过来的验证与优化选项,验证选项使用“v=”指出,优化选项使用“o=”指出。所有的预备工作都做完后,调用dvmPrepForDexOpt()函数启动一个虚拟机进程,在这个函数中,优化选项dexOptMode与验证选项varifyMode被传递到了全局DvmGlobals结构gDvm的dexOptMode与classVerifyMode字段中。这时候所有的初始化工作已经完成,dexopt调用dvmContinueOptimization()函数开始真正的验证和优化工作。

         dvmContinueOptimization()函数的调用链比较长。首先从OptMain.cpp转移到、dalvik/vm/analysis/DexPrepare.cpp,因为这里有dvmContinueOptimization()函数的实现。函数首先对dex文件做简单的检查,确保传递进来的目标文件属于dex或odex,接着调用mmap()函数将整个文件映射到内存中,然后根据gDvm的dexOptMode与classVerifyMode字段来设置doVarify与doOpt两个布尔值,接着调用rewriteDex()函数来重写dex文件,这里的重写内容包括字符调整、结构重新对齐、类验证信息以及辅助数据。rewriteDex()函数调用dexSwapAndVerify()调整字节序,接着调用dvmDexFileOpenPartial()创建DexFile结构,dvmDexFileOpenPartial()函数的实现在Android系统源码dalvik/vm/DvmDex.cpp文件中,该函数调用dexFileParse()函数解析dex文件,dexFileParse()函数读取dex文件的头部,并根据需要调用验证dexComputeChecksum()函数或调用dexComputeOptChecksum()函数来验证dex或odex文件爱你头的checksum与signature字段。

         接着回到DvmDex.cpp文件继续看代码,当验证成功后,dvmDexFileOpenPartial()函数调用allocateAuxStructures()函数设置DexFile结构辅助数据的相关字段,最后执行完后返回到rewriteDex()函数。rewriteDex()接下来调用loadAllClasses()加载dex文件中所有的类,如果这一步失败了,程序等不到后面的优化与验证就退出了,如果没有错误发生,会调用verifyAndOptimizeClasses()函数进行真正的验证工作,这个函数会调用verifyAndOptimizeClass()函数来优化与验证具体的类,而verifyAndOptimizeClass()函数会细分这些工作,调用dvmVerifyClass()函数进行验证,再调用dvmOptimizeClass()函数进行优化。

         dvmVerifyClass()函数的实现代码位于Android系统源码的dalvik/vm/analysis/DexVerify.cpp文件中。这个函数调用verifyMethod()函数对类的所有直接方法与虚方法进行验证,verifyMethod()函数具体的工作是先调用verifyInstructions()函数来验证方法中的指令及其数据的正确性,再调用dvmVerifyCodeFlow()函数来验证代码流的正确性。

         dvmOptimizeClass()函数的实现代码位于Android系统源码的dalvik/vm/analysis/Optimize.cpp文件爱你中。这个函数调用optimizeMethod()函数对类的所有直接方法与虚方法进行优化,优化的主要工作是进行“指令替换”,替换原则的优先级为“volatile”替换-正确性替换-高性能替换。比如指令iget-wide会根据优先级替换为“volatile”形式的iget-wide-volatile,而不是高性能的iget-wide-quick.

         rewriteDex函数返回后,会再次调用dvmDexFileOpenPartial()来验证odex文件,接着调用dvmGenerateRegisterMaps()函数来填充辅助数据区结构,填充结构完成后,接下来调用updateChecksum()函数重写dex文件爱你的checksum值,再往下就是writeDependencies()与writeOptData()了。

3.2 dex文件优化加载流程图

 Android中dex文件的加载与优化流程

Android中dex文件的加载与优化流程

Android中dex文件的加载与优化流程

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/153553.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • python的取余算法原理_python.取余算法

    python的取余算法原理_python.取余算法#-*-coding:utf-8-*-”’Createdon2012-12-28取余。取一个任意小于1美元的金额,然后计算可以换成最少多少枚硬币。硬币有1美分,5美分,10美分,25美分四种。1美元等于100美分。举例来说,0.76美元换算结果应该是3枚25美分,1枚1美分。类似76枚1美分,2枚25美分+2枚10美分+1枚5美分+1枚1美分这样的…

    2022年4月25日
    45
  • 两位数乘法的速算方法(三)

    两位数乘法的速算方法(三)两位数乘法的速算方法(三)一、速算方法总结序号类别子类别例如应用举例1首位相同尾数互补71X79|(7+1)x7||1×9|=56092尾数不互补72X73(72+3)x70+2×3=52563尾数和为983X867218-8X10=71384尾数和为1185X867230+8X10=73105尾数相同首数互补27X87|(2×8+7)||7×7|=23496首数不互补27X37|(2X3+7)|

    2022年6月7日
    37
  • hostapd的分析[通俗易懂]

    hostapd的分析[通俗易懂]Hostapd的功能就是作为AP的认证服务器,负责控制管理stations(通常可以认为带无线网卡的PC)的接入和认证。通过Hostapd可以将无线网卡切换为AP/Master模式,通过修改配置文件,可以建立一个开放式的(不加密)的,WEP,WPA或WPA2的无线网络。并且通过修改配置文件可以设置无线网卡的各种参数,包括频率,信号,beacon包时间间隔,是否发送beacon包,如果响应探针请求

    2022年5月21日
    144
  • 行测题库图形推理_2021年考公务员

    行测题库图形推理_2021年考公务员事业单位考试中,判断推理是占据一定的地位的,其中图形推理是大家经常见到的。然而,有的考生会觉得这类题目有些难,像“相亲”一样,都是看眼缘。实则不然,图形推理有它自己的规律,大家需要根据图形特征去识别该题对应的规律。比如图形相似我们可以从位置变化或者是组合叠加角度上去考虑。如果相似度很高我们更建议大家考虑位置变化,那今天中公教育老师带大家来看一下何为位置变化。1.从所给的四个选项中,选择最合适的一个…

    2025年10月17日
    7
  • 几种简单的随机数算法「建议收藏」

    几种简单的随机数算法「建议收藏」(1)产生一个范围内的随机数j=(int)(100.0*rand()/(RAND_MAX+1.0))//产生0到100的随机数(2)筛选型随机数x=random(100);while(x==6){x=random(100);}//产生0-99的随机数但不能是6(3)从一段连续的范围内取随机数x=random(11)+

    2022年7月26日
    45
  • MTP模式与USB存储模式(MTP in Android)「建议收藏」

    MTP模式与USB存储模式(MTP in Android)「建议收藏」转载:http://bbs.meizu.cn/thread-4747416-1-1.htmlMTPinAndroidMTP的全称是MediaTransferProtocol(媒体传输协议),它是微软公司提出的一套媒体文件传输协议。Android从3.0开始支持MTP。不过,在今天的智能手机领域内,Google和微软是一对冤家,为什么Android中会使用MTP呢?请看下文。一背景知…

    2022年4月20日
    117

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号