Search code examples
javasoot

How can I set up Soot when using it as a library?


I want to use Soot library to build an SSA from *.java file. But all the examples I found use Soot as standalone tool, not library. Can anyone give me example hot to do it in program?

For a start I am just trying to load my class from the source file and print it (TestClass.class is in the directory A/home/abdullin/workspace/test):

import soot.G
import soot.Scene
import soot.options.Options

fun main(args: Array<String>) {
    G.reset();
    Options.v().set_whole_program(true)
    Scene.v().loadBasicClasses()

    Scene.v().sootClassPath = "${Scene.v().defaultClassPath()}:/home/abdullin/workspace/test"

    val sc = Scene.v().getSootClass("TestClass")
    Scene.v().loadNecessaryClasses()
    sc.setApplicationClass()

    println(sc.name)
    sc.methods.forEach {
        println(it)
    }
}

But when I run this, I get runtime exception Aborting: can't find classfile TestClass. If I change Scene.v().getSootClass("TestClass") to Scene.v().loadClassAndSupport("TestClass") as they do in some of their tutorials, soot finds my class, but it is not complete. It prints me signatures of class methods, but can't find their bodies, activeBody field is null.

TestClass
<TestClass: void <init>()>
<TestClass: void main(java.lang.String[])>
<TestClass: void f1()>

Solution

  • You can read this post (https://o2lab.github.io/710/p/a1.html). But if you try to analyze a jar file, you should unzip it and get a set of class files. Then you should add your classes directory into the soot_class_path.

    Demo:

    public static void main(String[] args) {
        //spotbugs -- testing
        String classesDir = "D:\\wkspace\\seed8\\dir\\spotbugs";
        String mainClass = "edu.umd.cs.findbugs.LaunchAppropriateUI";
    
        //set classpath
        String jreDir = System.getProperty("java.home") + "\\lib\\jce.jar";
        String jceDir = System.getProperty("java.home") + "\\lib\\rt.jar";
        String path = jreDir + File.pathSeparator + jceDir + File.pathSeparator + classesDir;
        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(classesDir));
        Options.v().set_whole_program(true);
        //Options.v().set_app(true);
    
        SootClass appClass = Scene.v().loadClassAndSupport(mainClass);
        Scene.v().setMainClass(appClass);
        Scene.v().loadNecessaryClasses();
    
        //enableCHACallGraph();
        enableSparkCallGraph();
    
        PackManager.v().runPacks();
    }
    

    If you replace

    SootClass appclass = Scene.v().loadClassAndSupport(mainclass);
    Scene.v().setMainClass(appclass);
    Scene.v().loadNecessaryClasses();
    

    by

    Scene.v().loadNecessaryClasses();
    SootClass appclass = Scene.v().getSootClass(mainclass);
    Scene.v().setMainClass(appclass);
    

    , the program also works.