您的位置:首页 > 理论基础 > 数据结构算法

android dex文件中try块数据结构中各个字段的含义

2015-02-26 16:21 691 查看
今天看android逆向方法中关于try块的处理,java代码如下:

private void tryCatch(int drumsticks, String peple) {
        try {
            int i = Integer.parseInt(peple);
            try {
                int m = drumsticks / i;
                int n = drumsticks - m * i;
                String str = String.format("共有%d只鸡腿,%d个人平分,每人可分得%d只,还剩下%d只",
                        drumsticks, i, m, n);
                Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
            } catch (ArithmeticException e) {
                Toast.makeText(MainActivity.this, "人数不能为0", Toast.LENGTH_SHORT).show();
            }
        } catch (NumberFormatException e) {
            Toast.makeText(MainActivity.this, "无效的数值字符串", Toast.LENGTH_SHORT).show();
        }
        
    }


这个方法对应的smali代码如下:

0  (00000000) const/4             v9, 0 
        1  (00000002) invoke-static       v12, Ljava/lang/Integer;->parseInt(Ljava/lang/String;)I 
        2  (00000008) move-result         v1 
        3  (0000000a) div-int             v2, v11, v1 
        4  (0000000e) mul-int             v5, v2, v1 
        5  (00000012) sub-int             v3, v11, v5 
        6  (00000016) const-string        v5, u'\u5171\u6709%d\u53ea\u9e21\u817f\uff0c%d\u4e2a\u4eba\u5e73\u5206\uff0c\u6bcf\u4eba\u53ef\u5206\u5f97%d\u53ea\uff0c\u8fd8\u5269\u4e0b%d\u53ea' 
        7  (0000001a) const/4             v6, 4 
        8  (0000001c) new-array           v6, v6, [Ljava/lang/Object; 
        9  (00000020) const/4             v7, 0 
        10 (00000022) invoke-static       v11, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer; 
        11 (00000028) move-result-object  v8 
        12 (0000002a) aput-object         v8, v6, v7 
        13 (0000002e) const/4             v7, 1 
        14 (00000030) invoke-static       v1, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer; 
        15 (00000036) move-result-object  v8 
        16 (00000038) aput-object         v8, v6, v7 
        17 (0000003c) const/4             v7, 2 
        18 (0000003e) invoke-static       v2, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer; 
        19 (00000044) move-result-object  v8 
        20 (00000046) aput-object         v8, v6, v7 
        21 (0000004a) const/4             v7, 3 
        22 (0000004c) invoke-static       v3, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer; 
        23 (00000052) move-result-object  v8 
        24 (00000054) aput-object         v8, v6, v7 
        25 (00000058) invoke-static       v5, v6, Ljava/lang/String;->format(Ljava/lang/String; [Ljava/lang/Object;)Ljava/lang/String; 
        26 (0000005e) move-result-object  v4 
        27 (00000060) const/4             v5, 0 
        28 (00000062) invoke-static       v10, v4, v5, Landroid/widget/Toast;->makeText(Landroid/content/Context; Ljava/lang/CharSequence; I)Landroid/widget/Toast; 
        29 (00000068) move-result-object  v5 
        30 (0000006a) invoke-virtual      v5, Landroid/widget/Toast;->show()V 
        31 (00000070) return-void          
        32 (00000072) move-exception      v0 
        33 (00000074) const-string        v5, u'\u4eba\u6570\u4e0d\u80fd\u4e3a0' 
        34 (00000078) const/4             v6, 0 
        35 (0000007a) invoke-static       v10, v5, v6, Landroid/widget/Toast;->makeText(Landroid/content/Context; Ljava/lang/CharSequence; I)Landroid/widget/Toast; 
        36 (00000080) move-result-object  v5 
        37 (00000082) invoke-virtual      v5, Landroid/widget/Toast;->show()V 
        38 (00000088) goto                -12 
        39 (0000008a) move-exception      v0 
        40 (0000008c) const-string        v5, u'\u65e0\u6548\u7684\u6570\u503c\u5b57\u7b26\u4e32' 
        41 (00000090) invoke-static       v10, v5, v9, Landroid/widget/Toast;->makeText(Landroid/content/Context; Ljava/lang/CharSequence; I)Landroid/widget/Toast; 
        42 (00000096) move-result-object  v5 
        43 (00000098) invoke-virtual      v5, Landroid/widget/Toast;->show()V 
        44 (0000009e) goto
dexdump classes.dex >dump.txt后,tryCatch方法对应的内容如下:

name          : 'tryCatch'
      type          : '(ILjava/lang/String;)V'
      access        : 0x0002 (PRIVATE)
      code          -
      registers     : 13
      ins           : 3
      outs          : 3
      insns size    : 80 16-bit code units
      catches       : 3
        0x0001 - 0x0004
          Ljava/lang/NumberFormatException; -> 0x0045
        0x0005 - 0x0038
          Ljava/lang/ArithmeticException; -> 0x0039
          Ljava/lang/NumberFormatException; -> 0x0045
        <strong><span style="color:#ff0000;">0x003a - 0x0044</span></strong>
          Ljava/lang/NumberFormatException; -> 0x0045


dump.txt文件中的catches为3说明存在3个try块,但是上面java代码中却只是存在2个try语句,下面分析一下原因。

第三个try块的起始偏移地址和终止偏移地址(想对于函数的开始地址)分别为0x003a和0x0044,一个偏移地址单位是16bit,因此第三个try块的开始偏移地址是0x0070,终止偏移地址是0x0088,这个try块对应的smali代码为:

(00000070) return-void          
        32 (00000072) move-exception      v0 
        33 (00000074) const-string        v5, u'\u4eba\u6570\u4e0d\u80fd\u4e3a0' 
        34 (00000078) const/4             v6, 0 
        35 (0000007a) invoke-static       v10, v5, v6, Landroid/widget/Toast;->makeText(Landroid/content/Context; Ljava/lang/CharSequence; I)Landroid/widget/Toast; 
        36 (00000080) move-result-object  v5 
        37 (00000082) invoke-virtual      v5, Landroid/widget/Toast;->show()V 
        38 (00000088) goto
根据smali代码得到的java代码为:

catch (ArithmeticException e) {
                Toast.makeText(MainActivity.this, "人数不能为0", Toast.LENGTH_SHORT).show();
            }
由此可以得出结论:第三个try块对应于java代码中第一个try语句对应的catch代码块

这也是可以理解的,如下catch块

catch (ArithmeticException e) {
                Toast.makeText(MainActivity.this, "人数不能为0", Toast.LENGTH_SHORT).show();
            }


在执行的时候,如果出现了异常,如下catch块能够照常捕获异常

catch (NumberFormatException e) {
            Toast.makeText(MainActivity.this, "无效的数值字符串", Toast.LENGTH_SHORT).show();
        }


在android中,一个try块的数据结构为:

typedef struct DexTry {

u4 startAddr; /* start address, in 16-bit code units */

u2 insnCount; /* instruction count, in 16-bit code units

*/

u2 handlerOff; /* offset in encoded handler data to

handlers */

} DexTry;

注意insnCount表示的不是这个try块的实际指令个数,而是这个try块占用的16bit的个数
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: