[Soot-list] Generating Android APK CallFlowGraph
Monika Mashalkar
monikamashalkar at gmail.com
Tue Feb 24 23:30:08 EST 2015
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 Hash*Map*<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/20150224/3ac03590/attachment-0003.html
More information about the Soot-list
mailing list