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, 2024 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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.