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

来源:互联网 发布:js 判断函数是否定义 编辑:程序博客网 时间:2024/04/28 18:24

    今天看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的个数

0 0