Dalvik指令分析(三) dex文件的结构

以上一篇文章生成的dex文件为例,讲解dex文件结构,这个dex文件结构非常简单,只有一个HelloWorld.java

文件,dex文件的基本格式请参考官方文档,对照dex文件的各个组成部分,我们可以将dex的内容进行分解。

1、文件头上述dex文件header部分的内容如下:

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现在开始分解header部分的内容:64 65 78 0A 30 33 35 00这部分是dex_magic的值对应的ASCII码值为:dex 03552 5B 33 08

这部分是checksum,计算checksum的逻辑如下面的代码:

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);}其中,参数bytes[]为dex文件的字节流,计算出来的值写入bytes数组中,下标为8-11D6 16 D3 44 F7 27 50 E9 D6 16 9A 3E 6D 53 EF F992 28 70 FA这部分是sha1的签名,计算signature的逻辑如下: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这部分是文件大小:即0x0298=664bytes70 00 00 00这部分是头的大小,112bytes78 56 34 12这部分是大小端的标志,dex文件缺省是小端的,这个dex文件是小端的,因为对应的值为0x12345678,系统

里的定义如下:

uint ENDIAN_CONSTANT = 0x12345678;uint REVERSE_ENDIAN_CONSTANT = 0x78563412;00 00 00 00 00 00 00 00这全0的八字节是link_size和link_off字段,主要用在文件的静态链接上,该dex不是静态链接文件,所有为004 02 00 00

这部分为map_off字段,值为0x204,即516,这个值是map_list所在位置相对文件起始位置的偏移量。map_list

是对整个dex文件的描述,分不同的类型,包括头、字符串、类型、函数原型、类、代码等等,其实和header的

信息有一些冗余,主要是在dex文件生成后对文件做一些校验工作,dx进程在生成dex文件后,会根据map_list的

内容对dex做一些校验工作,,这个在后面介绍dx进程的时候会描述。

0C 00 00 00 70 00 00 00这部分内容为string_ids_size和string_ids_off,各占四字节

和map_list类似,string也有一个string_list,上面的两个值就是用来标识有多少个字符串,以及string_list

的偏移的。

header部分余下的都是各个list的长度和对应的偏移量,如type_ids_size和type_ids_off,指向type_list,

还有proto_list,field_list,method_list,code_item_list, class_def_item_list,data_list。这些list包含了

dex header部分的分析基本完成了,header部分是整个dex文件的描述,也是文件各部分内容的索引,

掌握了header部分就可以继续分析其他部分内容,比如method_list,比如code_item_list。

在分析的过程中,要经常参考android源码,主要是数据结构的定义,因为涉及到数据元素的大小以及

成员,所以还是很费时间和精力的,但是这些都很有意义,让您在理解了一个可执行文件的结构的同时,

也熟悉android的源码。如果您在分析其他部分时,碰到问题可以联系我,在时间允许的情况下我会帮

您一起分析、解答问题。

在繁华中体会热闹;若是厌倦了喧嚣,寻一处宁静的幽谷,

Dalvik指令分析(三) dex文件的结构

相关文章:

你感兴趣的文章:

标签云: