您的位置:首页 > 移动开发 > Android开发

第4章 Android dex文件格式 第三节

2016-03-04 14:00 204 查看
第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,如下图:



注意:通过DexMapItem定义可以发现:这个定义的像类、字符串、方法等资源和dex文件头里定义的类型有很多是一样的。其实这个map的数据,就是头里类型的重复,完全是为了检验作用而存在的。当andriod系统加载dex文件时,如果比较文件头类型个数与map里类型不一致时,就会停止使用这个dex文件。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: