secure-software-engineering / FlowDroid

FlowDroid Static Data Flow Tracker
GNU Lesser General Public License v2.1
1.02k stars 293 forks source link

Missing Call graph edges using FlowDroid #551

Open limerick1718 opened 1 year ago

limerick1718 commented 1 year ago

Hi @StevenArzt! Sorry to bother you again but I find there could be missing call graph edges. Below are the code to generate call graph using FlowDroid:

G.reset();
InfoflowAndroidConfiguration config = new InfoflowAndroidConfiguration();
config.getAnalysisFileConfig().setTargetAPKFile(apkPath);
config.getAnalysisFileConfig().setAndroidPlatformDir(Config.androidDirectory);
config.setCodeEliminationMode(InfoflowConfiguration.CodeEliminationMode.NoCodeElimination);
config.setCallgraphAlgorithm(InfoflowConfiguration.CallgraphAlgorithm.CHA); 
SetupApplication setupApplication = new SetupApplication(config);
setupApplication.getConfig().setEnableReflection(true);
setupApplication.getConfig().setMergeDexFiles(true);

setupApplication.constructCallgraph();
Scene.v().loadNecessaryClasses();
CallGraph callGraph = Scene.v().getCallGraph();
return callGraph;

The example APK is org.wikipedia.apk.zip

I observe that there would be one missing CG edge: [srcMethod=<org.wikipedia.page.PageTitle: boolean isTalkPage()>, callSite=$z0 = virtualinvoke $r1.<org.wikipedia.page.Namespace: boolean talk()>(), tgtMethod=<org.wikipedia.page.Namespace$1: boolean talk()>]

After observing this, I compare the result of FlowDroid with using Soot solely. In theory, FlowDroid should find more edges compared with Soot only. Below is the code that only uses Soot:

G.reset();
Options.v().set_allow_phantom_refs(true);
Options.v().set_whole_program(true);
Options.v().set_prepend_classpath(true);
Options.v().set_android_jars(Config.androidDirectory);
Options.v().set_src_prec(Options.src_prec_apk);
Options.v().set_process_dir(Collections.singletonList(apkPath)); 
Options.v().set_process_multiple_dex(true);
Options.v().set_include_all(true);
Options.v().setPhaseOption("cg.cha","enabled:true");
Options.v().set_validate(true);
Scene.v().loadNecessaryClasses();
CallGraphBuilder callGraphBuilder = new CallGraphBuilder();
callGraphBuilder.build();
CallGraph callGraph = Scene.v().getCallGraph();
return callGraph;

To make a fair comparison, the algorithm to build CG is "CHA" for both the soot-only approach and the FlowDroid approach.

As a result, I find that there are 27,659 edges only presented in the soot-only approach. This is the file of the edges that are only presented in the soot-only approach: wikipedia_diff.txt I filter out the edges that are not related to the application.

I decompile the APK using apktool and find that the "Soot only edges" should be true-positive: there should be such edges (by the static analysis performed in my brain), but FlowDroid reports that there are no such edges.

I believe there should be something wrong with my code. Would you please kindly help me?

Thank you very much and have a great day!

StevenArzt commented 1 year ago

Firstly, you don't need to call loadNecessaryClasses when running FlowDroid. I'm not sure whether this leads to any issues, but it's definitely unnecessary, so better remove it.

FlowDroid generates a dummy main method and generates the callgraph based on this entry point. If you just run Soot on the APK without an entry point, it might also take unreachable code into account. I would need to look into the details of how Soot works without an entry point, but I guess that's the main reason.

limerick1718 commented 1 year ago

Thank you very much for your help!

I (1) delete that statement in my code and (2) test the code again. The code fails again (Cannot identify more edges). We may need a step further investigation.

Thanks again and have a great day!

limerick1718 commented 1 year ago

Hello Steven, I do not mean to push you, but I wonder if anything is wrong with my code/my understanding. If not, is there any update (e.g., fixed in recent commits)? Thank you very much!