英文:
How to analyze .class files using soot?
问题
我正在尝试使用Soot构建spotbugs-4.0.2的调用图(CG)。代码如下所示。
public static void main(String[] args) {
String analyzed_classes_dir = "C:\\Users\\lyu\\lll\\src\\test\\java\\com\\demo\\dir3\\spotbugs"; //包含所有结构化的类文件
String mainclass = "edu.umd.cs.findbugs.LaunchAppropriateUI";
//设置类路径
String javapath = System.getProperty("java.class.path");
String jredir = System.getProperty("java.home") + "\\lib\\rt.jar";
String libs = "C:\\Users\\liuyu\\lll\\src\\test\\java\\com\\demo\\libs\\spotbugs-4.0.2\\";
String path = javapath + File.pathSeparator + jredir + File.pathSeparator + libs;
Scene.v().setSootClassPath(path);
//向Soot添加一个内部过程分析阶段
TestCallGraphSootJar_3 analysis = new TestCallGraphSootJar_3();
PackManager.v().getPack("wjtp").add(new Transform("wjtp.TestSootCallGraph", analysis));
excludeJDKLibrary();
Options.v().set_process_dir(Arrays.asList(analyzed_classes_dir));
Options.v().set_whole_program(true);
Options.v().set_no_bodies_for_excluded(true);
Options.v().set_allow_phantom_refs(true);
Scene.v().loadNecessaryClasses();
SootClass appclass = Scene.v().getSootClass(mainclass);
Scene.v().setMainClass(appclass); // 这里发生异常。
enableSparkCallGraph();
PackManager.v().runPacks();
}
然后出现以下异常:
Exception in thread "main" java.lang.RuntimeException: Main-class has no main method!
at soot.Scene.setMainClass(Scene.java:187)
at com.ouc.TestCallGraphSootJar_3.main(TestCallGraphSootJar_3.java:65)
语句Scene.v().setMainClass(appclass);
抛出了上述异常。我进行了调试,发现appclass
中的methodlst
为null,而且appclass
是幻影类(phantom)。
如图所示。
图:appclass的调试信息
mainclass
确实存在于指定路径中,并且确实包含主方法。
我在GitHub上提交了一个问题(https://github.com/Sable/soot/issues/1346#issuecomment-627551137),但没有解决。选项手册对此问题也没有帮助。
顺便问一下,我能否仅分析给定类中的调用关系?例如,我只想获取类C1内部的调用信息。
Class C1{
main(){
m1(parm);
}
m1(args){
m2(xxx);
}
m2(args){
m3(xxx);
}
m3(args){
...
}
}
然后,我只想获取如下的调用关系:
main -> m1() -> m2() -> m3()
如果main或m1或m2或m3调用另一个类C2中的方法,我将忽略它,只关注C1中的方法。
英文:
I'm trying to build a call-graph(CG) for spotbugs-4.0.2 with soot. The code is shown as follows.
public static void main(String[] args) {
String analyzed_classes_dir = "C:\\Users\\lyu\\lll\\src\\test\\java\\com\\demo\\dir3\\spotbugs"; //contains all structured class files
String mainclass = "edu.umd.cs.findbugs.LaunchAppropriateUI";
//set classpath
String javapath = System.getProperty("java.class.path");
String jredir = System.getProperty("java.home") + "\\lib\\rt.jar";
String libs = "C:\\Users\\liuyu\\lll\\src\\test\\java\\com\\demo\\libs\\spotbugs-4.0.2\\";
String path = javapath + File.pathSeparator + jredir + File.pathSeparator + libs;
Scene.v().setSootClassPath(path);
//add an intra-procedural analysis phase to Soot
TestCallGraphSootJar_3 analysis = new TestCallGraphSootJar_3();
PackManager.v().getPack("wjtp").add(new Transform("wjtp.TestSootCallGraph", analysis));
excludeJDKLibrary();
Options.v().set_process_dir(Arrays.asList(analyzed_classes_dir));
Options.v().set_whole_program(true);
Options.v().set_no_bodies_for_excluded(true);
Options.v().set_allow_phantom_refs(true);
Scene.v().loadNecessaryClasses();
SootClass appclass = Scene.v().getSootClass(mainclass);
Scene.v().setMainClass(appclass); // exception here.
enableSparkCallGraph();
PackManager.v().runPacks();
}
Then the exception:
Exception in thread "main" java.lang.RuntimeException: Main-class has no main method!
at soot.Scene.setMainClass(Scene.java:187)
at com.ouc.TestCallGraphSootJar_3.main(TestCallGraphSootJar_3.java:65)
The statement "Scene.v().setMainClass(appclass);" throws the above exception.
I debugged it and found that the methodlst
in the appclass
is null. And appclass
is phantom.
As shown in the picture.
fig. the debug information of appclass
The mainclass
does exist in the specified path, and it does contain the main method.
I've submitted an issue in GitHub (https://github.com/Sable/soot/issues/1346#issuecomment-627551137) but didn't solve it. And the options manual also didn't help with this problem.
Btw, could I only analyze the call relationships in a given class? For example, I only want to get the call information inside the class C1.
Class C1{
main(){
m1(parm);
}
m1(args){
m2(xxx);
}
m2(args){
m3(xxx);
}
m3(args){
...
}
}
Then I only want to get the follow call relationship:
main——>m1()——>m2()——m3()
If main or m1 or m2 or m3 calls a method in another class C2, I will ignore it, only focus on the methods in C1.
答案1
得分: 0
我是提问者,我已经解决了这个问题。如果你对这个问题感兴趣,你可以在这个帖子中阅读它:链接。
英文:
I'm the asker, and I've solved it. If you are interested in this question, you can read it in this issue post.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论