DEX文件简介

平安圈的敌人们,对于DEX文件应该是比拟理解的。咱们这次就简略介绍一下吧:

DEX文件(Dalvik Executable)是一种专为 Android 操作系统设计的可执行文件格局。DEX文件蕴含了由 Java 语言编写的程序的字节码,这些程序在运行时被 Dalvik 虚拟机(DVM)解释执行。

在 Android 利用程序开发中,Java 代码通过编译器编译生成Java字节码文件(.class文件),而后通过工具将字节码文件转换为DEX格局,最初打包成APK文件供装置和运行。因为 Android 设施的处理器架构和Java虚拟机的差别,所以须要将Java字节码转换为DEX格局,以便在Dalvik虚拟机上运行。

DEX文件的长处:

1.可能高效地应用内存和处理器资源,这是因为它采纳了基于寄存器的架构,绝对于传统的基于堆栈的Java虚拟机,在执行Java程序时,可能更快地加载和执行代码。

2.DEX文件反对在利用程序运行时动静加载类和办法,提供了更高的灵活性。

所以咱们如果想要理解加固解决方案如何帮忙Android 利用反抗逆向和破解,首先须要理解DEX文件到底是什么样的。

DEX文件格式解析

1.文件构造展现

DEX文件在010中的体现

2.文件构造详解

struct Header {    uint8_t magic[8];                                       // dex版本标识    uint32_t checksum;                                  // adler32校验和    uint8_t signature[kShalDigestSize];         // SHA-1哈希值    uint32_t file_size;                                      // 文件大小    uint32_t header_size;                               //Header构造大小    uint32_t endian_tag;                               //字节序标记    uint32_t link_size;                                   // 链接段大小    uint32_t link_off;                                    // 链接段偏移    uint32_t map_off;                                   //映射项偏移    uint32_t string_ids_size;                        //字符串标识符列表个数    uint32_t string_ids_off;                          //字符串标识符列表偏移    uint32_t type_ids_size;                          //类型标识符列表个数    uint32_t type ids_off;                            //类型标识符列表偏移     uint32_t proto_ids_size;                        //办法原型标识符列表个数    uint32_t proto_ids_off;                         //办法原型标识符列表偏移    uint32 t field ids size;                           //字段标识符列表个数    uint32_t field_ids_off;                          //字段标识符列表偏移    uint32 t method_ids_size;                   //办法标识符列表个数    uint32_t method_ids_off;                    //办法标识符列表偏移    uint32_t class_defs_size;                     //类定义列表个数    uint32_t class_defs_off;                      //类定义列表偏移    uint32_t data_size;                             //数据区大小    uint32_t data_off;                               //数据区偏移};

文件头

magic[8]:dex版本标识。这类字节必须呈现在 .dex 文件的结尾,以便零碎将其原样辨认。该值会特意蕴含一个换行符("\n" 或 0x0a)和空字节("\0" 或 0x00),以便帮助检测某些模式的损坏问题。该值还能够将格局版本号编码为 3 个十进制数字;随着格局的演变,预计该值会枯燥递增。checksum:能够用于文件残余内容(除 magic 和此字段之外的所有内容)的 adler32 校验和。另外,还能够用于检测文件损坏状况。signature[kSha1DigestSize]:文件残余内容(除 magic、checksum 和此字段之外的所有内容)的 SHA-1 签名(哈希);用于对文件进行惟一标识。file_size:整个文件(包含标头)的大小,以字节为单位。header_size:标头(整个区段)的大小,以字节为单位。这一项容许至多肯定水平的向后/向前兼容性,而不用让格局生效。endian_tag:字节序标记。ENDIAN_CONSTANT ,示意小端字节序。REVERSE_ENDIAN_CONSTANT 示意大端字节序,默认值为 ENDIAN_CONSTANT 。link_size 与 link_off :链接区段的大小与文件偏移。如果此文件未进行动态链接,则两个值都为0。map_off:从文件结尾到映射项列表的文件偏移量。string_ids_size 与 string_ids_off:字符串标识符列表中的字符串数量与文件偏移。type_ids_size 与 type_ids_off:类型标识符列表中的元素数量及文件偏移。元素数量下限为65535。proto_ids_size 与 proto_ids_off:原型标识符列表中的元素数量及文件偏移。元素数量下限为65535。field_ids_size 与 field_ids_off:字段标识符列表中的元素数量及文件偏移。method_ids_size 与 method_ids_off:办法标识符列表中的元素数量及文件偏移。class_defs_size 与 class_defs_off:类定义列表中的元素数量及文件偏移。data_size 与 data_off :data区段的大小及文件偏移。

字符串标识符列表( dex_string_ids )在DEX文件以 DexStringId[] 的模式存在,其构造如下。

struct DexStringId {    u4 stringDataOff;  //字符串数据的文件偏移};

类型标识符列表( dex_type_ids )在DEX文件以 DexTypeId[] 的模式存在,其构造如下。

struct DexType {    u4 descriptorIdx;  //类型描述符对应在字符串标识符列表中的索引};

办法原型标识符列表( dex_proto_ids )在DEX文件以 DexProtoId[] 的模式存在,其中 DexProtoId 构造如下。

struct DexProtoId {    u4 shortyIdx;           // 办法原型的简写模式对应在字符串标识符列表中的索引    u4 returnTypeIds;   // 返回值类型对应在类型标识符列表中的索引    u4 parametersOff;  // 参数类型在DEX文件中的偏移,构造为DexTypeList};

DexTypeList 构造如下。

struct DexTypeItem {    u2 typeIdx;           // 类型在类型标识符表中的索引};struct DexTypeList {    u4 size;   // 返回值类型对应在类型标识符列表中的索引    DexTypeItem List[1];  // DexTypeItem数组};

办法标识符列表( dex_method_ids ) 在DEX文件以 DexMethodId[] 的模式存在,其中 DexMethodId 构造如下

struct DexMethodId {    u2 classIdx;   // 类定义在类型标识符列表中的索引    u2 protoIdx;   // 办法原型类型在办法原型标识符列表中的索引                u2 nameIdx;   // 办法名称在字符串列表中的索引};

类定义列列表( dex_class_defs )在DEX文件以 DexClassDef[] 的模式存在,其中 DexClassDef 构造如下

struct DexClassId {    u4 classIdx;   // 类定义在类型标识符列表中的索引    u4 accessFlags;   // 类拜访标识                u4 superclassIdx;   // 超类在类型标识符列表中的索引    u4 interfaceOff;   // 接口,DexTypeList构造的文件偏移    u4 sourceFileIdx;   // 源文件名在字符串示意列表中的索引                u4 annotationsOff;   // 注解,DexAnnotationsDirectoryItem构造的文件偏移    u4 classDataOff;   // 类数据,DexClassData构造的文件偏移    u4 staticValuesOff;   // 动态值,DexEncodeArray构造的文件偏移};

映射项列表( dex_map_list ) 在DEX文件以 DexMapItem[] 的模式存在,其中 DexMapItem 构造如下。

struct DexMapItem {    u2 type;         //类型代码    u2 unused;    //未应用    u4 size;         //在指定偏移量处找到的项数量    u4 offset;      //相干项的文件偏移量};

类型代码表如图所示。

明天就先讲到这里啦,下次将在第二篇文章中持续解析DEX文件的DexAnnotationsDirectoryItem 、 DexClassData 与 DexEncodeArray 构造,请持续关注~