smali 语法 - iterator & switch-case & try-catch
本文环境
java version "1.7.0_75"dx version 1.11baksmali 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 的数据:
可用来验证结果