-
-
[原创]Smali中异常----有无finally的区别
-
发表于: 2017-9-2 02:38 2965
-
写在前面:
1. 第一次发帖;
2. 不会排版;
3. 文中纯属个人理解, 如有错误请指出, 感谢!
因为上课走神, 没听明白, 所以就写了一个小例子, 把自己的理解写了下来希望能交流一下;
环境:
编译工具:Eclipse
反编译工具:JEB 2.2.7
系统环境:Win7 64
0x1 什么是try catch表
一般java函数内有写的try catch, 在其函数下面就会有生成对应的try catch表, 因为IDA与JEB生成的表格式不同, 这里只说JEB的;
就是这个样子, 后面说格式;
0x2 不加finally的try catch
比较简单就直接贴代码了;
java函数例子代码:
public void Mytest1()
{
FileOutputStream fos = null;
try {
File file = new File(getFilesDir(), "mytest");
fos = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
jeb反编译的smali代码:
不加finally的结构很简单, 一般根据try块标号可以确定catch块的数量, 之后再细看每个块中的实现 (嵌套的依旧是很坑的);
JEB中trycatch表结构:
.catch [异常类型] {[try块开始标号], [try块结束标号]} :[catch代码开始处标号]
0x3 加finally的try catch
finally 语句块作用:执行一些必要代码。即不管出现异常与否,在finally中的代码都会被执行
执行时机:针对所有catch语句之后,退出方法之前将被执行;
java函数例子代码:
public void Mytest()
{
FileOutputStream fos = null;
try {
File file = new File(getFilesDir(), "mytest");
fos = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
Log.d("Mytest", "finally");
}
}
JEB里trycatch表有名称catchall代表是有finally块语句, 但可不是有几个cathall就有几个finally哦;
其结构为:
.catchall {[catch代码开始标号], [catch代码结束标号]}} :[统一处理块代码标号]
jeb反编译的smali代码:
通过以上图得出的理解:
1. 代码生成过程中会编译器会把finally块内代码在每个catch内拷贝一份, 以达到一定能执行finally块中的代码的目的;
2. 因为catch代码也可能会出现异常, 所以编译器会给每个catch块中的代码再生成一份统一异常处理代码, 这份代码里依旧会执行finally块中的代码, 但是此时的异常没有处理, 所以编译器选择抛出异常;