通过dexdump来学习DEX文件格式

一、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     : 
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值