dex文件格式

dex文件格式

数据结构

u1:等同于uint8_t,表示1字节的无符号数
u2
u4
u8
sleb128:有符号LEB128,可变长度15字节
uleb128:无符号LEB128,可变长度1
5字节
uleb128p1:无符号LEB128指加1,可变长度1~5字节

uleb128:

1
2
3
4
5
6
00001001 10000111 01100101  624485的2进制表示
0100110 0001110 1100101 把2进制的表示的bit扩展为能被7整除(不足的加0)
0100110 0001110 1100101 再以7-bit为一组进行分组
00100110 10001110 11100101 把第一组+0扩展为8bit,而其余的都+1扩展为8bit
0x26 0x8E 0xE5 结果表示位16进制
0xE5 0x8E 0x26 最终在内存中的表示

sleb128:

1
2
3
4
5
6
11110110 01111000 10011011  -624485的2进制表示(呵呵,负数在计算机中是如何表示的,大家没有忘吧:)补码啊补码)
101100111100010011011 把2进制的表示扩展为能被7整除
101001 1110001 0011011 再以7-bit为一组进行分组
01011001 11110001 10011011 把第一组+0扩展为8bit,而其余的都根据原整形数的符号位来扩展为8bit(所以这里最后两个7bit组都是+1来扩展的)
0x59 0xf1 0x9b 结果表示位16进制
0x9b 0xf1 0x59 最终在内存中的表示

文件结构

dexformat

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
25
26
27
28
/*
* Direct-mapped "header_item" struct.
*/
struct DexHeader {
u1 magic[8]; /* includes version number */
u4 checksum; /* adler32 checksum */
u1 signature[kSHA1DigestLen]; /* SHA-1 hash */
u4 fileSize; /* length of entire file */
u4 headerSize; /* offset to start 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;
};

dexformat

string_ids: the list of DexStringId

1
2
3
struct DexStringId {
u4 stringDataOff; /* file offset to string_data_item */
};

type_ids: the list of DexTypeId

1
2
3
struct DexTypeId {
u4 descriptorIdx; /* index into stringIds list for type descriptor */
};

proto_ids: the list ofDexProtoId

1
2
3
4
5
struct DexProtoId {
u4 shortyIdx; /* index into stringIds for shorty descriptor */
u4 returnTypeIdx; /* index into typeIds list for return type */
u4 parametersOff; /* file offset to type_list for parameter types */
};

field_ids: the list of DexFieldId

1
2
3
4
5
struct DexFieldId {
u2 classIdx; /* index into typeIds list for defining class */
u2 typeIdx; /* index into typeIds for field type */
u4 nameIdx; /* index into stringIds for field name */
};

method_ids: the list of DexMethodId

1
2
3
4
5
struct DexMethodId {
u2 classIdx; /* index into typeIds list for defining class */
u2 protoIdx; /* index into protoIds for method prototype */
u4 nameIdx; /* index into stringIds for method name */
};

class_defs: the list of DexClassDef

1
2
3
4
5
6
7
8
9
10
struct DexClassDef {
u4 classIdx; /* index into typeIds for this class */
u4 accessFlags;
u4 superclassIdx; /* index into typeIds for superclass */
u4 interfacesOff; /* file offset to DexTypeList */
u4 sourceFileIdx; /* index into stringIds for source file name */
u4 annotationsOff; /* file offset to annotations_directory_item */
u4 classDataOff; /* file offset to class_data_item */
u4 staticValuesOff; /* file offset to DexEncodedArray */
};

map:the list of DexMapItem and the list size

1
2
3
4
struct DexMapList {
u4 size; /* #of entries in list */
DexMapItem list[1]; /* entries */
};
1
2
3
4
5
6
struct DexMapItem {
u2 type; /* type code (see kDexType* above) */
u2 unused;
u4 size; /* count of items of the indicated type */
u4 offset; /* file offset to the start of data */
};