Dex文件格式

简介: Dex文件格式讲解

什么是Dex

Dex是Android可执行文件,类似Windows上的PE文件,Linux下的ELF文件,和Mac下的Mach-o文件,只是一中文件格式

整体文件浏览

Dex文件内容分布如下图


Alt text

结构体分布图


Alt text

Dex.hdex头文件下载地址

Dex文件头

header_item []
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
struct header_item
{
ubyte[8] magic;
unit checksum;
ubyte[20] signature;
uint file_size;
uint header_size;
unit endian_tag;
uint link_size;
uint link_off;
uint map_off;
uint string_ids_size;
uint string_ids_off;
uint type_ids_size;
uint type_ids_off;
uint proto_ids_size;
uint proto_ids_off;
uint filed_ids_size
uint filed_ids_off;
uint method_ids_size;
uint method_ids_off;
uint class_defs_size;
uint class_defs_off;
uint data_size;
uint data_off;
}


Alt text

magic

magic代表dex中的文件标识,一般被称为魔数,是用来识别dex这种文件的,它可以判断当前的dex文件是否有效,可以看到它用了8个1字节的无符号数来表示,相当于Window PE结构的PE 和 MZ就是一个标志而已。

checksum

checksum是dex文件的校验和,使用 alder32 算法校验文件除去 maigc、checksum 外余下的所有文件区域,通过它可以判断dex文件是否被损坏或者被篡改。

signature

signature字段用于检验dex文件,使用 SHA-1 算法 hash 除去 magic、checksum 和 signature 外余下的所有文件区域,其实就是把整个dex文件用SHA-1签名得到的一个值。

file_size

此Dex文件大小

header_size

此Dex的hheader_item头部大小,目前是固定为 0x70

endian_tag

大小端标签,dex 文件格式为小端,固定值为 0x12345678 常量

linkSize为0的话表示静态链接,通常情况下它们都为0

通常情况下它们都为0

map_off

指定了DexMapList的文件偏移,该 item 属于 data 区里的内容,值要大于等于 data_off 的大小,处于 dex 文件的末端

string_ids_size

字符串的个数

string_ids_off

字符串的位置偏移

type_ids_size

数据类型大小

type_ids_off

数据类型位置偏移

proto_ids_size

method prototype 代表 java 语言里的一个 method 的原型

proto_ids_off

位置偏移

filed_ids_size

字段名的大小

filed_ids_off

字段名的位置偏移

method_ids_size

方法的个数

method_ids_off

方法的位置偏移

class_defs_size

类的个数

class_defs_off

类的位置偏移

data_size

具体数据的大小

data_off

数据的位置偏移

String_ids

String []
1
2
3
4
5
6
7
8
9
10
11
12
13
14
ubyte    8-bit unsinged int
uint 32-bit unsigned int, little-endian
uleb128 unsigned LEB128, valriable length

struct string_ids_item
{
uint string_data_off;
}

struct string_data_item
{
uleb128 utf16_size;
ubyte data;
}

string 顾名思义就是指向字符串,但是它不是直接指向字符串的,往下看
string_ids_off 指向一块内容,是包含以上结构体的一个数组
string_ids_item->string_data_off 才是真正字符串的位置,而string_data_item才是真正的字符串

Type_ids

Type []
1
2
3
4
struct type_ids_item
{
uint descriptor_idx; //-->string_ids
}

本身是一个由这个结构体组成的一个数组
descriptor_idx 是指向string这个数组的一个下标

Proto_ids

Proto []
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
uint 32-bit unsigned int, little-endian
struct proto_id_item
{
uint shorty_idx; //-->string_ids
uint return_type_idx; //-->type_ids
uint parameters_off;
}
struct DexTypeList
{
u4 size; /*DexTypeItem的个数*/
DexTypeItem list[1]; /*DexTypeItem结构*/
}
struct DexTypeItem
{
u2 typeIdx; /*指向DexTypeId列表的索引*/
}

parameters_off 指向 DexTypeList-> 指向 DexTypeItem->typeIdx 是指向 type_id 这个个数组的一个下标

Filed_ids

Filed []
1
2
3
4
5
6
struct DexFieldId
{
u2 classIdx; /*类的类型,指向DexTypeId列表的索引*/
u2 typeIdx; /*字段类型,指向DexTypeId列表的索引*/
u4 nameIdx; /*字段名,指向DexStringId列表的索引*/
}

Method_ids

Method []
1
2
3
4
5
6
struct DexMethodId
{
u2 classIdx; /*类的类型,指向DexTypeId列表的索引*/
u2 protoIdx; /*声明类型,指向DexProtoId列表的索引*/
u4 nameIdx; /*方法名,指向DexStringId列表的索引*/
}

Class_defs

Class []
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
struct DexClassDef
{
u4 classIdx; /*类的类型,指向DexTypeId列表的索引*/
u4 accessFlags; /*访问标志*/
u4 superclassIdx; /*父类类型,指向DexTypeId列表的索引*/
u4 interfacesOff; /*接口,指向DexTypeList的偏移*/
u4 sourceFileIdx; /*源文件名,指向DexStringId列表的索引*/
u4 annotationsOff; /*注解,指向DexAnnotationsDirectoryItem结构*/
u4 classDataOff; /*指向DexClassData结构的偏移*/
u4 staticValuesOff; /*指向DexEncodedArray结构的偏移*/
}
struct DexClassData
{
DexClassDataHeader header; /*指定字段与方法的个数*/
DexField* staticFields; /*静态字段,DexField结构*/
DexField* instanceFields; /*实例字段,DexField结构*/
DexMethod* directMethods; /*直接方法,DexMethod结构*/
DexMethod* virtualMethods; /*虚方法,DexMethod结构*/
}
struct DexClassDataHeader
{
u4 staticFieldsSize; /*静态字段个数*/
u4 instanceFieldsSize; /*实例字段个数*/
u4 directMethodsSize; /*直接方法个数*/
u4 virtualMethodsSize; /*虚方法个数*/
}

struct DexField
{
u4 fieldIdx; /*指向DexFieldId的索引*/
u4 accessFlags; /*访问标志*/
}

struct DexMethod
{
u4 methodIdx; /*指向DexMethodId的索引*/
u4 accessFlags; /*访问标志*/
u4 codeOff; /*指向DexCode结构的偏移*/
}

×

谢谢支持

扫码支持
扫码打赏

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. 什么是Dex
  2. 2. 整体文件浏览
  3. 3. Dex文件头
    1. 3.0.1. magic
    2. 3.0.2. checksum
    3. 3.0.3. signature
    4. 3.0.4. file_size
    5. 3.0.5. header_size
    6. 3.0.6. endian_tag
    7. 3.0.7. link_size
    8. 3.0.8. link_off
    9. 3.0.9. map_off
    10. 3.0.10. string_ids_size
    11. 3.0.11. string_ids_off
    12. 3.0.12. type_ids_size
    13. 3.0.13. type_ids_off
    14. 3.0.14. proto_ids_size
    15. 3.0.15. proto_ids_off
    16. 3.0.16. filed_ids_size
    17. 3.0.17. filed_ids_off
    18. 3.0.18. method_ids_size
    19. 3.0.19. method_ids_off
    20. 3.0.20. class_defs_size
    21. 3.0.21. class_defs_off
    22. 3.0.22. data_size
    23. 3.0.23. data_off
  • 4. String_ids
  • 5. Type_ids
  • 6. Proto_ids
  • 7. Filed_ids
  • 8. Method_ids
  • 9. Class_defs
  • ,