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文件的加载与优化流程

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • scala隐式转换[通俗易懂]

    scala隐式转换[通俗易懂]简述:1:通过隐式转换,程序员可以在编写Scala程序时故意漏掉一些信息,让编译器去尝试在编译期间自动推导出这些信息来,这种特性减少代码量,忽略那些冗长的代码。2:我们经常引入第三方库,但当我们想要扩展新功能的时候通常是很不方便的,因为我们不能直接修改其代码。scala提供了隐式转换机制和隐式参数帮我们解决诸如这样的问题。Scala中的隐式转换是一种非常强大的代码查找机制。当函数、构造器调用缺少参数或者某一实例调用了其他类型的方法导致编译不通过时,编译器会尝试搜索一些特定的区域,尝试使编译

  • Spring Cloud版本说明

    Spring Cloud版本说明SpringCloud是一个由众多独立子项目组成的大型综合项目,每个子项目有不同的发行节奏,都维护着自己的发布版本号。SpringCloud通过一个资源清单BOM(BillofMaterials)来管理每个版本的子项目清单。为避免与子项目的发布号混淆,所以没有采用版本号的方式,而是通过命名的方式。这些版本名称的命名方式采用了伦敦地铁站的名称,同时根据字母表的顺序来对应版本时间顺序,比如…

  • clgao资源网址

    clgao资源网址工作流项目github:https://github.com/snakerflow/snaker-web

  • mysql索引详解「建议收藏」

    一、MySQL三层逻辑架构MySQL的存储引擎架构将查询处理与数据的存储/提取相分离。下面是MySQL的逻辑架构图:一、对比InnoDB与MyISAM1、存储结构MyISAM:每个MyISAM在磁盘上存储成三个文件。分别为:表定义文件、数据文件、索引文件。第一个文件的名字以表的名字开始,扩展名指出文件类型。.frm文件存储表定义。数据文件的扩展名为.MYD(MYData)。索引文件的扩展名是.MYI(MYIndex)。InnoDB:所有的表都保存在同一个数据文件中(也可能是多个

  • 七年级小四门知识点_unity animator trigger

    七年级小四门知识点_unity animator triggerUnity小科普老规矩,先介绍一下Unity的科普小知识:Unity是实时3D互动内容创作和运营平台。包括游戏开发、美术、建筑、汽车设计、影视在内的所有创作者,借助Unity将创意变成现实。Unity平台提供一整套完善的软件解决方案,可用于创作、运营和变现任何实时互动的2D和3D内容,支持平台包括手机、平板电脑、PC、游戏主机、增强现实和虚拟现实设备。也可以简单把Unity理解为一个游戏引擎,可以用来专业制作游戏!Unity小知识点学习Unity中使用代码查询D.

  • 求一个点在平面上的投影_unity获取物体坐标

    求一个点在平面上的投影_unity获取物体坐标Unity计算投影点主要内容新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML图表FLowchart流程图导出与导入导出导入主要内容本文旨在求得点在某一平面的投影点,主要包括Unity中InverseTransformPoint和TransformPoint方法。主要

    2022年10月23日

发表回复

您的电子邮箱地址不会被公开。

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