在使用FlowDroid对apk进行静态分析和绘制函数调用图(CallGraph)时,遇到了一个问题,如下:
SootMethod entryPoint = app.getEntryPointCreator().createDummyMain();
执行该行代码时,抛出空指针异常,打断点发现这个getEntryPointCreator()返回了null,这是什么问题?
有的apk是正常的,能正确的绘制CG,其他的都在这里出错,问题出在哪了啊
SootMethod entryPoint = app.getEntryPointCreator().createDummyMain();
执行该行代码时,抛出空指针异常,打断点发现这个getEntryPointCreator()返回了null,这是什么问题?
有的apk是正常的,能正确的绘制CG,其他的都在这里出错,问题出在哪了啊
package CGPackage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;import soot.MethodOrMethodContext;
import soot.PackManager;
import soot.Scene;
import soot.SootMethod;
import soot.jimple.infoflow.android.SetupApplication;
import soot.jimple.infoflow.entryPointCreators.AndroidEntryPointCreator;
import soot.jimple.toolkits.callgraph.CallGraph;
import soot.jimple.toolkits.callgraph.Targets;
import soot.options.Options;
import soot.util.dot.DotGraph;
import soot.util.dot.DotGraphEdge;public class CGGenerator {
// 设置android的jar包目录
public final static String androidPath = "C:\\AndroidSDK\\sdk\\platforms\\android-27\\android.jar";
// 设置要分析的APK文件
public final static String apkPath = "C:\\DynamicLoad\\Apks\\weibo.apk";
// dot保存目录
public final static String dotpath = "C:\\DynamicLoad\\CallGraph";
// 设置sourceAndSink目录
public final static String sourceAndSink = "C:\\SourcesAndSinks.txt"; private static Map<String, Boolean> visited = new HashMap<String, Boolean>();
//private static CGExporter cge = new CGExporter(); private static DotGraph dotGraph = new DotGraph("dot"); public static void main(String[] args) {
SetupApplication app = new SetupApplication(androidPath, apkPath);
try {
// 计算APK的入口点
app.calculateSourcesSinksEntrypoints(sourceAndSink);
} catch (Exception e) {
e.printStackTrace();
}
soot.G.reset(); Options.v().set_src_prec(Options.src_prec_apk);
Options.v().set_process_dir(Collections.singletonList(apkPath));
Options.v().set_force_android_jar(androidPath);
Options.v().set_whole_program(true);
Options.v().set_allow_phantom_refs(true);
Options.v().set_output_format(Options.output_format_none);
Options.v().setPhaseOption("cg.spark verbose:true", "on");
Scene.v().loadNecessaryClasses(); //SootMethod entryPoint = app.getEntryPointCreator().createDummyMain();
AndroidEntryPointCreator creator = app.getEntryPointCreator();
SootMethod entryPoint = creator.createDummyMain();
Options.v().set_main_class(entryPoint.getSignature());
Scene.v().setEntryPoints(Collections.singletonList(entryPoint));
PackManager.v().runPacks();
// 获取函数调用图
CallGraph cg = Scene.v().getCallGraph();
System.out.println("*********************************");
System.out.println(entryPoint);
System.out.println("*********************************");
// System.out.println(cg.toString());
System.out.println("*********************************");
toDot(cg, entryPoint);
File file = new File(dotpath, "test.dot");
OutputStream out;
try {
out = new FileOutputStream(file);
dotGraph.render(out, 0);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} private static void toDot(CallGraph cg, SootMethod m) { Iterator<MethodOrMethodContext> inTargets = new Targets(cg.edgesInto(m));
visited.put(m.getSignature(), true);
if (inTargets != null) {
while (inTargets.hasNext()) {
SootMethod in = (SootMethod) inTargets.next();
if (in == null) {
System.out.println("in is null");
}
System.out.println("----------------In Edge-----------");
System.out.println(in + " --> " + m);
DotGraphEdge dotGraphEdge = dotGraph.drawEdge(in + "", m + "");
dotGraphEdge.setLabel("inEdge");
dotGraph.drawNode(in + "");
dotGraph.drawNode(m + "");
System.out.println("************************************");
if (!visited.containsKey(in.getSignature())) {
toDot(cg, in);
}
}
} Iterator<MethodOrMethodContext> outTargets = new Targets(cg.edgesOutOf(m));
if (outTargets != null) {
while (outTargets.hasNext()) {
SootMethod out = (SootMethod) outTargets.next();
if (out == null) {
System.out.println("out is null");
}
System.out.println("----------------Out Edge-----------");
System.out.println(m + " --> " + out);
DotGraphEdge dotGraphEdge = dotGraph.drawEdge(m + "", out + "");
dotGraphEdge.setLabel("outEdge");
dotGraph.drawNode(m + "");
dotGraph.drawNode(out + "");
System.out.println("************************************");
if (!visited.containsKey(out.getSignature())) {
toDot(cg, out);
}
}
}
}
}
private SootMethod getMethodFromHierarchyEx(SootClass c, String methodSignature) {
if (c.declaresMethod(methodSignature))
return c.getMethod(methodSignature);
if (c.hasSuperclass())
return getMethodFromHierarchyEx(c.getSuperclass(), methodSignature);
throw new RuntimeException("Could not find method");
}