question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

How to get Call graph using Androguard API

See original GitHub issue

Hi,

i want to extract call graph of the entire application using only the API and i am using XREF in order to do it. In addition, i would distinguish external call from internal call. How can i do that?

I made a simple function that do the following:

# dalvik is DalvikVMFormat
for d in dalvik:
    classes = d.get_classes()
    for c in classes:
        methods = c.get_methods()
        for method in methods:
            # x is Analysis object
            method_class_analysis = x.get_method_analysis(method)
            xref_to = method_class_analysis.get_xref_to()
            #add method to graph
            #and for each method in xref_to: add method to graph and add edge

In the variable xref_to I can find methods of type EncodedMethod and ExternalMethod (i can distinguish external call from internal code based on this type), but when I iterate over method (for method in methods) I don’t know if it is an external or internal one. This problem leads to an incorrect call graph.

Anyone can help?

Thanks.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:49 (25 by maintainers)

github_iconTop GitHub Comments

5reactions
reoxcommented, Apr 21, 2018

I just changed the code a little bit to get color for the methods:

from androguard.misc import AnalyzeAPK
from androguard.core.analysis.analysis import ExternalMethod
import matplotlib.pyplot as plt
import networkx as nx

a, d, dx = AnalyzeAPK("4e2201cde26141715255d2421f0bcfb1")

CFG = nx.DiGraph()

# Note: If you create the CFG from many classes at the same time, the drawing
# will be a total mess...
for m in dx.find_methods(classname="Lcom/elite/MainActivity;"):
    orig_method = m.get_method()
    print("Found Method --> {}".format(orig_method))
    # orig_method might be a ExternalMethod too...
    # so you can check it here also:
    if isinstance(orig_method, ExternalMethod):
        is_this_external = True
        # If this class is external, there will be very likely
        # no xref_to stored! If there is, it is probably a bug in androguard...
    else:
        is_this_external = False

    CFG.add_node(orig_method, external=is_this_external)

    for other_class, callee, offset in m.get_xref_to():
        if isinstance(callee, ExternalMethod):
            is_external = True
        else:
            is_external = False

        if callee not in CFG.node:
            CFG.add_node(callee, external=is_external)

        # As this is a DiGraph and we are not interested in duplicate edges,
        # check if the edge is already in the edge set.
        # If you need all calls, you probably want to check out MultiDiGraph
        if not CFG.has_edge(orig_method, callee):
            CFG.add_edge(orig_method, callee)

pos = nx.spring_layout(CFG)

internal = []
external = []

for n in CFG.node:
    if isinstance(n, ExternalMethod):
        external.append(n)
    else:
        internal.append(n)


nx.draw_networkx_nodes(CFG, pos=pos, node_color='r', nodelist=internal)
nx.draw_networkx_nodes(CFG, pos=pos, node_color='b', nodelist=external)
nx.draw_networkx_edges(CFG, pos, arrow=True)
nx.draw_networkx_labels(CFG, pos=pos, labels={x: "{} {}".format(x.get_class_name(), x.get_name()) for x in CFG.edge})
plt.draw()
plt.show()

figure_1-1

This also shows something important: If you inherit a class and this class is for example an API class, all methods that are not overwritten are also external. As you can see in the graph, there are methods like startService or setContentView, which are external (blue) but have the classname of an internal class.

1reaction
reoxcommented, Apr 23, 2018

Okay I see an imediate show stopper here: https://developer.android.com/studio/terms.html See especially point 3.4

So I would not put in the android jars into androguard… I think making this part optional with providing the path to the jars seems to be a good idea.

btw: In the prebuilds/sdk repo, there are also xml/txt files containing all the API description. And yes, the whole repo is huge (about 4,5GB)

Read more comments on GitHub >

github_iconTop Results From Across the Web

androguard cg - Create Call Graph from APK - Read the Docs
The default is to create a file called callgraph.gml in the current directory! classnames are found in the type "Lfoo/bar/bla;". Example: $ androguard...
Read more >
Static call graph extraction from Android application - Esther
The easiest way to tackle this problem is to use Androguard. We will see how it is easy to statically extract the call...
Read more >
Androguard Documentation - Read the Docs
If you want to create call graphs, use androguard cg, ... There are many more methods to explore, just take a look at...
Read more >
Parallelization of Machine Learning Applied to Call Graphs of ...
Therefore, we need to parallelize these algorithms in order to make them viable. The first step of our automatic-tuning malware detection engine consists...
Read more >
Analyzing Android Applications
"I have a game on the market called Sinister Planet which ... Baksmali (free), Androguard (free) ... You must search specific API in...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found