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.

0x90
  • 677
  • 2
  • 7
  • 19

4 Answers4

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

devtty1er
  • 13
  • 3
Megabeets
  • 8,989
  • 2
  • 24
  • 48
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().

Fish
  • 194
  • 5
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

Peter Teoh
  • 155
  • 4
n4sm
  • 63
  • 6
2

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

yaspr
  • 2,663
  • 14
  • 20