1.Soot中语句中如何判断是否是调用语句?
见如下代码:
- 作者会将java代码等,一般转换为Jimple的中间形式。(Jimple可以说是Soot的一个核心)
- 所以对于当我们想获得的信息,最好都从与Jimple相关的对象中获得。(Soot中对于Jimple这种中间的形式进行了对象的建模,从而用对象的形式模拟出Jimple语言中的语句)
private static void testCFG4(SootMethod method){
//1.获取方法体,并转化为JimpleBody,
//JimpleBody 比 Body 要包含更多有用的信息。
JimpleBody body = (JimpleBody)method.retrieveActiveBody();
//2.我们可以据此来绘制出Unit之间的调用图。
UnitGraph g = new BriefUnitGraph(body);
Iterator<Unit> it = g.iterator();
while (it.hasNext()) {
//3.Stmt 是Jimple一条语句的表示形式。(Stmt继承自Unit,所以有更多信息)
Stmt stmt = (Stmt)it.next();
if(stmt.containsInvokeExpr()){
System.out.println("the invoke is : " + stmt.toString() );
System.out.println("the method is : " + tmp.getInvokeExpr().getMethod()); }
}
}
2.Soot中对于switch的处理(Jimple语言)
soot中对于switch的处理是分情况的,他提供了两种建模方式,JTableSwitchStmt以及JLookupSwitchStmt,在其建模中认为case 区分主要为数字。
两者的区别在于:
- 【 JTableSwitchStmt 】switch是分成多种情况的,并且通过数字来进行区分这些情况。如果数字是连续的,比如说,2,3,4,5 ,那么soot就会采取 JTableSwitchStmt 来存储它,因为这样查找效率更高。
- 【 JLookupSwitchStmt 】如果case中构成的数字情况集合是稀疏的,比如,case情况有2,9,100,那么将采取 JLookupSwitchStmt 方式来存储switch相关的一些内容,没有上面的 JTableSwitchStmt 查找效率高,但是节省空间。
举例:
例1: (下面代码在soot中表示为 JTableSwitchStmt)
switch(type){
case 2:
A1();
break;
case 3:
A2();
break;
case 4:
A3();
break;
default:
A3();
}
例2: (下面代码在soot中表示为 JLookupSwitchStmt)
switch(type){
case 2:
A1();
break;
case 5:
A2();
break;
case 9:
A3();
break;
default:
A3();
}
附: 参看JTableSwitchStmt,JLookupSwitchStmt 中的 toString( ) 函数,能了解到更细节的原理。