Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to 'not' include java libraries methods #14

Open
DhritiKhanna opened this issue Nov 18, 2019 · 4 comments
Open

How to 'not' include java libraries methods #14

DhritiKhanna opened this issue Nov 18, 2019 · 4 comments

Comments

@DhritiKhanna
Copy link

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_for_excluded(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
Copy link
Owner

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
Copy link
Owner

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
Copy link

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
Copy link
Owner

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

public Map<Local, Constant> callEntryFlowFunction(Context<SootMethod, Unit, Map<Local, Constant>> context, SootMethod calledMethod, Unit unit, Map<Local, Constant> inValue) {
// Initialise result to empty map
Map<Local, Constant> entryValue = topValue();
// Map arguments to parameters
InvokeExpr ie = ((Stmt) unit).getInvokeExpr();
for (int i = 0; i < ie.getArgCount(); i++) {
Value arg = ie.getArg(i);
Local param = calledMethod.getActiveBody().getParameterLocal(i);
assign(param, arg, inValue, entryValue);
}
// And instance of the this local
if (ie instanceof InstanceInvokeExpr) {
Value instance = ((InstanceInvokeExpr) ie).getBase();
Local thisLocal = calledMethod.getActiveBody().getThisLocal();
assign(thisLocal, instance, inValue, entryValue);
}
// Return the entry value at the called method
return entryValue;
}

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants