如何使用soot分析 .class 文件?

huangapple go评论81阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2020年5月30日 05:26:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/62094822.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定