kivi
kivi

Reputation: 399

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()>

Upvotes: 0

Views: 1898

Answers (2)

Liu Yuan
Liu Yuan

Reputation: 16

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.

Upvotes: 0

Cephalopod
Cephalopod

Reputation: 15145

First, make sure that the Soot jar is in the classpath.

Then, set up Soot using the classes soot.G and soot.options.Options (G.reset() and Options.v().parse() are methods of interest, also see command line options).

Using soot.Scene.v().setSootClassPath() and similar you can tell Soot where to find the class files of the code you want to analyze.

You can then use Scene.v().getSootClass() to obtain SootClass objects. Make sure that Soot loads all classes after setting the class you want to analyze as main class:

mySootClass.setApplicationClass();
Scene.v().loadNecessaryClasses();

After this, you can use Soot to obtain various types of graphs and run you analyses, as described in the Survivor's guide

Upvotes: 3

Related Questions