Information Security 5 min read

Static Analysis of ELF Binaries to Extract Function Call Relationships

This article describes how to statically analyze Linux ELF executables using objdump and shell scripts to collect function definitions, source locations, and call sites, and then construct a detailed function call graph with a C++ data structure.

Baidu Intelligent Testing
Baidu Intelligent Testing
Baidu Intelligent Testing
Static Analysis of ELF Binaries to Extract Function Call Relationships

This article explores a method for obtaining function call relationships by statically analyzing the disassembled code of ELF binaries.

ELF (Executable and Linkable Format) is the standard binary format on Linux, analogous to the PE format on Windows, and it contains extensive metadata that can be leveraged for analysis.

1. Collecting ELF binary information

Objdump is a powerful command‑line tool for disassembling programs.

objdump -d targetfile

Here targetfile is the binary to be analyzed. The disassembly output (shown in the original images) lists all functions in a compact form.

Although the output is assembly, it is organized into function bodies similar to C++ source; call sites are marked by the callq instruction. The C++ demangler c++filt can translate mangled names such as _Z6thr_fnPv back to their original form thr_fn(void*) .

Compiling with the -g option and using objdump -S -l targetfile adds source line information, producing a mixed source‑and‑assembly view (illustrated in the images) that reveals the exact file and line of each function definition.

From this enriched output we can extract the name of each function, the location of its definition, and the source location of every call, enabling a complete mapping of call relationships.

2. Algorithm

1) Function‑call element collection algorithm (shell implementation)

A. Collecting function definition information

Lines matching the pattern 000000000043a03c: are considered function definitions. Example shell snippet:

if [[ "$linetmp" =~ "<.*>:" ]]; then callfun=$(echo $line | awk -F "<" '{print $2}' | awk -F ">" '{print $1}' | sed 's/@plt$//g' | c++filt) fi

If source information is present, the following line matches )$ , and the third line matching [a-zA-Z]:[0-9][0-9]*$ provides the source file and line number.

B. Collecting function call information

Lines containing callq indicate a call site. Example snippet:

if [[ "$linetmp" =~ " callq" ]]; then callfun=$(echo $line | awk -F " " '{print $NF}') # the nearest preceding source‑location line gives the call location fi

2) Function call graph algorithm (C++ implementation)

The call graph is represented by a bidirectional linked structure:

struct functionnode { std::string funname; // full function name std::string definefuncpp; // definition source location std::list fatherfunlist; // callers of this function std::list callthislist; // locations where callers invoke this function std::list childfunlist; // functions called by this function };

Each node links to both its callers and callees, forming a network graph that can be visualized (as shown in the original diagrams).

elfReverse Engineeringstatic analysisfunction call graphobjdump
Baidu Intelligent Testing
Written by

Baidu Intelligent Testing

Welcome to follow.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.