soot插桩关键点总结(三)
2016-05-18 11:11
246 查看
一 插入字段
给某个SootClass插入字段,关键API为new SootField(String,Type,int);//向sootclass添加静态Intent intent_for_ipc字段 SootField intent_for_ipc = new SootField("intent_for_ipc", intentSootClass.getType(),Modifier.STATIC); sootclass.addField(intent_for_ipc);注意:一般是在wjtp下给某个SootClass插入字段
二 构造方法
1. 构造没有参数的方法
SootMethod sm = new SootMethod("getIntent", Arrays.asList(new Type[]{}), RefType.v("java.lang.String"), Modifier.PUBLIC);
2. 构造对象为参数的方法
SootClass intentSootClass = Scene.v().getSootClass("android.content.Intent"); SootMethod sm = new SootMethod("getIntent", Arrays.asList(new Type[]{}), intentSootClass.getType(),Modifier.PUBLIC);
3. 构造数组为参数的方法
method=new SootMethod("main",Arrays.asList(newType[]{ArrayType.v(RefType.v("java.lang.String"), 1)}),VoidType.v(),Modifier.PUBLIC|Modifier.STATIC);
4. 构造多个参数的方法
SootMethod smmm = new SootMethod("mulPara",Arrays.asList(new Type[]{RefType.v("java.lang.String"),intentSootClass.getType()}),VoidType.v(), Modifier.PUBLIC);
三 字段赋值
在(一)中给出了向某个SootClass插入字段的关键代码,那么针对字段该如何赋值呢?下面给出非静态字段赋值与静态字段赋值的方法1. 静态字段赋值
关键API位:Jimple.v().newStaticFieldRef(intent_for_ipc_makeRef())和Jimple.v().newAssignStmt()//保存参数 Local arg = Jimple.v().newLocal("l0", intentSootClass.getType()); helperBody.getLocals().add(arg); IdentityStmt para = Jimple.v().newIdentityStmt(arg, Jimple.v().newParameterRef(intentSootClass.getType(), 0)); helperBody.getUnits().add(para); //将arg赋值给字段 helperBody.getUnits().add(Jimple.v().newAssignStmt(Jimple.v().newStaticFieldRef(intent_for_ipc.makeRef()), arg)); helperBody.getUnits().add(Jimple.v().newReturnVoidStmt());
2. 非静态字段赋值
关键API为:Jimple.v().newInstanceFieldRef(Value, SootFieldRef),其中第一个参数为字段所在类的实例化对象四 在确定位置插桩
在soot实现Android Apps插桩(一)的完整代码中有一段代码:while(iter.hasNext()){ final Unit unit = (Unit)iter.next(); unit.apply(new AbstractStmtSwitch(){ public void caseAssignStmt(AssignStmt stmt){ ... } public void caseInvokeStmt(InvokeStmt stmt){ ... } } }
这是一种在确定位置插桩的方法,其中,还有另外一种方法,如下:
PatchingChain<Unit> units = body.getUnits(); for(Iterator iter = units.snapshotIterator();iter.hasNext();){ Unit u = (Unit)iter.next(); if(u instanceof InvokeStmt){ String methodName = ((InvokeStmt) u).getInvokeExpr().getMethod().getName(); System.out.println(methodName); if(methodName.equals("add")){ Local local = Jimple.v().newLocal("lizhengqiao",RefType.v("java.lang.String")); body.getLocals().add(local); ... } } //if(u instance IdentityStmt) //... }另:在Java中,可以采用另外一种插桩的方法:直接写一个需要插桩的Java代码,然后插桩调用该Java类中的方法即可。
经过我的测试:给某个确定的方法内插桩代码时,应该使用BodyTransformer,而插桩字段、方法则应该使用SceneTransformer;在向某个方法中插桩句子时,在使用SceneTransformer时,我没有成功;经过我的多次尝试,在Scene下插桩代码,很容易被soot优化掉,如:插桩一个local,但是没有对local进一步的操作,则会被soot优化掉,查看生成的代码中就没有该local,而在Body下插桩则不会出现这种情况。可能我的理解有误,有成功的希望能够分享一二。
相关文章推荐
- Redis + Django Session Cookie
- 重新学习《C++Primer5》第11章-关联容器
- 关于子函数中用new的问题
- C++的iostream标准库介绍+使用详解(转)
- 浏览器兼容处理(HTML条件注释、CSSHack和JS识别)
- 敏捷软件开发(1)--- STATE 模式
- SQL中分页与distinct冲突解决方案
- ruby关于flip-flop理解上一个注意点
- iPhone 应用开发的5个贴士
- BackTracking
- 解决java.lang.IllegalArgumentException: pointerIndex out of range 或者 arrayindexoutofboundsexception的错误
- 消息模型
- perl 使用SUPER类来访问覆盖的方法
- Android Gradle配置Debug和release参数的方法
- 计算机网络常识(摘抄)
- oracle显示中文乱码
- 平安好医生技术栈的分析【转】
- 完整简单的红黑树算法
- Soft-Margin SVM
- 光纤收发器TR-962D/932D的面板指示灯及开关代表的含义?