使用代码分析工具SOOT经验总结

本文介绍了在使用JAVA代码分析工具Soot过程中遇到的两个问题及其解决方案。第一个问题是关于-soot-classpath和-process-path参数设置导致的类找不到错误,解决方法是调整路径,去掉子目录名作为包名。第二个问题是在执行控制流例子时遇到的问题,内容未详述。

好久没写技术博客了,之前写的都是关于linux环境下资源监测方面的内容,比赛做完以后改做Android移动平台的研究,主要关注能耗这部分,有兴趣的童鞋可以多交流。

最近因为工作需要我需要分析JAVA程序,师兄师姐们首推SOOT,看过入门文档后也觉得SOOT功能很强大,上次去PLDI会议的workshop还看到了现在SOOT的负责人Eric Bodden,很帅的一个小伙子偷笑,言归正传~

Soot的安装和使用参考官网http://www.sable.mcgill.ca/soot/ 的supervisor guide就可以,跑通里面的例子就能对soot的功能有大体的了解。下面是我在后期使用遇到的问题及解决办法。

1. Error: class com.ByteCodeStyle read in from a classfile in which ByteCodeStyle was expected.

这个问题是在程序内部设置了 -soot-classpath, -process-path参数后出现的。

-soot-classpath:C:\*****\workspace\SeeByteCode\bin\com

-process-path:C:\*****\workspace\SeeByteCode\bin\com


从逻辑上考虑我已经将要处理的类ByteCodeStyle的路径告诉了soot,它应该可以找到类。我们再看一下错误信息soot在类文件读到的类名是com.ByteCodeStyle,但是它需要的类名却是ByteCodeStyle。这两个名称的差别就在于前者多了一个包名。下一步跟踪到最底层错误产生的代码(Util.java):


往上找调用这个方法的代码可以发现name是从类文件中读出的类名,bclass.getName()是从用户指定的路径中读出来的类名,所以我们设置的路径下的类名就是ByteCodeStyle,再看一下这个类文件的字节码


读出的com.ByteCodeStyle和路径下的ByteCodeStyle不匹配,对应的解决方法就是修改-process-path和-soot-classpath,把它们都改成C:\*****\workspace\SeeByteCode\bin,比上面的路径少了一个\com,soot默认把这个子目录名当做包名,这样路径下的类文件名就是com.ByteCodeStyle,与类文件读出来的就一致了。DONE~


2. 在执行文档中控制流例子的时候遇到的问题,代码

         SootClass c=Scene.v().loadClassAndSupport("com.ByteCodeStyle");
	 c.setApplicationClass();
	 SootMethod m=c.getMethodByName("add");
	 Body b=m.retrieveActiveBody();
	 UnitGraph g= new ExceptionalUnitGraph(b);
	 Iterator i=g.iterator();
	 while(i.hasNext())
	 {
		 Unit u=(Unit)i.next();//........

	 }
错误信息: Exception in thread "main" java.lang.NullPointerException,跟踪错误定位在Body b=m.retrieveActiveBody();m为null所以产生了空指针异常,说明之前才,c.getMethodByName("add");出现问题,也可以判定soot并没有成功加载方法,之前在网上查了一些资料都没有找到合适的解决办法,最后向soot-list里面的大牛发邮件询问,很快就收到了Phil Pratt-Szeliga的回复,他发给我一个代码文件,建议我通过Transformer去加载类和方法,一试果然有效,现附上大牛的代码文件,希望能有所帮助。

import java.util.Iterator;
import java.util.Map;
import soot.*;
import soot.toolkits.graph.BriefUnitGraph;
import soot.toolkits.graph.UnitGraph;
//wrote by Phil Pratt-Szeliga
class Example {

  public void run(String dir){
    
    Printer printer = new Printer();
    Transform t1 = new Transform("jtp.Printer", printer);
    PackManager.v().getPack("jtp").add(t1);
    
    int size = 4;
    String[] soot_args = new String[size];
    soot_args[0] = "-process-dir";
    soot_args[1] = dir;
    soot_args[2] = "-pp";
    soot_args[3] = "-allow-phantom-refs";
    soot.Main.main(soot_args);
  }

  public static void main(String[] args){
    Example example = new Example();
    example.run("build/classes/");
  }

  class Printer extends BodyTransformer {

    @Override
    protected void internalTransform(Body body, String string, Map map) {
      SootMethod method = body.getMethod();
      if(method.getName().equals("main") == false){
        return;
      }
      UnitGraph g=new BriefUnitGraph(body);
      Iterator it=g.iterator();
      while(it.hasNext()){
        Unit u=(Unit)it.next();
      }
    }
  }
}

目前还遇到一个问题,等找到解决方案后再写出来。


评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值