dex 文件结构学习。

# dex 整体结构

1
2
3
4
5
6
7
8
9
10
#       struct dex{
# Header;
# string_ids;
# type_ids;
# proto_ids;
# field_ids;
# methods_ids;
# class_defs;
# data;
# link_data;}

# Header

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#      struct  DexHeader{
# magic [8];
# checksum;
# signature [kSHA1DigestLen];
# fileSize;
# headerSize;
# endianTag;
# linkSize;
# linkOff;
# mapOff;
# stringIdsSize;
# stringIdsOff;
# typeIdsSize;
# typeIdsOff;
# protoIdsSize;
# protoIdsOff;
# fieldIdsSize;
# fieldIdsOff;
# methodIdsSize;
# methodIdsOff;
# classDefsSize;
# classDefsOff;
# dataSize;
# dataOff;}

1.checksum:dex 文件校验和。
2. signature [kSHA1DigestLen]:整个 dex 文件通过 SHA-1 签名得到的值,占用 20 字节,用于检验 dex 文件。
3.endianTag: 字节序标记,用于指定 dex 运行环境的 cpu。
4.linkSzie 和 linkOff:指定链接段大小和文件偏移,通常情况下都为 0.linkSize 为 0 的话表示静态链接。
5.mapOff:指定 DexMapList 的文件偏移。
6.stringIdsSize 和 stringIdsOff:指定了 dex 文件中所有用到的字符串的个数和 string_ids 结构位置偏移。
7.typeIdsSize 和 TypeIdsOff:表示类的类型的数量和 type_ids 结构位置偏移。
8.protoIdsSize 和 protoIdsOff:表示 dex 文件中方法原型的个数和 proto_ids 结构位置偏移。
9.fieldIdsSize 和 fieldsIdsOff:表示 dex 文件中字段个数和 field_ids 结构位置偏移。
10.methodIdsSize 和 methodIdsOff:表示 dex 文件中的方法数量和 methods_ids 结构位置偏移。
11.classDefsSize 和 classDefsOff:指明 dex 文件中类的定义的相关信息。

# string_ids

string_ids 结构中,每 4 字节表示一个位置偏移,该偏移指向真正字符串的偏移地址,真正的字符串存在 data 中。

# type_ids

types_ids 中只存在一种数据 descriptorIdx,它的值为 string_ids 结构的索引。

# proto_ids

1
2
3
4
5
#     struct proto_ids{
# shortyIdx; // 指向 string_Ids 列表的索引
# returnTypeIdx; // 指向 type_Id 列表的索引
# parametersOff; // 指向 type_list 的位置偏移
# }

# type_list

1
2
3
4
#     struct type_list{
# size; //type_Item 的个数
# type_item list [1]; //type_Item 结构,只有一个 type_id 参数,指向 type_id 列表
# }

# field_ids

1
2
3
4
5
#        struct field_ids{
# classIdx; // 类的类型,指向 type_Id 列表的索引
# typeIdx; // 字段类型,指向 type_Id 列表的索引
# nameIdx; // 字段名,指向 string_Id 列表的索引
# }

# methods_ids

1
2
3
4
5
#      struct method_id{
# classIdx; // 类的类型,指向 type_Id 列表的索引
# protoIdx; // 声明类型,指向 proto_Id 列表的索引
# nameIdx; // 方法名,指向 string_Id 列表的索引
# }

# class_defs

1
2
3
4
5
6
7
8
9
10
#           struct    class_defs{
# classIdx; // 类的类型,指向 type_Id 列表的索引
# accessFlags; // 访问标志
# superclassIdx; // 父类类型,指向 type_Id 列表的索引
# interfacesOff; // 接口,指向 type_list 的偏移
# sourceFileIdx; // 源文件名,指向 string_Ids 列表的索引
# annotationsOff; // 注解,指向 annotationsDirectory_Item 结构
# classDataOff; // 指向 class_data 结构的偏移
# staticValuesOff; // 指向 encoded_array 结构的偏移
# }

# class_data

1
2
3
4
5
6
7
#        struct DexClassData{
# classDataHeader header; // 指定字段与方法的个数
# Field* staticFields; // 静态字段,Field 结构
# Field* instanceFields; // 实例字段,Field 结构
# Method* directMethods; // 直接方法,Method 结构
# Method* virtualMethods; // 虚方法,Method 结构
# }

# classDataHeader

1
2
3
4
5
6
#   struct classDataHeader{
# staticFieldsSize; // 静态字段个数
# instanceFieldsSize; // 实例字段个数
# directMethodsSize; // 直接方法个数
# virtualMethodsSize; // 虚方法个数
# }

# Field

1
2
3
4
#       struct DexField{
# field_Idx; // 指向 field_Ids 的索引
# accessFlags; // 访问标志
# }

# Method

1
2
3
4
5
#           struct DexMethod{
# method_Idx; // 指向 method_Ids 的索引
# accessFlags; // 访问标志
# codeOff; // 指向 code 结构的偏移
# }