rohanpadhye / vasco

An inter-procedural data-flow analysis framework using value-based context sensitivity
GNU Lesser General Public License v2.1
87 stars 35 forks source link

How to 'not' include java libraries methods #14

Open DhritiKhanna opened 4 years ago

DhritiKhanna commented 4 years ago

Hello, I am setting the below options in my analysis to exclude analyzing java libraries from my analysis: _Options.v().set_app(true); Options.v().set_allow_phantom_refs(true); List l = new LinkedList(); l.add("java.*"); Options.v().set_exclude(l); Options.v().set_no_bodies_forexcluded(true);

But, the following exception is coming: specialinvoke $r0.<java.util.LinkedList: void ()>()

Exception in thread "main" java.lang.RuntimeException: cannot get active body for phantom class: <java.util.LinkedList: void <init>()>
    at soot.SootMethod.getActiveBody(SootMethod.java:292)
    at vasco.soot.DefaultJimpleRepresentation.getControlFlowGraph(DefaultJimpleRepresentation.java:73)
    at vasco.soot.DefaultJimpleRepresentation.getControlFlowGraph(DefaultJimpleRepresentation.java:47)
    at vasco.ForwardInterProceduralAnalysis.initContext(ForwardInterProceduralAnalysis.java:289)
    at vasco.ForwardInterProceduralAnalysis.doAnalysis(ForwardInterProceduralAnalysis.java:125)
    at MyAnalysis.<init>(MyAnalysis.java:82)
    at Analyzer.internalTransform(Analyzer.java:43)
    at soot.SceneTransformer.transform(SceneTransformer.java:39)
    at soot.Transform.apply(Transform.java:89)
    at soot.ScenePack.internalApply(ScenePack.java:43)
    at soot.Pack.apply(Pack.java:114)
    at soot.PackManager.runWholeProgramPacks(PackManager.java:418)
    at soot.PackManager.runPacks(PackManager.java:336)
    at soot.Main.run(Main.java:198)
    at soot.Main.main(Main.java:141)
    at Driver.main(Driver.java:88) 
rohanpadhye commented 4 years ago

Hello. It looks like you have set the option set_no_bodies_for_excluded, which means that these methods will not have a CFG associated with them.

If you want to ignore method bodies, you need to provide some sort of dummy methods in the ProgramRepresentation. For example, you might want to replace all methods without a body to having a stub CFG that is equivalent to "return null" or something like that. Otherwise, the data-flow analysis does not know what to do when analyzing calls to phantom methods. The ideal way to do this is to subclass the DefaultJimpleRepresentation with your own handling of skipped methods.

There is an implementation of initContextForPhantomMethod which simply copies the IN to the OUT for a phantom method. I don't think this method is ever called, but you can possibly use it instead of the default intiContext whenever programRepresentation.isPhantomMethod() returns true -- you will have to override this as well to return true for the methods that you want to skip.

rohanpadhye commented 4 years ago

I just pushed a commit that does the above. If a soot method does not have a body, then when it is called the context is initialized such that the OUT of the method is equal to its IN. Phantom methods are essentially "jumped over" as if they never existed. Note that this is not sound in general.

FALTUCKY commented 4 years ago

hello, I made a little change to the vasco.tests.CopyContantTestCase as follow:

...
public int foo(int a, int b) {
    int x = a;
    int y = b;
    int z;
    if (a < 5) {
        z = x;
    } else {
        z = y;
    }
    ArrayList<Integer> list = new ArrayList<>();
    list.add(a);
    return z + list.get(0);
}

then I set the optionOptions.v().set_no_bodies_for_excluded(true), run the vasco.soot.examples.CopyConstantTest ,I got this Exception:

java.lang.RuntimeException: This operation requires resolving level BODIES but java.util.ArrayList is at resolving level SIGNATURES
If you are extending Soot, try to add the following call before calling soot.Main.main(..):
Scene.v().addBasicClass(java.util.ArrayList,BODIES);
Otherwise, try whole-program mode (-w).
    at soot.SootClass.checkLevelIgnoreResolving(SootClass.java:183)
    at soot.SootClass.checkLevel(SootClass.java:165)
    at soot.SootMethod.getActiveBody(SootMethod.java:329)
    at vasco.soot.examples.CopyConstantAnalysis.callEntryFlowFunction(CopyConstantAnalysis.java:121)
    at vasco.soot.examples.CopyConstantAnalysis.callEntryFlowFunction(CopyConstantAnalysis.java:53)
    at vasco.ForwardInterProceduralAnalysis.doAnalysis(ForwardInterProceduralAnalysis.java:121)
    at vasco.soot.examples.CopyConstantTest.internalTransform(CopyConstantTest.java:59)
    at soot.SceneTransformer.transform(SceneTransformer.java:36)
    at soot.Transform.apply(Transform.java:102)
    at soot.ScenePack.internalApply(ScenePack.java:35)
    at soot.Pack.apply(Pack.java:117)
    at soot.PackManager.runWholeProgramPacks(PackManager.java:612)
    at soot.PackManager.runPacksNormally(PackManager.java:495)
    at soot.PackManager.runPacks(PackManager.java:419)
    at soot.Main.run(Main.java:269)
    at soot.Main.main(Main.java:141)
    at vasco.soot.examples.CopyConstantTest.main(CopyConstantTest.java:137)
    at vasco.soot.examples.CopyConstantTest.testCopyConstantAnalysis(CopyConstantTest.java:143)

but ,if i remove the option Options.v().set_no_bodies_for_excluded(true), I got another exception:

java.lang.RuntimeException: no active body present for method <java.lang.Throwable: java.lang.Throwable fillInStackTrace(int)>
    at soot.SootMethod.getActiveBody(SootMethod.java:337)
    at vasco.soot.examples.CopyConstantAnalysis.callEntryFlowFunction(CopyConstantAnalysis.java:115)
    at vasco.soot.examples.CopyConstantAnalysis.callEntryFlowFunction(CopyConstantAnalysis.java:53)
    at vasco.ForwardInterProceduralAnalysis.doAnalysis(ForwardInterProceduralAnalysis.java:121)
    at vasco.soot.examples.CopyConstantTest.internalTransform(CopyConstantTest.java:59)
    at soot.SceneTransformer.transform(SceneTransformer.java:36)
......
rohanpadhye commented 4 years ago

Right. I guess CopyConstantAnalysis#callEntryFlowFunction will have to handle the case where calledMethod.hasActiveBody() is false, and just return copy(inValue) in that case.

https://github.com/rohanpadhye/vasco/blob/5598bcf6dc47bd7f0e905cefb5eb0b2e70599586/src/main/java/vasco/soot/examples/CopyConstantAnalysis.java#L108-L126

Feel free to send a PR if you get around to fixing this.