Dalvik switch语句


struct packed-switch-payload{
 ushort ident; //值固定为0x100
 ushort size; //case数目
 int first_key; //初始case的值
 int[] targets; //每个case相对switch指令处的偏移
};

打开IDA Pro找到“packed-switch p1, :pswitch_data_0"指令位于0x2CB1A处,相应的机器码为”2B 02 13 00 00 00“,手动分析机器码如下:

2B 为packed-switch的OpCode

02 为寄存器p1

00000013为偏移量0x13

Dalvik中计算偏移量是以两个字节为单位,因此实际该指令指向的packed-switch-payload结构体的偏移量为0x2CB1A+2*0x13  = 0x2CB40。使用C32asm查看该处的数据,如下图所示:


第1个ident字段为0x100,标识packed-switch有效的case区域。第二个字段size为4,表明有4个case。第3个字段first_key为0,表明初始case值为0。第四个字段为偏移量,分别为0x6、0x9、0xC、0xF,加上packed-switch指令的偏移值0x2CB1A,计算可得:

case 0位置 = 0x2CB1A+2* 0x6 = 0x2CB26

case 1位置 = 0x2CB1A+2* 0x9 = 0x2CB2C

case 2位置 = 0x2CB1A+2* 0xC = 0x2CB32

case 3位置 = 0x2CB1A +2× 0xF = 0x2CB38

至此,有规律递增的switch分析就算是搞明白了。最后将这段smali代码整理为Java代码如下。

private String packedSwitch(int i){
 String str = null;
 switch(i) {
  case 0:
         str = "she is a baby";
         break;
  case 1:
         str = "she is a girl";
         break;
   case 2:
          str = "she is a woman";
          break;
   case 3:
          str = "she is an obasan";
          break;
   default:
          str = "she is a person";
          break;
 }
 return str;
}
代码中的switch分支使用的是sparse-switch指令。按照分析packed-switch的方法,我们直接查看sswitch_data_0标号出的内容。可以看到“.sparse-switch”指令没有给出初始case的值,所有的case值都使用“case值->case标号”的形式给出。此处共有4个case,它们的内容都是构造一个字符串,然后跳转到goto_0标号处,代码架构上与packed-switch方式的switch分支一样。

sparse-switch指令在Dalvik中的格式如下:

sparse-switch vAA , +BBBBBBBB

指令后面的“+BBBBBBBB”被指明为一个sparse-switch-payload格式的偏移。它的格式如下。

struct sparse-switch-payload{
 ushort ident; //值固定为0x0200
 ushort size; //case数目
 int[] keys; //每个case的值,顺序从低到高
 int[] targets; //每个case相对switch指令处的偏移
};
同样的,打开IDA Pro找到“sparse-switch p1, :sswitch_data_0”指令位于0x2CB6A处,相应的机器码为“2C 02 13 00 00 00”,手动分析机器码如下:

2C 为sparse-switch的OpCode。

02 为寄存器p1。

00000013为偏移量0x13。

因此实际该指令指向的sparse-switch-payload结构体的偏移量为0x2CB6A + 2 * 0x13 = 0x2CB90。该处的数据如下图所示:


第1个ident字段为0x200,标识sparse-switch有效的case区域。第2个字段size为4,表明有4个case。第3个字段keys为4个case的值,分别为0x5、0xF、0x23、0x41。第4个字段分别为偏移量,分别为0x6、0x9、0xC、0xF,加上sparse-switch指令的偏移值0x2CB6A,计算可得:

case 0 位置 = 0x2CB6A + 2 * 0x6 = 0x2CB76

case 1 位置 = 0x2CB6A + 2 * 0x9 = 0x2CB7C

case 2 位置 = 0x2CB6A + 2 * 0xC = 0x2CB82

case 3 位置 = 0x2CB6A + 2 * 0xF = 0x2CB88

最后,将这段smali代码整理为Java代码如下:

private String sparseSwitch(int age){
 String str = NULL;
 switch(age) {
  case 5:
          str = "he is a baby";
          break;
  case 15:
          str = "he is a student";
          break;
  case 35:
          str = "he is a father";
          break;
  case 65:
          str = "he is a grandpa";
          break;
  default:
          str = "he is a person";
          break;
 }
 return str;
}



  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值