Skip to content

Example: Using Heros with Soot

cshiflet edited this page Sep 20, 2018 · 6 revisions

This page is an example of using the Heros' IFDS solver with Soot. It was written using Soot v. 3.1.0 and Heros v. 1.0.1.

Overview

Soot performed Java analysis and optimization by running packs. Heros operates is a whole-program analysis and needs to run in a whole-program pack. In this example, Heros is run in the Whole-Jimple Transformation Pack (wjtp).

Heros SceneTransformer class to load into Soot wjtp

In order to add an analysis, like Heros, to a whole-program pack in Soot, it must be implemented a class that extends SceneTransformer. The following is a simple example using example IFDSReachingDefinitions found in Soot. IFDSReachingDefinitions was a quickly written example that is not necessarily kept up to date in Soot, and it may require corrections to properly handle special edges (usually related to Thread.run) added to the call graph by newer versions of Soot.

// Subclass of SceneTransformer to run Heros IFDS solver in Soot's "wjtp" pack
public class IFDSDataFlowTransformer extends SceneTransformer {
    @Override
    protected void internalTransform(String phaseName, Map<String, String> options) {
        JimpleBasedInterproceduralCFG icfg= new JimpleBasedInterproceduralCFG();
        IFDSTabulationProblem<Unit, Pair<Value, 
                Set<DefinitionStmt>>, SootMethod, 
                InterproceduralCFG<Unit, SootMethod>> problem = new IFDSReachingDefinitions(icfg);

        IFDSSolver<Unit, Pair<Value, Set<DefinitionStmt>>, 
                SootMethod, InterproceduralCFG<Unit, SootMethod>> solver = 
                    new IFDSSolver<Unit, Pair<Value, Set<DefinitionStmt>>, SootMethod, 
                                   InterproceduralCFG<Unit, SootMethod>>(problem);

        System.out.println("Starting solver");
        solver.solve();
        System.out.println("Done");
    }
}

Setup and Run Heros in Soot

Soot must be run with the whole-program option enabled with using Heros. Here, Soot is configured to run in whole-program mode and construct a call-graph using SPARK.

        // Set Soot's internal classpath
        Options.v().set_soot_classpath(classpath);

        // Enable whole-program mode
        Options.v().set_whole_program(true);
        Options.v().set_app(true);

        // Call-graph options
        Options.v().setPhaseOption("cg", "safe-newinstance:true");
        Options.v().setPhaseOption("cg.cha","enabled:false");

        // Enable SPARK call-graph construction
        Options.v().setPhaseOption("cg.spark","enabled:true");
        Options.v().setPhaseOption("cg.spark","verbose:true");
        Options.v().setPhaseOption("cg.spark","on-fly-cg:true");

        Options.v().set_allow_phantom_refs(true);

        // Set the main class of the application to be analysed
        Options.v().set_main_class(mainClass);

        // Load the main class
        SootClass c = Scene.v().loadClass(mainClass, SootClass.BODIES);
        c.setApplicationClass();

        // Load the "main" method of the main class and set it as a Soot entry point
        SootMethod entryPoint = c.getMethodByName("main");
        List<SootMethod> entryPoints = new ArrayList<SootMethod>();
        entryPoints.add(entryPoint);
        Scene.v().setEntryPoints(entryPoints);

Next, an instance of the Heros analysis class above is added to the Soot Whole-Jimple Transform Pack (wjtp). Note that the name I used here, "wjtp.herosifds", must begin with "wjtp.", but the rest is arbitrarily chosen; You can use whatever name you want after "wjtp.".

        PackManager.v().getPack("wjtp").add(new Transform("wjtp.herosifds", new IFDSDataFlowTransformer()));

Finally, execute Soot

        soot.Main.main();

This example does not include any code to work with the IFDS solution provided by Heros, and such code can be added in several places, including at the end of the "IFDSDataFlowTransformer" class above.

Clone this wiki locally