[置顶] 第4章 Android dex文件格式 第三节

第4章 dex文件格式 第三节

 

1、 环境配置

Ubuntu 15.10 系统 IP:192.168.153.130

理解dex文件整体结构

 

一、dex文件整体结构

 

1、 dex文件由7个部分组成。Dex header为dex文件头,它指定了dex文件的一些属性,并记录了其他6部分数据结构在dex文件中的物理偏移。String_ids到class_def结构可以理解为“索引结构区”,真实的数据存放在data数据区,最后link_data为静态链接数据区,对于目前生成dex文件而言,它始终为空。

Dex header

String_ids

Type_ids

Proto_ids

Field_ids

Methon_ids

Class_ids

data

Link_data

 

2、 dex文件结构如下:

structDexFile {

    /* directly-mapped "opt" header*/

    const DexOptHeader* pOptHeader;

 

    /* pointers to directly-mapped structs andarrays in base DEX */

    const DexHeader*    pHeader;

    const DexStringId*  pStringIds;

    const DexTypeId*    pTypeIds;

    const DexFieldId*   pFieldIds;

    const DexMethodId*  pMethodIds;

    const DexProtoId*   pProtoIds;

    const DexClassDef*  pClassDefs;

          const DexLink*      pLinkData;

 

3、 DexHeader结构占用0x70个字节如下:

structDexHeader {

    u1 magic[8];           /* includesversion number */

    u4 checksum;           /* adler32checksum */

    u1 signature[kSHA1DigestLen]; /* SHA-1 hash */

    u4 fileSize;           /* length ofentire file */

    u4 headerSize;         /* offset tostart of next section */

    u4 endianTag;

    u4 linkSize;

    u4 linkOff;

    u4 mapOff;

    u4 stringIdsSize;

    u4 stringIdsOff;

    u4 typeIdsSize;

    u4 typeIdsOff;

    u4 protoIdsSize;

    u4  protoIdsOff;

    u4 fieldIdsSize;

    u4 fieldIdsOff;

    u4 methodIdsSize;

    u4 methodIdsOff;

    u4 classDefsSize;

    u4 classDefsOff;

    u4 dataSize;

    u4 dataOff;

};

 

1)Magic字段标识了一个有效的dex文件,目前它的值固定为“64 65 78 0a 30 33 35 00”,转换为字符串为“dex.035”。

2)chencksum段为dex文件的校验和,通过它来判断dex文件是否被损坏或修改。

3)Signature字段用来识别最佳化之间的dex文件,checksum字段与signature字段将dexopt验证与优化。

4)FileSize字段记录了包括DexHeader在内的整个dex文件的大小。

5)HeaderSize字段记录了DexHeader结构本身占用的字节数,目前它的值为0x70。

6)endianTag字段指定了dex运行环境cpu字节序,预设值ENDIAN_CONSTANT等于0x12345678,表示默认采用Little-Endian字节序。

7)linkSize字段与stringldsOff字段指定链接段的大小与文件偏移,大多数情况下它们的值为0。

8)mapOff字段指定了DexMapList结构的文件偏移。

9)其他字段分别表示DexStringid、DexTypeid、DexProtoid、DexFieldid、DexMethonid、DexClassDef以及数据段的大小与文件偏移。

 

4、 DexHeader结构下面的数据为“索引结构区” 与“数据区”,“索引结构区”中各数据结构的偏移地址都是从DexHeader结构的stringIdsOff~classDefsOff字段的值指定的,它们并非真正的类数据,而是指向dex文件的data数据区的偏移或数据结构索引。(DexData字段,实际上是ubyte字节数组,包含了程序所有使用到的数据)

 

二、dex文件结构分析

 

1、 Dalvik虚拟机解析dex文件的内容,最终将其映射成DexMapList数据结构。DexHeader结构的mapOff字段指明了DexMaplist结构在dex文件中的偏移,声明如下。

 

Struct DexMapList{

          U4  size;                                   /*DexMapItem的个数*/

          DexMapItemlist[1];       /*DexMapItem结构*/

};

 

2、Size 字段表示接下来有多少个DexMapItem结构,DexMapItem的结构声明如下。

 

Struct DexMapItem {

          U2 type;           /*kDexType开头的类型*/

          U2 unused;      /*未使用,用于字节对齐*/

          U4 size;            /*指定类型的个数*/

          U4 offset;                 /*指定类型数据的文件偏移*/

};

 

2、 type字段为一个枚举常量,如下所示名称,通过类型很容易判断它的具体类型。

Enum{

          kDexTypeHeaderItem             = 0x0000,

          kDexTypeStringIdItem             = 0x0001,

          kDexTypeTypeIdItem               = 0x0002,

          kDexTypeProtoIdItem             = 0x0003,

          kDexTypeFieldIdItem               = 0x0004,

          kDexTypeMethodIdItem                 = 0x0005,

          ……….

          ……….

          kDexTypeAnnotationsDirectoryItem     = 0x2006,

};

 

DexMapItem中的size字段指定了特定类型的个数,它们以特定的类型在dex文件中连续存放。Offset为该类型的文件起始偏移地址。以Hello.dex为例,DexHeader结构的mapOff字段为0x290,读取0x290处的一个双字值为0x0d,表明接下来会有13个DexMapItem结构。使用hexdump –C命令打开Hello.dex,如下图:

 [置顶] 第4章 Android dex文件格式 第三节_第1张图片

注意:通过DexMapItem定义可以发现:这个定义的像类、字符串、方法等资源和dex文件头里定义的类型有很多是一样的。其实这个map的数据,就是头里类型的重复,完全是为了检验作用而存在的。当andriod系统加载dex文件时,如果比较文件头类型个数与map里类型不一致时,就会停止使用这个dex文件。

 

你可能感兴趣的:([置顶] 第4章 Android dex文件格式 第三节)