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.
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)
fiIf 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
fi2) 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<std::string> fatherfunlist; // callers of this function
std::list<std::string> callthislist; // locations where callers invoke this function
std::list<std::string> 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).
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
