secure-software-engineering / FlowDroid

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

Exception in Call Graph Construction #549

Closed gnipping closed 1 year ago

gnipping commented 1 year ago

I want to use FlowDroid to get the call graph of an android apk. I use maven project with soot 4.1.0 and flowdroid 2.10.0.

My code is below: `package com.gnip.mama;

import soot.PackManager; import soot.Scene; import soot.jimple.infoflow.android.SetupApplication; import soot.jimple.toolkits.callgraph.CallGraph; import soot.options.Options;

import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList;

import java.util.List;

import static java.lang.System.exit;

public class AppCallGraph {

public static String appToRun = "";

public static String androidPlatform = "";

public static String result_fn = "";

public static void main(String[] args) {
    if (args.length == 2) {
        appToRun = args[0];
        androidPlatform = args[1];
    } else {
        System.out.println("Wrong arguments, invocation should be like:\\njava -jar mamadroid.jar <path_to_apk> <path_to_android_platform>\\n");
        exit(0);
    }
    result_fn = appToRun + ".txt";
    initSoot();
    SetupApplication app = new SetupApplication(androidPlatform, appToRun);

    app.constructCallgraph();
    CallGraph cg = Scene.v().getCallGraph();

    try{
        FileWriter writer = new FileWriter(result_fn);
        writer.write(cg.toString());
        writer.close();
    }
    catch (IOException e) {
        e.printStackTrace();
    }
}

 static void initSoot(){
     Options.v().set_src_prec(Options.src_prec_apk);
     Options.v().set_output_format(Options.output_format_none);

     List<String> pathList = new ArrayList<String>();
     pathList.add(appToRun);
     String androidJarPath = Scene.v().getAndroidJarPath(androidPlatform, appToRun);
     pathList.add(androidJarPath);
     Options.v().set_process_dir(pathList);

     Options.v().set_force_android_jar(appToRun);
     Options.v().set_whole_program(true);

     List<String> includePackagesList = new ArrayList<String>();
     List<String> excludePackagesList = new ArrayList<String>();
     includePackagesList.add("java.");
     includePackagesList.add("android.");
     includePackagesList.add("org.");
     includePackagesList.add("com.");
     includePackagesList.add("javax.");
     Options.v().set_include(includePackagesList);
     excludePackagesList.add("soot.");
     Options.v().set_exclude(excludePackagesList);

     Scene.v().loadNecessaryClasses();
     PackManager.v().runPacks();
}

} `

When I run the following command: java -jar CallGrpah-1.0-SNAPSHOT-jar-with-dependencies.jar C:\Users\17323\Desktop\mama\app-release.apk D:\android_sdk\platforms

I get the following exception: [main] INFO soot.jimple.infoflow.android.SetupApplication - Initializing Soot... [main] INFO soot.jimple.infoflow.android.SetupApplication - Loading dex files... Exception in thread "main" java.lang.NoSuchMethodError: soot.Scene.createLocalGenerator(Lsoot/Body;)Lsoot/LocalGenerator; at soot.jimple.infoflow.cfg.LibraryClassPatcher.generateMessageObtainMethod(LibraryClassPatcher.java:231) at soot.jimple.infoflow.cfg.LibraryClassPatcher.patchMessageObtainImplementation(LibraryClassPatcher.java:123) at soot.jimple.infoflow.cfg.LibraryClassPatcher.patchLibraries(LibraryClassPatcher.java:71) at soot.jimple.infoflow.android.SetupApplication.initializeSoot(SetupApplication.java:1194) at soot.jimple.infoflow.android.SetupApplication.runInfoflow(SetupApplication.java:1439) at soot.jimple.infoflow.android.SetupApplication.constructCallgraph(SetupApplication.java:1311) at com.gnip.mama.AppCallGraph.main(AppCallGraph.java:40)

It seems like the soot does not have the method soot.Scene.createLocalGenerator(Lsoot/Body;)Lsoot/LocalGenerator; ? What is right version of flowdroid and soot? Could you help me? Thank you!

StevenArzt commented 1 year ago

I'm not sure why you picked a Soot version. FlowDroid should reference the correct Soot version via Maven. If you compile your own code using Maven and declare FlowDroid as a dependency, Soot should automatically be added and Maven should take care to load the correct version. Since FlowDroid is on Maven central by now, that should also be the easiest solution.

gnipping commented 1 year ago

I'm not sure why you picked a Soot version. FlowDroid should reference the correct Soot version via Maven. If you compile your own code using Maven and declare FlowDroid as a dependency, Soot should automatically be added and Maven should take care to load the correct version. Since FlowDroid is on Maven central by now, that should also be the easiest solution.

Thank you very much! After I remove the soot dependency in pom.xml, it works! The old dependencies: `

org.soot-oss soot 4.1.0
    <dependency>
        <groupId>de.fraunhofer.sit.sse.flowdroid</groupId>
        <artifactId>soot-infoflow</artifactId>
        <version>2.10.0</version>
    </dependency>
    <dependency>
        <groupId>de.fraunhofer.sit.sse.flowdroid</groupId>
        <artifactId>soot-infoflow-summaries</artifactId>
        <version>2.10.0</version>
    </dependency>
    <dependency>
        <groupId>de.fraunhofer.sit.sse.flowdroid</groupId>
        <artifactId>soot-infoflow-android</artifactId>
        <version>2.10.0</version>
    </dependency>
</dependencies>`

The new dependencies: `

de.fraunhofer.sit.sse.flowdroid soot-infoflow 2.10.0
    <dependency>
        <groupId>de.fraunhofer.sit.sse.flowdroid</groupId>
        <artifactId>soot-infoflow-summaries</artifactId>
        <version>2.10.0</version>
    </dependency>
    <dependency>
        <groupId>de.fraunhofer.sit.sse.flowdroid</groupId>
        <artifactId>soot-infoflow-android</artifactId>
        <version>2.10.0</version>
    </dependency>
</dependencies>`