一、dexdump简介
dexdump是android提供的一个dex文件查看工具,在4.4之前的版本上,我们可以在dalvik的dexdump目录找到源码。这个工具简单而且全面。通过学习这个工具的源码,我们可以很快的对dex文件有一个全面的了解。
首先看下dexdump的命令行参数:
dexdump: [-c] [-d] [-f] [-h] [-i] [-l layout] [-m] [-t tempfile]
dexfile…-c : verify checksum and exit
-d : disassemble code sections
-f : display summary information from file header
-h : display file header details
-i : ignore checksum failures
-l : output layout, either ‘plain’ or ‘xml’
-m : dump register maps (and nothing else)
-t : temp file name (defaults to /sdcard/dex-temp-*)
参数都很浅显易懂,没有什么好说的。因为dex文件是多个class的集合,因此我们只要看每个class是怎样定义的即可。下面这个例子是一个最简单的class,没有任何field,只要一个无代码的方法,dump出的结果如下:
Class #110 -
Class descriptor : 'Landroid/widget/Filterable;'
Access flags : 0x0601 (PUBLIC INTERFACE ABSTRACT)
Superclass : 'Ljava/lang/Object;'
Interfaces -
Static fields -
Instance fields -
Direct methods -
Virtual methods -
#0 : (in Landroid/widget/Filterable;)
name : 'getFilter'
type : '()Landroid/widget/Filter;'
access : 0x0401 (PUBLIC ABSTRACT)
code : (none)
source_file_idx : 12206 (Filterable.java)
可以看到,dexdump按照类的定义,清晰的列出了其结构和内容。
下面看一个对field的dump(static和instance field的dump是一样的)
#1 : (in Landroid/app/Activity;)
name : 'DEFAULT_KEYS_DIALER'
type : 'I'
access : 0x0019 (PUBLIC STATIC FINAL)
给出了field的name, type, access这些定义。
在看method的定义
#12 : (in Landroid/widget/ArrayAdapter;)
name : 'createViewFromResource'
type : '(ILandroid/view/View;Landroid/view/ViewGroup;I)Landroid/view/View;'
access : 0x0002 (PRIVATE)
code -
registers : 12
ins : 5
outs : 4
insns size : 66 16-bit code units
18abd4: |[18abd4] android.widget.ArrayAdapter.createViewFromResource:(ILandroid/view/View;Landroid/view/ViewGroup;I)Landroid/view/View;
18abe4: 3909 1f00 |0000: if-nez v9, 001f // +001f
....
18abec: 1206 |0004: const/4 v6, #int 0 // #0
.....
18ac60: 6e20 6bde 5300 |003e: invoke-virtual {v3, v5}, Landroid/widget/TextView;.setText:(Ljava/lang/CharSequence;)V // method@de6b
18ac66: 28dd |0041: goto 001e // -0023
catches : 2
0x0009 - 0x0011
Ljava/lang/ClassCastException; -> 0x002a
0x0021 - 0x0029
Ljava/lang/ClassCastException; -> 0x002a
positions :
0x0000 line=370
0x0002 line=371
0x0009 line=377
0x000d line=379
....
0x0032 line=386
0x003a line=394
locals :
0x0000 - 0x0000 reg=7 this Landroid/widget/ArrayAdapter;
0x0015 - 0x001b reg=2 item Ljava/lang/Object; TT;
...
0x0000 - 0x0042 reg=10 parent Landroid/view/ViewGroup;
0x0000 - 0x0042 reg=11 resource I
因为例子很长,且我们关心的是method的格式,所以我省略了很多细节内容。可以清楚的看到,dump出的内容包括method的信息头(名字、类型、权限)、代码段的信息(大小、寄存器总数、参数个数等)、代码段内容、catch内容、源码与字节码的行对应关系、寄存器与变量的对应关系。
其中行号对应与变量对应关系是调试、抛出异常时必须的内容。这两部分内容开始的位置都是基于本方法代码的开头位置,通过字节码的偏移范围来实现的。
如何在调用dexdump时加上-h选项,就会得到关于class header的信息,这些信息是更加原始的关于class定义的信息。例如下面的例子
Class #0 header:
class_idx : 6
access_flags : 17 (0x0011)
superclass_idx : 5731
interfaces_off : 0 (0x000000)
source_file_idx :