好久没写技术博客了,之前写的都是关于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();
}
}
}
}
目前还遇到一个问题,等找到解决方案后再写出来。
本文介绍了在使用JAVA代码分析工具Soot过程中遇到的两个问题及其解决方案。第一个问题是关于-soot-classpath和-process-path参数设置导致的类找不到错误,解决方法是调整路径,去掉子目录名作为包名。第二个问题是在执行控制流例子时遇到的问题,内容未详述。

3441

被折叠的 条评论
为什么被折叠?



