Dalvik command analysis (3) dex file structure, dalvikdex
Take the dex file generated in the previous article as an example to explain the dex file structure. The dex file structure is very simple, and there is only one HelloWorld. java
For the basic format of the dex file, refer to the official documentation. We can break down the dex content according to the components of the dex file.
1. File Header
Header |
Header_item |
The header |
The content of the above dex file header is as follows:
64 65 78 0A 30 33 35 00 52 5B 33 08 D6 16 D3 44F7 27 50 E9 D6 16 9A 3E 6D 53 EF F9 92 28 70 FA98 02 00 00 70 00 00 00 78 56 34 12 00 00 00 0000 00 00 00 04 02 00 00 0C 00 00 00 70 00 00 0006 00 00 00 A0 00 00 00 02 00 00 00 B8 00 00 0001 00 00 00 D0 00 00 00 04 00 00 00 D8 00 00 0001 00 00 00 F8 00 00 00 80 01 00 00 18 01 00 00
Start to parse the header content:
64 65 78 0A 30 33 35 00
This part is the ASCII code value corresponding to the value of dex_magic: dex 035
52 5B 33 08
This part is checksum. The logic for calculating checksum is as follows:
private static void calcChecksum(byte bytes[]) {Adler32 a32 = new Adler32();a32.update(bytes, 12, bytes.length - 12);int sum = (int) a32.getValue();checksum[0] = (byte) sum;checksum[1] = (byte) (sum >> 8);checksum[2] = (byte) (sum >> 16);checksum[3] = (byte) (sum >> 24);try {String decoded = new String(checksum, "UTF-8");System.out.println(decoded);} catch (UnsupportedEncodingException e) {e.printStackTrace();}bytes[8] = (byte) sum;bytes[9] = (byte) (sum >> 8);bytes[10] = (byte) (sum >> 16);bytes[11] = (byte) (sum >> 24);}
The bytes [] parameter is the byte stream of the dex file. The calculated value is written into the bytes array with the subscript 8-11.
D6 16 D3 44 F7 27 50 E9 D6 16 9A 3E 6D 53 EF F992 28 70 FA
This part is the sha1 signature. The logic for calculating signature is as follows:
private static void calcSignature(byte bytes[]) {MessageDigest md;try {md = MessageDigest.getInstance("SHA-1");} catch (NoSuchAlgorithmException ex) {throw new RuntimeException(ex);}md.update(bytes, 32, bytes.length - 32);try {int amt = md.digest(bytes, 12, 20);if (amt != 20)throw new RuntimeException((new StringBuilder()).append("unexpected digest write:").append(amt).append("bytes").toString());} catch (DigestException ex) {throw new RuntimeException(ex);}}
98 02 00 00
This part is the file size: 0x0298 = 664 bytes
70 00 00 00
This part is the size of the header, 112 bytes
78 56 34 12
This part is the size flag. By default, the dex file is small. This dex file is small, because the corresponding value is 0x12345678.
Is defined as follows:
uint ENDIAN_CONSTANT = 0x12345678;uint REVERSE_ENDIAN_CONSTANT = 0x78563412;
00 00 00 00 00 00 00 00
The eight-character section of 0 contains the link_size and link_off fields, which are mainly used for static links of files. This dex is not a static link file and has 0
04 02 00 00
This part is divided into the map_off field. The value is 0x204, that is, 516. This value is the offset of the position of map_list relative to the start position of the file. Map_list
Is the description of the entire dex file, divided into different types, including header, String, type, function prototype, class, code, etc., in fact, and header
Information is redundant, mainly after the dex file is generated, the file is verified. After the dx process generates the dex file
The content performs some verification on dex, which will be described later when the dx process is introduced.
0C 00 00 00 70 00 00 00
This part of content is string_ids_size and string_ids_off, each of which occupies four bytes.
Similar to map_list, string also has a string_list. The above two values are used to identify the number of strings and string_list
.
The rest of the header is the length of each list and the corresponding offset, such as type_ids_size and type_ids_off, pointing to type_list,
There are also proto_list, field_list, method_list, code_item_list, class_def_item_list, and data_list. These lists contain
The string information, function prototype, field, function description, and class description information in the program constitute all program content.
The analysis of the dex header is basically complete. The header part is the description of the entire dex file and the index of each part of the file,
After you have mastered the header part, you can continue to analyze other parts, such as method_list, such as code_item_list.
In the process of analysis, you should often refer to the android source code, mainly the definition of the data structure, because it involves the size of data elements and
It takes a lot of time and effort, but it makes sense to understand the structure of an executable file,
You are also familiar with the android source code. If you encounter problems when analyzing other parts, contact me. If time permits, I will help you
You can analyze and answer questions together.