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;}
|
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 结构 # }
|
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 结构的偏移 # }
|