18

I have a non-stripped ELF binary for which I want to create a call graph as a dot file. Is there such a tool which generates the call graph?

EDIT: Is there away in addition to the conventional call graph to find a call graph between libraries based on the executable. For example showing the call graph only of from libc to pthread.

1
  • Another option would be: rizin.re
    – 0x90
    Commented Apr 7 at 8:46

4 Answers 4

21

You can use radare2 or one of the alternatives below to generate a full call-graph in dot format.

radare2 Installation

First of all, install radare2 from git repository:

$ git clone https://github.com/radare/radare2.git
$ cd radare2
$ ./sys/install.sh

Analysis

After you've downloaded and installed radare2, open your binary and perform analysis on it using the aaa command:

$ r2 /bin/ls
[0x004049a0]> aaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Constructing a function name for fcn.* and sym.func.* functions (aan)
[x] Type matching analysis for all functions (afta)
[x] Use -AA or aaaa to perform additional experimental analysis.

Output visual graph

The ag command and subcommands can help you to output the visual graph into Graphviz format.

[0x00000000]> ag?
Usage: ag<graphtype><format> [addr]
Graph commands:
| aga[format]             Data references graph
| agA[format]             Global data references graph
| agc[format]             Function callgraph
| agC[format]             Global callgraph
| agd[format] [fcn addr]  Diff graph
| agf[format]             Basic blocks function graph
| agi[format]             Imports graph
| agr[format]             References graph
| agR[format]             Global references graph
| agx[format]             Cross references graph
| agg[format]             Custom graph
| ag-                     Clear the custom graph
| agn[?] title body       Add a node to the custom graph
| age[?] title1 title2    Add an edge to the custom graph

Output formats:
| <blank>                 Ascii art
| *                       r2 commands
| d                       Graphviz dot
... <truncated> ...
| w [path]                Write to path or display graph image (see graph.gv.format and graph.web)

You're searching for the agCd command. The C specifies to output a full ("global") call-graph of the program. The d specifies to output in Graphviz dot format.

[0x004049a0]> agCd > output.dot

The dot utility is part of the Graphviz software which can be installed using sudo apt-get install graphviz.
You can view your output in any offline dot viewer, paste the output into an online Graphviz viewer and even convert the dot file to PNG:

$ r2 /bin/ls
[0x004049a0]> aa
[x] Analyze all flags starting with sym. and entry0 (aa)
[0x004049a0]> agCd > output.dot
[0x004049a0]> !!dot -Tpng -o callgraph.png output.dot

To read more about radare2 it is recommended to read radare2 book.


Alternatives

  • gen-callgraph - gen-callgraph is a script to generate call graph from elf binary

  • IDA Pro - generate GDL (Graph Description File) call graph using CTRL+F12, save it and then convert it to dot file with one of the following options:

The free version of IDA is also capable of generate GDL of call graph but it is only available as exe, use wine on Linux to run it

3
  • Is there away to get a call graph between libraries or files rather call graph between functions?
    – 0x90
    Commented Aug 13, 2017 at 19:44
  • 1
    You can use il to get libraries used by the binary or rabin2 -l /bin/ls which is the same
    – Megabeets
    Commented Aug 15, 2017 at 18:43
  • I don't know of a command to generate a call graph of only libraries, sorry
    – Megabeets
    Commented Aug 15, 2017 at 19:02
8

You might want to give angr a try.

  • Load the binary. Suppose p is the angr Project instance.
  • Generate a CFG: cfg = p.analyses.CFG(show_progressbar=True).
  • Access/traverse the call graph (which is a networkx.DiGraph) in whatever way you want: cfg.functions.callgraph.

For example showing the call graph only of specific address range or specific static library

You can limit the range of CFG generation by passing the regions argument to CFG().

0
3

You can use angr-utils in order to generate the graph from angr : https://github.com/axt/angr-utils

For more information please see:

https://github.com/axt/angr-utils/blob/master/examples/plot_cg/README.md

enter image description here

1
  • You should elaborate a bit...
    – perror
    Commented Feb 16, 2020 at 23:14
2

Check out Callgrind or KCachegrind. Much simpler than any other alternative.

2
  • but are these static analyzers? or only report what is called in some typical run?
    – rfabbri
    Commented Jul 23, 2019 at 23:38
  • Callgrind is based on Valgrind, a serializing dynamic analysis framework.
    – yaspr
    Commented Jan 4, 2020 at 9:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.