Search code examples
soot

Run functions using Soot


I am trying to use soot to measure execution time for every function in a particular class. I have tried to read all tutorials of Soot Framework by Eric Bodden.

What I have come up till now is this,

package test;

import java.util.Map;

import soot.Body;
import soot.BodyTransformer;
import soot.PackManager;
import soot.Scene;
import soot.SootClass;
import soot.SootMethod;
import soot.Transform;

public class MyMain {
    public static void main(String[] args) {

        PackManager
                .v()
                .getPack("jtp")
                .add(new Transform("jtp.GotoInstrumenter", GotoInstrumenter.v()));

        System.out.println(Scene.v().defaultClassPath());
        SootClass sootClass = Scene.v().loadClassAndSupport("test.TestClass");


        if (sootClass == null || !(sootClass instanceof SootClass)) {
            System.out.println("sootClass not initialized");
            System.exit(0);
        } else {
            System.out.println(sootClass.getMethodCount());
        }
        sootClass.setApplicationClass();
        for (SootMethod m : sootClass.getMethods()) {

            try {
                new Transform("jtp.GotoInstrumenter", GotoInstrumenter.v())
                        .apply(m.retrieveActiveBody());
            } catch (Exception e) {
                System.out.println("Exeception in for loop : " + e);
            }
        }

    }

}

@SuppressWarnings("all")
class GotoInstrumenter extends BodyTransformer {
    private static GotoInstrumenter instance = new GotoInstrumenter();

    private GotoInstrumenter() {
    }

    public static GotoInstrumenter v() {
        return instance;
    }

    protected void internalTransform(Body body, String phaseName, Map options) {

        System.out.println("Processing method : "
                + body.getMethod().getSignature());
    }
}

and here is my TestClass

package test;

public class TestClass {
    public static void main(String[] args) {
        System.out.println("I am in test class");
    }
    public void f1(){
        System.out.println(Math.pow(2, 10));
    }
}

I have added sootclasses by using add variable in eclipse and executing it like a Java Application.

This is my program output:

C:\Users\Aks\Java\soot-2.5.0.jar;C:\Users\Aks\workspace\SootAnalysis\bin;D:\Installs\eclipse\plugins\ca.mcgill.sable.soot.lib_2.5.2\lib\sootclasses.jar;;C:\Program Files\Java\jre7\lib\rt.jar
3
Processing method : <test.TestClass: void <init>()>
Processing method : <test.TestClass: void main(java.lang.String[])>
Processing method : <test.TestClass: void f1()>

Now I understand that Soot has read the bytecode and is stepping through all the methods. What i want to do is, run each of them. Is this possible using the Soot Framework??


Solution

  • Probably this is not why people want to use soot. I don't know if there is any elegant way to do that using soot. But, definitely, you can utilize the power of reflection here. Adding the following line at the end of internalTransform() method should work:

    TestClass.class.getMethod(body.getMethod().getName()).invoke(new TestClass());

    Of course, there is nothing like init() method within the class TestClass. So, you don't want to invoke that method. Also, for main() method, you need to specify the correct parameter as per the syntax of reflection. Otherwise, there will be exceptions.

    Hope it will help. Thanks.