dexfile
//art/runtime/dex_file.h class DexFile { // Raw header_item. struct Header { uint8_t magic_[8]; uint32_t checksum_; // See also location_checksum_ uint8_t signature_[kSha1DigestSize];//20 uint32_t file_size_; // size of entire file uint32_t header_size_; // offset to start of next section uint32_t endian_tag_; uint32_t link_size_; // unused uint32_t link_off_; // unused uint32_t map_off_; // unused uint32_t string_ids_size_; // number of StringIds uint32_t string_ids_off_; // file offset of StringIds array uint32_t type_ids_size_; // number of TypeIds, we don't support more than 65535 uint32_t type_ids_off_; // file offset of TypeIds array uint32_t proto_ids_size_; // number of ProtoIds, we don't support more than 65535 uint32_t proto_ids_off_; // file offset of ProtoIds array uint32_t field_ids_size_; // number of FieldIds uint32_t field_ids_off_; // file offset of FieldIds array uint32_t method_ids_size_; // number of MethodIds uint32_t method_ids_off_; // file offset of MethodIds array uint32_t class_defs_size_; // number of ClassDefs uint32_t class_defs_off_; // file offset of ClassDef array uint32_t data_size_; // unused uint32_t data_off_; // unused }; // Map item type codes. enum { kDexTypeHeaderItem = 0x0000, kDexTypeStringIdItem = 0x0001, kDexTypeTypeIdItem = 0x0002, kDexTypeProtoIdItem = 0x0003, kDexTypeFieldIdItem = 0x0004, kDexTypeMethodIdItem = 0x0005, kDexTypeClassDefItem = 0x0006, kDexTypeMapList = 0x1000, kDexTypeTypeList = 0x1001, kDexTypeAnnotationSetRefList = 0x1002, kDexTypeAnnotationSetItem = 0x1003, kDexTypeClassDataItem = 0x2000, kDexTypeCodeItem = 0x2001, kDexTypeStringDataItem = 0x2002, kDexTypeDebugInfoItem = 0x2003, kDexTypeAnnotationItem = 0x2004, kDexTypeEncodedArrayItem = 0x2005, kDexTypeAnnotationsDirectoryItem = 0x2006, }; struct MapItem { uint16_t type_; //kDexType开头的类型 uint16_t unused_; //这个字段未使用,用来作字节对齐 uint32_t size_; //指定类型的个数 uint32_t offset_; //指定类型数据的文件偏移值 }; struct MapList { uint32_t size_; //MapItem的个数 MapItem list_[1]; }; // Raw string_id_item. struct StringId { uint32_t string_data_off_; // offset in bytes from the base address private: DISALLOW_COPY_AND_ASSIGN(StringId); }; // Raw type_id_item. struct TypeId { uint32_t descriptor_idx_; // index into string_ids private: DISALLOW_COPY_AND_ASSIGN(TypeId); }; // Raw field_id_item. struct FieldId { uint16_t class_idx_; // index into type_ids_ array for defining class uint16_t type_idx_; // index into type_ids_ array for field type uint32_t name_idx_; // index into string_ids_ array for field name private: DISALLOW_COPY_AND_ASSIGN(FieldId); }; // Raw method_id_item. struct MethodId { uint16_t class_idx_; // index into type_ids_ array for defining class uint16_t proto_idx_; // index into proto_ids_ array for method prototype uint32_t name_idx_; // index into string_ids_ array for method name private: DISALLOW_COPY_AND_ASSIGN(MethodId); }; // Raw proto_id_item. struct ProtoId { uint32_t shorty_idx_; // index into string_ids array for shorty descriptor uint16_t return_type_idx_; // index into type_ids array for return type uint16_t pad_; // padding = 0 uint32_t parameters_off_; // file offset to type_list for parameter types private: DISALLOW_COPY_AND_ASSIGN(ProtoId); }; // Raw class_def_item. struct ClassDef { uint16_t class_idx_; // index into type_ids_ array for this class uint16_t pad1_; // padding = 0 uint32_t access_flags_; uint16_t superclass_idx_; // index into type_ids_ array for superclass uint16_t pad2_; // padding = 0 uint32_t interfaces_off_; // file offset to TypeList uint32_t source_file_idx_; // index into string_ids_ for source file name uint32_t annotations_off_; // file offset to annotations_directory_item uint32_t class_data_off_; // file offset to class_data_item uint32_t static_values_off_; // file offset to EncodedArray // Returns the valid access flags, that is, Java modifier bits relevant to the ClassDef type // (class or interface). These are all in the lower 16b and do not contain runtime flags. uint32_t GetJavaAccessFlags() const { .......... } }; // Raw type_item. struct TypeItem { uint16_t type_idx_; // index into type_ids section }; // Raw type_list. class TypeList { public: uint32_t Size() const { return size_; } const TypeItem& GetTypeItem(uint32_t idx) const { DCHECK_LT(idx, this->size_); return this->list_[idx]; } // Size in bytes of the part of the list that is common. static constexpr size_t GetHeaderSize() { return 4U; } // Size in bytes of the whole type list including all the stored elements. static constexpr size_t GetListSize(size_t count) { return GetHeaderSize() + sizeof(TypeItem) * count; } private: uint32_t size_; // size of the list, in entries TypeItem list_[1]; // elements of the list }; // Raw code_item. struct CodeItem { uint16_t registers_size_; uint16_t ins_size_; uint16_t outs_size_; uint16_t tries_size_; uint32_t debug_info_off_; // file offset to debug info stream uint32_t insns_size_in_code_units_; // size of the insns array, in 2 byte code units uint16_t insns_[1]; }; // Raw try_item. struct TryItem { uint32_t start_addr_; uint16_t insn_count_; uint16_t handler_off_; }; .......... }
//Bleach.java public class Bleach { public static final String TAG = "111111111"; public static final String name = "caoming_123456"; public static final int id1 = 0x333333; private static final int id2 = 0x444444; public static void main(String[] args) { add(id1, id2); } public static int add(int a, int b) { int c = a + b; return c; } }
$ javac Bleach.java $ dx --dex --output=Bleach.dex Bleach.class
// Bleach.dex 0000000: 6465 780a 3033 3500 ff5d 319c a78a 60ba dex.035..]1...`. 0000010: f6ea 6645 dfbc 2572 199b c30a 06a2 965b ..fE..%r.......[ 0000020: 4403 0000 7000 0000 7856 3412 0000 0000 D...p...xV4..... 0000030: 0000 0000 9802 0000 1200 0000 7000 0000 ............p... 0000040: 0600 0000 b800 0000 0300 0000 d000 0000 ................ 0000050: 0400 0000 f400 0000 0400 0000 1401 0000 ................ 0000060: 0100 0000 3401 0000 f001 0000 5401 0000 ....4.......T... 0000070: b601 0000 c101 0000 c901 0000 d601 0000 ................ 0000080: d901 0000 de01 0000 e801 0000 fc01 0000 ................ 0000090: 1002 0000 1502 0000 1802 0000 1c02 0000 ................ 00000a0: 3102 0000 3602 0000 4602 0000 4b02 0000 1...6...F...K... 00000b0: 5002 0000 5602 0000 0300 0000 0500 0000 P...V........... 00000c0: 0600 0000 0700 0000 0900 0000 0b00 0000 ................ 00000d0: 0400 0000 0000 0000 a801 0000 0900 0000 ................ 00000e0: 0400 0000 0000 0000 0a00 0000 0400 0000 ................ 00000f0: b001 0000 0100 0300 0800 0000 0100 0000 ................ 0000100: 0e00 0000 0100 0000 0f00 0000 0100 0300 ................ 0000110: 1100 0000 0100 0100 0100 0000 0100 0000 ................ 0000120: 0c00 0000 0100 0200 1000 0000 0200 0100 ................ 0000130: 0100 0000 0100 0000 0100 0000 0200 0000 ................ 0000140: 0000 0000 0200 0000 0000 0000 7d02 0000 ............}... 0000150: 7002 0000 0100 0100 0100 0000 5c02 0000 p...........\... 0000160: 0400 0000 7010 0300 0000 0e00 0300 0200 ....p........... 0000170: 0000 0000 6102 0000 0300 0000 9000 0102 ....a........... 0000180: 0f00 0000 0300 0100 0200 0000 6902 0000 ............i... 0000190: 0a00 0000 1400 3333 3300 1401 4444 4400 ......333...DDD. 00001a0: 7120 0100 1000 0e00 0200 0000 0000 0000 q .............. 00001b0: 0100 0000 0500 0931 3131 3131 3131 3131 .......111111111 00001c0: 0006 3c69 6e69 743e 000b 426c 6561 6368 ..<init>..Bleach 00001d0: 2e6a 6176 6100 0149 0003 4949 4900 084c .java..I..III..L 00001e0: 426c 6561 6368 3b00 124c 6a61 7661 2f6c Bleach;..Ljava/l 00001f0: 616e 672f 4f62 6a65 6374 3b00 124c 6a61 ang/Object;..Lja 0000200: 7661 2f6c 616e 672f 5374 7269 6e67 3b00 va/lang/String;. 0000210: 0354 4147 0001 5600 0256 4c00 135b 4c6a .TAG..V..VL..[Lj 0000220: 6176 612f 6c61 6e67 2f53 7472 696e 673b ava/lang/String; 0000230: 0003 6164 6400 0e63 616f 6d69 6e67 5f31 ..add..caoming_1 0000240: 3233 3435 3600 0369 6431 0003 6964 3200 23456..id1..id2. 0000250: 046d 6169 6e00 046e 616d 6500 0100 070e .main..name..... 0000260: 000d 0200 0007 0e2d 0009 0100 070e 9600 .......-........ 0000270: 0417 0044 3333 3344 4444 4417 0d04 0003 ...D333DDDD..... 0000280: 0000 1901 1901 1a01 1900 8180 04d4 0201 ................ 0000290: 09ec 0201 0984 0300 0e00 0000 0000 0000 ................ 00002a0: 0100 0000 0000 0000 0100 0000 1200 0000 ................ 00002b0: 7000 0000 0200 0000 0600 0000 b800 0000 p............... 00002c0: 0300 0000 0300 0000 d000 0000 0400 0000 ................ 00002d0: 0400 0000 f400 0000 0500 0000 0400 0000 ................ 00002e0: 1401 0000 0600 0000 0100 0000 3401 0000 ............4... 00002f0: 0120 0000 0300 0000 5401 0000 0110 0000 . ......T....... 0000300: 0200 0000 a801 0000 0220 0000 1200 0000 ......... ...... 0000310: b601 0000 0320 0000 0300 0000 5c02 0000 ..... ......\... 0000320: 0520 0000 0100 0000 7002 0000 0020 0000 . ......p.... .. 0000330: 0100 0000 7d02 0000 0010 0000 0100 0000 ....}........... 0000340: 9802 0000 ....
magic字段为8个字节,标示一个有效的dex文件它的值固定为6465 780a 3033 3500
转换为字符串为“dex.035.”
checksum字段为4个字节 ff5d 319c
哈希值为20个字节
a78a 60ba f6ea 6645 dfbc 2572 199b c30a 06a2 965b
fileSize 4个字节 为整个文件大小:4403 0000
0x(0000 0344) = 836
mutian@mutian:~/Desktop/test$ ll
-rw-rw-r-- 1 mutian mutian 836 Jan 29 10:58 Bleach.dex
HeaderSize DexHeader结构大小,为固定值7000 0000
0x(0000 0070) = 112
endianTag字段指定了dex运行环境的cpu字节序
预设值ENDIAN_CONSTANT = 0x12345678表示默认采用Little-Endian字节序, 即小端字节序
linkSize字段与stringIdsOff字段指定链接段的大小与文件偏移,大多数情况下他们值都为0
mapOff字段指定了DexMapList结构的文件偏移:9802 0000
偏移地址map_off_=0x(0000 0298)
[0x0298] = 0e00 0000 即MapList.size_ = 0x(0000 000e) 表示后面有14个MapItem
0000 0000 0100 0000 0000 0000
0100 0000 1200 0000 7000 0000
0200 0000 0600 0000 b800 0000
0300 0000 0300 0000 d000 0000
0400 0000 0400 0000 f400 0000
.............................
分析第一个MapItem
0000 0000 0100 0000 0000 0000
类型为0(kDexTypeHeaderItem),个数为1,偏移为0
分析第二个MapItem
0100 0000 1200 0000 7000 0000
类型为1(kDexTypeStringIdItem),个数为0x(0000 0012)=18,也就是说有18个字符串。
字符串指针数组的首地址为0x(0000 0070)
0000070: b601 0000 c101 0000 c901 0000 d601 0000 ................ 0000080: d901 0000 de01 0000 e801 0000 fc01 0000 ................ 0000090: 1002 0000 1502 0000 1802 0000 1c02 0000 ................ 00000a0: 3102 0000 3602 0000 4602 0000 4b02 0000 1...6...F...K... 00000b0: 5002 0000 5602 0000
这18个字符串的存放地址依次为0x(0000 01b6) 0x(0000 01c1) 0x(0000 01c9) 0x(0000 01d6) ......
这里以第一个字符串为例,其存放地址为0x(0000 01b6)
00001b0: 0100 0000 0500 0931 3131 3131 3131 3131 .......111111111 00001c0: 0006 3c69 6e69 743e 000b 426c 6561 6368 ..<init>..Bleach
第一个字节0x(09)表示字符串的长度(字符串结束标识符不计算在内)
所以字符串内容为31 3131 3131 3131 3131,即“111111111”
第二个字符串,其存放地址0x(0000 01c1)
字符串长度为0x(06),内容为3c69 6e69 743e,即“<init>”
其它字段类推。
其它MapItem类推

浙公网安备 33010602011771号