[Soot-list] Generating Android APK CallFlowGraph
Steven Arzt
Steven.Arzt at cased.de
Wed Feb 25 05:21:45 EST 2015
Hi Monika,
The CFG class is not part of Soot. It was just written as an example. You need to compile it on your own.
Best regards,
Steven
M.Sc. M.Sc. Steven Arzt
Secure Software Engineering Group (SSE)
European Center for Security and Privacy by Design (EC SPRIDE)
Rheinstraße 75
D-64293 Darmstadt
Phone: +49 61 51 869-336
Fax: +49 61 51 16-72118
eMail: <mailto:steven.arzt at ec-spride.de> steven.arzt at ec-spride.de
Web: http://sse.ec-spride.de <http://sse.ec-spride.de/>
Von: Monika Mashalkar [mailto:monikamashalkar at gmail.com]
Gesendet: Mittwoch, 25. Februar 2015 05:30
An: soot-list at googlegroups.com
Cc: soot-list at sable.mcgill.ca; soot-list at cs.mcgill.ca; Steven.Arzt at cased.de
Betreff: Re: [Soot-list] Generating Android APK CallFlowGraph
Hi Lokesh,
I am very new to the SOOT Framework and Flow-droid. I want to find the flow graph from android apk in my project and I am trying to run the code posted in this thread to do the same. I am trying to run the following command on Ubuntu
Command : java -cp soot-trunk.jar:soot-infoflow.jar:soot-infoflow-android.jar:slf4j-api-1.7.5.jar:slf4j-simple-1.7.5.jar:axml-2.0.jar -cp .:/usr/lib/jvm/java-7-openjdk-i386/jre/lib/rt.jar CFG
but I am getting Error as : Error: Could not find or load main class CFG
Could you please tell me the command to execute the CFG program.
Thank you,
Monika
On Monday, 21 July 2014 13:46:37 UTC+5:30, LOKESH JAIN wrote:
Hi all,
I resolved the issue and finally i am getting the call graph. Thank you all of you for your time and help. :)
1. But Stevan I am still curious to know how to work with QueueReader Object for generating dot format.
2. And why the size of call graph for RV2013.apk is 54. And is there any way to remove unnecessary size.
Thanks&Regards
Lokesh
On Mon, Jul 21, 2014 at 11:38 AM, LOKESH JAIN <lokesh... at gmail.com <javascript:> > wrote:
Hi all,
Steven I still couldn't figure it out how to work with queuereader object for generating dot format.
I have used dot graph class manually as suggested to me by Stefan but,
I am getting NullPointerException. I don't know why. I have pasted the complete code.
Please help me out.
Exception in thread "main" java.lang.NullPointerException
at DotGraph.getNode(DotGraph.java:53)
at DotGraph.drawNode(DotGraph.java:61)
at CFG.visit(CFG.java:114)
at CFG.main(CFG.java:94)
CFG.java
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.xmlpull.v1.XmlPullParserException;
import soot.MethodOrMethodContext;
import soot.PackManager;
import soot.Scene;
import soot.SootMethod;
import soot.jimple.infoflow.android.SetupApplication;
import soot.jimple.toolkits.callgraph.CallGraph;
import soot.jimple.toolkits.callgraph.Targets;
import soot.options.Options;
import soot.util.dot.DotGraphUtility;
import soot.util.dot.Renderable;
public class CFG {
private static DotGraph dot = new DotGraph("callgraph");
private static HashMap <String,Boolean> visited = new HashMap<String,Boolean>();
public CFG() {
}
public static void main(String[] args) {
// TODO Auto-generated method stub
SetupApplication app = new SetupApplication("/home/lokesh/Desktop/android-sdk-linux/platforms/android-19/android.jar","/home/lokesh/Desktop/android-instrumentation-tutorial-master/app-example/RV2013/bin/RV2013.apk");
try {
app.calculateSourcesSinksEntrypoints("/home/lokesh/Downloads/soot-infoflow-android-develop/SourcesAndSinks.txt");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
soot.G.reset();
Options.v().set_src_prec(Options.src_prec_apk);
Options.v().set_process_dir(Collections.singletonList("/home/lokesh/Desktop/android-instrumentation-tutorial-master/app-example/RV2013/bin/RV2013.apk"));
Options.v().set_force_android_jar("/home/lokesh/Desktop/android-sdk-linux/platforms/android-19/android.jar");
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();
Options.v().set_main_class(entryPoint.getSignature());
Scene.v().setEntryPoints(Collections.singletonList(entryPoint));
System.out.println("............"+entryPoint.getActiveBody());
PackManager.v().runPacks();
System.out.println(Scene.v().getCallGraph().size());
CallGraph cg = Scene.v().getCallGraph();
visit(cg, entryPoint);
dot.plot("/home/lokesh/Desktop/soot1"+ dot.DOT_EXTENSION);
}
private static void visit(CallGraph cg, SootMethod k)
{
String identifier = k.getName();
visited.put(k.getSignature(),true);
dot.drawNode(identifier);
//iterate over unvisited parents
Iterator<MethodOrMethodContext> ptargets = new Targets(cg.edgesInto(k));
if(ptargets != null){
while(ptargets.hasNext())
{
SootMethod p = (SootMethod) ptargets.next();
if(p == null) System.out.println("p is null");
if(!visited.containsKey(p.getSignature()))
visit(cg,p);
}
}
//iterate over unvisited children
Iterator<MethodOrMethodContext> ctargets = new Targets(cg.edgesOutOf(k));
if(ctargets != null){
while(ctargets.hasNext())
{
SootMethod c = (SootMethod) ctargets.next();
if(c == null) System.out.println("c is null");
dot.drawEdge(identifier, c.getName());
if(!visited.containsKey(c.getSignature()))
visit(cg,c);
}
}
}
}
DotGraph.java
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import soot.util.dot.DotGraphEdge;
import soot.util.dot.DotGraphNode;
import soot.util.dot.DotGraphUtility;
import soot.util.dot.Renderable;
public class DotGraph implements Renderable
{
public final static String DOT_EXTENSION = ".dot";
private HashMap<String, DotGraphNode> nodes;
private boolean isSubGraph;
private List<Renderable> drawElements;
private String graphname;
public DotGraph(String graphname)
{
this.drawElements = new LinkedList<Renderable>();
}
public DotGraph createSubGraph(String label)
{
DotGraph subgraph = new DotGraph(label);
subgraph.isSubGraph = true;
this.drawElements.add(subgraph);
System.out.println(subgraph);
return subgraph;
}
@Override
public void render(OutputStream out, int indent) throws IOException {
String graphname = this.graphname;
if (!isSubGraph) {
DotGraphUtility.renderLine(out, "digraph \""+graphname+"\" {", indent);
} else {
DotGraphUtility.renderLine(out, "subgraph \""+graphname+"\" {", indent);
}
}
public void plot(String filename) {
try {
BufferedOutputStream out =new BufferedOutputStream(new FileOutputStream(filename));
render(out, 0);
out.close();
} catch (IOException ioe) {
}
}
public DotGraphNode getNode(String name){
DotGraphNode node = nodes.get(name);
if (node == null) {
node = new DotGraphNode(name);
nodes.put(name, node);
}
return node;
}
public DotGraphNode drawNode(String name){
DotGraphNode node = getNode(name);
if(node == null)
throw new RuntimeException("Assertion failed.");
if(!this.drawElements.contains(node))
this.drawElements.add(node);
return node;
}
public DotGraphEdge drawEdge(String from, String to) {
DotGraphNode src = drawNode(from);
DotGraphNode dst = drawNode(to);
DotGraphEdge edge = new DotGraphEdge(src, dst);
this.drawElements.add(edge);
return edge;
}
}
Thanks & Regards
Lokesh
On Sun, Jul 20, 2014 at 5:10 PM, Stefan Gommer <gom... at informatik.uni-bremen.de <javascript:> > wrote:
Hi Lokesh,
sorry I misspelled it. Originally it is of type HashMap<String,Boolean>.
You can also use HashSet<String>. In this case you have to use visited.add(k.getSignature());
Regards,
Stefan
Am 20.07.2014 um 13:35 schrieb LOKESH JAIN <lokesh... at gmail.com <javascript:> >:
Hi Stefan,
HashSet<String,Boolean> type is giving error whereas HashSet<String> is correct form. But
then
visited.put(k.getSignature(),true) is giving error.
How do i resolve this?
Thanks & Regards
Lokesh
On Sun, Jul 20, 2014 at 4:52 PM, LOKESH JAIN <lokesh... at gmail.com <javascript:> > wrote:
Hi Stefan,
HashSet<String,Boolean> type is giving error whereas HashSet<String> is correct form. But
then
visited.put(k.getSignature(),true) is giving error.
Thanks & Regards
Lokesh
On Sun, Jul 20, 2014 at 4:16 PM, Stefan Gommer <gom... at informatik.uni-bremen.de <javascript:> > wrote:
Hi Lokesh,
visited is of type HashSet<String,Boolean> but can also be any kind of List like HashSet<String>
Regards
Stefan
Am 20.07.2014 um 12:44 schrieb LOKESH JAIN <lokesh... at gmail.com <javascript:> >:
Hey Stefan!
What is the type of "visited" ?
Thanks & Regards
Lokesh
On Sun, Jul 20, 2014 at 2:57 PM, Stefan Gommer <gom... at informatik.uni-bremen.de <javascript:> > wrote:
Hi Lokesh,
I did it like this (I skipped the standard soot settings:
private static DotGraph dot = new DotGraph("CallGraph“);
...
SootMethod entryPoint = app.getEntryPointCreator().createDummyMain();
…
PackManager.v().runPacks();
CallGraph cg = Scene.v().getCallGraph();
visit(cg, entryPoint);
…
dot.plot("/Users/neji/Desktop/graph"+ dot.DOT_EXTENSION);
…
private static void visit(CallGraph cg, SootMethod k)
{
String identifier = k.getName();
visited.put(k.getSignature(), true);
dot.drawNode(identifier);
//iterate over unvisited parents
Iterator<MethodOrMethodContext> ptargets = new Targets(cg.edgesInto(k));
if(ptargets != null){
while(ptargets.hasNext())
{
SootMethod p = (SootMethod) ptargets.next();
if(p == null) System.out.println("p is null");
if(!visited.containsKey(p.getSignature()))
visit(cg,p);
}
}
//iterate over unvisited children
Iterator<MethodOrMethodContext> ctargets = new Targets(cg.edgesOutOf(k));
if(ctargets != null){
while(ctargets.hasNext())
{
SootMethod c = (SootMethod) ctargets.next();
if(c == null) System.out.println("c is null");
dot.drawEdge(identifier, c.getName());
if(!visited.containsKey(c.getSignature()))
visit(cg,c);
}
}
}
Am 20.07.2014 um 09:44 schrieb LOKESH JAIN <lokesh... at gmail.com <javascript:> >:
I have tried DotGraph class from the soot.util.dot package but it's giving me null pointer exception. Following is the tried code.
I have converted QueueReader object into string as DotGraph takes only string argument. It's getting complicated. Please suggest some simple solution.
import java.io.IOException;
import java.io.OutputStream;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import org.xmlpull.v1.XmlPullParserException;
import soot.PackManager;
import soot.Scene;
import soot.SootMethod;
import soot.jimple.infoflow.android.SetupApplication;
import soot.options.Options;
import soot.util.dot.DotGraphUtility;
import soot.util.dot.Renderable;
public class CFG {
//private static Map options;
static DotGraph dg;
public CFG() {
//this.options=options;
// TODO Auto-generated constructor stub
}
/*public DotGraph createSubGraph(String label)
{
DotGraph createSubGraph = DotGraph.createSubGraph(Scene.v().getCallGraph().listener().toString());
}*/
public static void main(String[] args) {
// TODO Auto-generated method stub
SetupApplication app = new SetupApplication("/home/lokesh/Desktop/android-sdk-linux/platforms/android-19/android.jar","/home/lokesh/Desktop/android-instrumentation-tutorial-master/app-example/RV2013/bin/RV2013.apk");
try {
app.calculateSourcesSinksEntrypoints("/home/lokesh/Downloads/soot-infoflow-android-develop/SourcesAndSinks.txt");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
soot.G.reset();
Options.v().set_src_prec(Options.src_prec_apk);
Options.v().set_process_dir(Collections.singletonList("/home/lokesh/Desktop/android-instrumentation-tutorial-master/app-example/RV2013/bin/RV2013.apk"));
Options.v().set_force_android_jar("/home/lokesh/Desktop/android-sdk-linux/platforms/android-19/android.jar");
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();
Options.v().set_main_class(entryPoint.getSignature());
Scene.v().setEntryPoints(Collections.singletonList(entryPoint));
System.out.println("............"+entryPoint.getActiveBody());
PackManager.v().runPacks();
System.out.println(Scene.v().getCallGraph().size());
String label = Scene.v().getCallGraph().listener().toString();
dg.createSubGraph(label);
}
}
import java.io.IOException;
import java.io.OutputStream;
import java.util.LinkedList;
import java.util.List;
import soot.util.dot.DotGraphUtility;
import soot.util.dot.Renderable;
public class DotGraph implements Renderable
{
private boolean isSubGraph;
private List<Renderable> drawElements;
private String graphname;
public DotGraph(String graphname)
{
this.drawElements = new LinkedList<Renderable>();
}
public DotGraph createSubGraph(String label)
{
DotGraph subgraph = new DotGraph(label);
subgraph.isSubGraph = true;
this.drawElements.add(subgraph);
System.out.println(subgraph);
return subgraph;
}
@Override
public void render(OutputStream out, int indent) throws IOException {
String graphname = this.graphname;
if (!isSubGraph) {
DotGraphUtility.renderLine(out, "digraph \""+graphname+"\" {", indent);
} else {
DotGraphUtility.renderLine(out, "subgraph \""+graphname+"\" {", indent);
}
}
}
Thanks & Regards
Lokesh
On Sat, Jul 19, 2014 at 10:57 PM, Stefan Gommer <gommer... at googlemail.com <javascript:> > wrote:
Hi Lokesh,
you could use the DotGraph class from the soot.util.dot package and build a Graph on your own while traversing through the cfg. I don’t know if there is a method to do this automatically.
Stefan
Am 19.07.2014 um 15:16 schrieb LOKESH JAIN <lokesh... at gmail.com <javascript:> >:
Hi Steven,
this Scene.v().getCallgraph().listener() is giving me QueueReader object. But I am not able to create a dot file from it. I have tried dump_cfg and various others options but all are of no help.
1. Please can you tell me how do i print a dot file out of QueueReader object?
Also I am getting the call graph size as 54 for the general example apk "RV2013.apk".
2. How come call graph size is 54?
On Fri, Jul 18, 2014 at 9:37 PM, Steven Arzt <Steve... at cased.de <javascript:> > wrote:
Hi Lokesh,
You can manually iterate over the callgraph using Scene.v().getCallgraph().listener() and print it out in dot format which should be fairly simple as it is just a QueueReader over the edges. Still, I think Soot can also directly do that, but I have never used the dot visualizer for callgraphs.
Afterwards, you can visualize the dot file using GraphViz.
Best regards,
Steven
Von: LOKESH JAIN [mailto:lokesh... at gmail.com <javascript:> ]
Gesendet: Freitag, 18. Juli 2014 18:04
An: Steven Arzt
Cc: Modhi Alsobiehy; soot... at cs.mcgill.ca <javascript:> ; soot... at sable.mcgill.ca <javascript:> ; soot... at googlegroups.com <javascript:>
Betreff: Re: [Soot-list] Generating Android APK CallFlowGraph
Hi,
A gentle reminder. Please reply fast. I need it for my research project.
Regards
Lokesh
On Thu, Jul 17, 2014 at 9:21 PM, LOKESH JAIN <lokesh... at gmail.com <javascript:> > wrote:
Thanks a lot Steven and Modhi. It worked.
It is showing call graph in words. How can I graphically see the call graph for apk files as we see for java files??
Regards
Lokesh Jain
On Thu, Jul 17, 2014 at 6:11 PM, Steven Arzt <Steve... at cased.de <javascript:> > wrote:
Hi Lokesh,
It seems that you are missing the axml-2.0.jar library on your Java classpath.
Best regards,
Steven
Von: soot-lis... at CS.McGill.CA <javascript:> [mailto:soot-lis... at CS.McGill.CA <javascript:> ] Im Auftrag von Modhi Alsobiehy
Gesendet: Donnerstag, 17. Juli 2014 14:39
An: LOKESH JAIN
Cc: soot... at cs.mcgill.ca <javascript:> ; soot... at sable.mcgill.ca <javascript:> ; soot... at googlegroups.com <javascript:>
Betreff: Re: [Soot-list] Generating Android APK CallFlowGraph
Hi Lokesh,
Open the folder of your project and add the call back file into it.
-Best,
Modhi
On Jul 17, 2014, at 12:03 PM, "LOKESH JAIN" <lokesh... at gmail.com <javascript:> > wrote:
Hi all,
Modhi, I am using your code for generating call graph for apk file. But, I am getting following error
Exception in thread "main" java.lang.NoClassDefFoundError: pxb/android/axml/NodeVisitor
at soot.jimple.infoflow.android.manifest.ProcessManifest.handle(Unknown Source)
at soot.jimple.infoflow.android.manifest.ProcessManifest.<init>(Unknown Source)
at soot.jimple.infoflow.android.manifest.ProcessManifest.<init>(Unknown Source)
at soot.jimple.infoflow.android.SetupApplication.calculateSourcesSinksEntrypoints(Unknown Source)
at soot.jimple.infoflow.android.SetupApplication.calculateSourcesSinksEntrypoints(Unknown Source)
at CFG.main(CFG.java:33)
Caused by: java.lang.ClassNotFoundException: pxb.android.axml.NodeVisitor
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 6 more
It's pretty much the same error that you were getting. Though I had checked , there is no duplicate library added. Also there is already AndroidCallbacks.txt in soot-infoflow-android, i haven't understood how to add it into my project.
Any help would be appreciated. Thank You
Regards
Lokesh
On Saturday, 5 July 2014 23:04:49 UTC+5:30, Modhi Alsobiehy wrote:
Hi all,
I need to traverse the call flow graph of android apps( apk files).
I understand that I must set an entry point so to start, I tried the following code :
---------------------
...
-------------- next part --------------
An HTML attachment was scrubbed...
URL: https://mailman.CS.McGill.CA/pipermail/soot-list/attachments/20150225/1084ae93/attachment-0003.html
More information about the Soot-list
mailing list