Problems in runInfoflow( ) when Re-implement MaMaDroid
I was trying to re-implement Appgraph.java in MaMaDroid source code which transform apks to call graph. I use FlowDroid with IntelliJ to do that, but some problems happened. A few apks failed and errors happened in runInfoflow("sourceAndSink.txt"). The overall code workflows are below:
G.reset() --> soot configurations like PackManager.v() / Options.v() --> loadNecessaryClasses() --> configrations like setSootIntegrationMode() / setAndroidPlatformDir() --> SetupApplication(config) --> app.setCallbackFile(androidCallbackPath) --> runInfoflow("sourceAndSink.txt") --> constructCallgraph();
The source code in mamadroid also use getEntryPointCreator().createDummyMain() to set an entryPoint, errors also happened when I tried to do that in my own code.
Some apks whose size are only 2~3 MB, but their txt files used to save call graph can reach 10 MB. Is it a normal situation?
Additionally, if I Want to use FlowDroid transforming a large number of apks to call graph, are there any possible solutions that my program can go on with the next apk and log down the situations when the current apk failed or throw out exceptions.
Thank You!
this is the code I use:
G.reset();
PackManager.v().getPack("cg"); PackManager.v().getPack("jb"); PackManager.v().getPack("wjap.cgg"); Options.v().set_src_prec(Options.src_prec_apk); Options.v().set_process_dir(Collections.singletonList(appToRun)); Options.v().set_android_jars(androidPlatform); Options.v().set_whole_program(true); Options.v().set_allow_phantom_refs(true); Options.v().set_prepend_classpath(true); Options.v().set_app(true); Options.v().set_include(toInclude); Options.v().set_exclude(toExclude); Options.v().set_output_format(Options.output_format_xml); Options.v().setPhaseOption("cg", "safe-newinstance:true"); Options.v().setPhaseOption("cg.spark", "on"); Options.v().setPhaseOption("wjap.cgg", "show-lib-meths:true"); Options.v().setPhaseOption("jb", "use-original-names:true");
Scene.v().loadNecessaryClasses();
InfoflowAndroidConfiguration config = new InfoflowAndroidConfiguration(); config.getAnalysisFileConfig().setTargetAPKFile(appToRun); config.getAnalysisFileConfig().setAndroidPlatformDir(androidPlatform); config.setSootIntegrationMode(InfoflowConfiguration.SootIntegrationMode.UseExistingInstance); config.setCodeEliminationMode(InfoflowConfiguration.CodeEliminationMode.NoCodeElimination); config.setCallgraphAlgorithm(InfoflowConfiguration.CallgraphAlgorithm.SPARK); // CHA or SPARK config.setStaticFieldTrackingMode(InfoflowConfiguration.StaticFieldTrackingMode.None); config.getAccessPathConfiguration().setAccessPathLength(1); config.setFlowSensitiveAliasing(false); config.setExcludeSootLibraryClasses(true);
SetupApplication app = new SetupApplication(config); app.setCallbackFile(androidCallbackPath);
// problems happened SootMethod entryPoint = app.getDummyMainMethod(); Options.v().set_main_class(entryPoint.getSignature()); Scene.v().setEntryPoints(Collections.singletonList(entryPoint)); app.runInfoflow(sourceAndSinkPath);
app.constructCallgraph();
The errors is below:
[main] ERROR soot.jimple.infoflow.android.SetupApplication - Could not calculate callback methods java.lang.IllegalStateException: UnitThrowAnalysis StmtSwitch: type of throw argument is not a RefType!
Exception in thread "main" java.lang.IllegalStateException: UnitThrowAnalysis StmtSwitch: type of throw argument is not a RefType!
Your setup looks overly complex. I'd suggest to have FlowDroid initialize Soot:
SetupApplication app = new SetupApplication("myApp.apk", "PLATFORMDIR");
app. constructCallgraph();
CallGraph cg = Scene.v().getCallgraph();
No need to do anything with Soot options, packs, resetting, etc. FlowDroid will do all of that. It's just three lines from your side as shown above.
Your code looks like a mixture between old-style (FlowDroid v1.x) approach and unnecessary manual handling of options and workflow.
Thank You Arzt. I also feel that the simple FlowDroid settings have the best outcomes.