smali 语法 - iterator & switch-case & try-catch
本文环境
java version "1.7.0_75"
dx version 1.11
baksmali 2.1.0
iterator
(for 和 while-do 两种形式)
java 代码
|
|
smali 代码
|
|
两种方式完全一样啊
switch
java 代码
|
|
smali 代码
|
|
switch 指令格式
|
|
AA
表示要判断的值BBBB
表示相应 switch-payload 的偏移
两种 switch-payload 的格式
(1) packed-switch-payload format
Name | Format | Description |
---|---|---|
ident | ushort = 0x0100 | 固定值 |
size | ushort | 入口的个数 |
first_key | int | 第一个switch的值(最小的) |
targets | int[] | 每个case相对于switch指令的偏移,而非此矩阵 |
(2) sparse-switch-payload format
Name | Format | Description |
---|---|---|
ident | ushort = 0x0200 | 固定值 |
size | ushort | 入口的个数 |
keys | int[] | case的值,从低到高 |
targets | int[] | 每个case相对于switch指令的偏移,而非此矩阵 |
验证
由官方文档可得packed-switch
的 opcode 为 2b
,sparse-switch
的 opcode 为 2c
.
在16进制编辑器中搜索 2b
,可得两条 switch 的位置(0x146, 0x14c),从 smali 代码中也能看出他们是相邻的。(当然这一步可用ida直接搜索packed-swtch更方便)
第一条翻译为:packed-switch v0,146h+2*3bh
,得矩阵的偏移为 0x1bc.
ident
: 0x0100size
: 0x04first_key
: 0x0targets
: 0x07, 0x0c, 0x12, 0x18
如:0x146+2*0x07=0x154 即为 case 0 对应的代码地址。
第二条翻译为:sparse-switch v0,14ch+2*44h
,得矩阵的偏移为 0x1d4.
ident
: 0x0200size
: 0x04keys
: 0x00, 0x02, 0x04, 0x08targets
: 0x1c, 0x21, 0x28, 0x2f
如:0x14c+2*0x1c=0x184 即为 case 0 对应的代码地址。
try
java 代码:
|
|
smali 代码:
|
|
格式
try 代码块以两个标号为界,:try_start_数字
和 :try_end_数字
,(不晓得这一段的数字为什么没有规律)。
紧接着是 catch 的格式:.catch 异常类 {try起始标号 .. try结束标号} catch代码标号
java 并没有对重复的 catch 代码进行优化,但是变量的定义被挪到了 try 之外。
嵌套的 try-catch 被分成了单个的 try-catch .
try 在 dex 中的存在
关于try-catch是如何在dex文件中存在的参考解析 dex 文件结构 - 索引区和数据区(三) - ClassDefs .
下面是手动查找:
前期准备:
classDefsSize: 0x1
classDefsOff: 0x128
directMethodsSize: 0x2
func函数的codeOff: 0x160
DexCode.triesSize: 0x05
try-catch 地址: 0x204,数据如下:
首先是0x5个DexTry,
startAddr | insnCount | handlerOff | 对应的异常和handler(由下表所得) |
---|---|---|---|
0x02 | 0x02 | 0x01 | 0号handler: 抓到 ArithmeticException |
0x07 | 0x02 | 0x04 | 1号handler: 抓到 ArithmeticException和Exception |
0x0c | 0x02 | 0x09 | 2号handler: 抓到 ArithmeticException和Exception |
0x0f | 0x08 | 0x0e | 3号handler: 抓到 Exception |
0x32 | 0x07 | 0x0e | 3号handler: 抓到 Exception |
[注]这里的handleroff是以handler_list为起始的偏移
catch_handler列表个数
: 0x04
下面是0x04个catch_handler:
序号 | size | typeId | addr | catch_all_addr |
---|---|---|---|---|
0x0 | 0x01 | 0x02(java.lang.ArithmeticException) | 0x18 | - |
0x1 | 0x02 | 0x02(java.lang.ArithmeticException) | 0x21 | - |
- | - | 0x03(java.lang.Exception) | 0x2a | - |
0x2 | 0x02 | 0x02(java.lang.ArithmeticException) | 0x31 | - |
- | - | 0x03(java.lang.Exception) | 0x3a | - |
0x03 | 0x01 | 0x03(java.lang.Exception) | 0x3a | - |
下面是使用 dexdump 的数据:
可用来验证结果