Dissecting ELF with readelf
readelf
is a powerful tool that can be leveraged to dissect and understand ELF files. It can further help to understand how the linker and loader make use of the information present in it to load the executable into the memory. In this cheatsheet kind of self-reference post, the most important functions of this tool are described.
Reading file header
Run the tool with -h
or --file-header
displays the ELF header.
The header section of the ELF file contains the information about the ELF file itself. The tool parses the header section into separate attributes and displays them in a human readable format.
The header section of an object file is shown below.
$ readelf -h hello_math.o
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 832 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 64 (bytes)
Number of section headers: 12
Section header string table index: 11
The header section of an executable file is shown below:
readelf -h hello
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x1060
Start of program headers: 64 (bytes into file)
Start of section headers: 14832 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 13
Size of section headers: 64 (bytes)
Number of section headers: 31
Section header string table index: 30
Displaying section headers
Running the tool with -S
or --sections
or --section-headers
displays the section header, if it has any.
$ readelf -S hello_math.o
There are 12 section headers, starting at offset 0x340:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .text PROGBITS 0000000000000000 00000040
0000000000000045 0000000000000000 AX 0 0 1
[ 2] .data PROGBITS 0000000000000000 00000085
0000000000000000 0000000000000000 WA 0 0 1
[ 3] .bss NOBITS 0000000000000000 00000085
0000000000000000 0000000000000000 WA 0 0 1
[ 4] .comment PROGBITS 0000000000000000 00000085
000000000000002c 0000000000000001 MS 0 0 1
[ 5] .note.GNU-stack PROGBITS 0000000000000000 000000b1
0000000000000000 0000000000000000 0 0 1
[ 6] .note.gnu.propert NOTE 0000000000000000 000000b8
0000000000000020 0000000000000000 A 0 0 8
[ 7] .eh_frame PROGBITS 0000000000000000 000000d8
0000000000000078 0000000000000000 A 0 0 8
[ 8] .rela.eh_frame RELA 0000000000000000 00000290
0000000000000048 0000000000000018 I 9 7 8
[ 9] .symtab SYMTAB 0000000000000000 00000150
0000000000000120 0000000000000018 10 9 8
[10] .strtab STRTAB 0000000000000000 00000270
000000000000001a 0000000000000000 0 0 1
[11] .shstrtab STRTAB 0000000000000000 000002d8
0000000000000067 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
l (large), p (processor specific)
Brief description of the sections (src):
.text
: code of the executable.data
: initialized data.rodata
: read-only data.bss
: uninitialized data.plt
: Procedure Linkage Table.got
: GOT entried dedicated to dynamically linked global variables.got.plt
: GOT entries dedicated to dynamically linked functions.symtab
: global symbol table.dynamic
: holds all the needed information for dynamic linking.dynsym
: symbol tables dedicated to dynamically linked symbols.strtab
: striing table of .symtab section.dynstr
: string table of .dynsym section.interp
: RTLD embedded string.rel.dyn
: global variable relocation table.rel.plt
: function relocation table
Displaying Symbols
Running the tool with flag -s
or --symbols
displays the symbol table of the ELF file. Symbols (like function names) are stored under the section .symtab
(symbol table). Symbol table holds the information needed to relocate a program’s symbolic definitions and references. Typically this section is not allocable and thus will not be loaded in the memory.
$ readelf -s hello_math.o
Symbol table '.symtab' contains 12 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS hello_math.c
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
3: 0000000000000000 0 SECTION LOCAL DEFAULT 2
4: 0000000000000000 0 SECTION LOCAL DEFAULT 3
5: 0000000000000000 0 SECTION LOCAL DEFAULT 5
6: 0000000000000000 0 SECTION LOCAL DEFAULT 6
7: 0000000000000000 0 SECTION LOCAL DEFAULT 7
8: 0000000000000000 0 SECTION LOCAL DEFAULT 4
9: 0000000000000000 24 FUNC GLOBAL DEFAULT 1 add
10: 0000000000000018 22 FUNC GLOBAL DEFAULT 1 sub
11: 000000000000002e 23 FUNC GLOBAL DEFAULT 1 mul
In the above output, add
, sub
and mul
are the functions present in the file hello_math.c
.
Displaying section specific information
Running the tool with -p <number or name>
/--string-dump=<number or name>
, displays the content of the indicated section as printable strings. The argument can either be the section name or the index itself.
Running the tool with -x <number or name>
/--hex-dump=<number or name>
, displays the content of the indicated section in hexadecimal. The argument can either be the section name or the index itself.
Running the tool with -R <number or name>
/--relocated-dump=<number or name>
, the working is the same as above, but the content of the section will be relocated before they are displayed.
Displaying program headers
These flags display the program header, if it has any. These headers contain the execution information for the ELF file. If the ELF file is object file, it doesn’t contain any program headers. ~WIP~.