int g_int = 0xcafebabe;
int sum(int x, int y)
{
return x + y;
}
int main(int argc, char** argv)
{
int a = 1, b = 2;
int s = sum(a, b);
return 0;
}$ gcc main.c -o main$ readelf --wide --sections main
Section Headers:
[Nr] Name Type Address Off Size ES Flg Lk Inf Al
[ 6] .dynsym DYNSYM 00000000000003d8 0003d8 000090 18 A 7 1 8
[ 7] .dynstr STRTAB 0000000000000468 000468 000088 00 A 0 0 1
[12] .plt PROGBITS 0000000000001020 001020 000010 10 AX 0 0 16
[13] .plt.got PROGBITS 0000000000001030 001030 000010 10 AX 0 0 16
[14] .text PROGBITS 0000000000001040 001040 00013b 00 AX 0 0 16
[22] .got PROGBITS 0000000000003fc0 002fc0 000040 08 WA 0 0 8
[23] .data PROGBITS 0000000000004000 003000 000014 00 WA 0 0 8
[24] .bss NOBITS 0000000000004014 003014 000004 00 WA 0 0 1
[26] .symtab SYMTAB 0000000000000000 003048 000378 18 27 18 8
[27] .strtab STRTAB 0000000000000000 0033c0 0001d3 00 0 0 1
[28] .shstrtab STRTAB 0000000000000000 003593 00010c 00 0 0 1The .strtab section is a string table that contains null-terminated strings. Each string represents a symbol name.
$ readelf --string-dump=.strtab main
String dump of section '.strtab':
[ 134] g_int
[ 163] sum
[ 187] main Each line shows a symbol name and its offset within the .strtab section.
A symbol represents a function, a global variable, and other named entity. Section .symtab is the symbol table that map symbols to their addresses.
$ readelf --wide --symbols main
Symbol table '.symtab' contains 37 entries:
Num: Value Size Type Bind Vis Ndx Name
23: 0000000000004010 4 OBJECT GLOBAL DEFAULT 23 g_int
27: 0000000000001129 24 FUNC GLOBAL DEFAULT 14 sum
32: 0000000000001141 58 FUNC GLOBAL DEFAULT 14 main Relationships between .symtab and other sections.
┌────────────┐ ┌────────────┐ ┌────────────┐
│ .strtab │ │ .symtab │ │ section |
┼────────────┤ ┼────────────┤ ┼────────────┤
│ index ◄──┼───────┼─ st_index │ ┌────┼► index │
│ │ │ │ │ │ │
│ value │ │ st_shndx ─┼───┘ │ ..... │
└────────────┘ └────────────┘ └────────────┘In x86_64, a symbol is represented by struct Elf64_Sym. In x86_64, it is represented by Elf32_Sym.
// pahole elf64_sym
struct elf64_sym { // offset size
Elf64_Word st_name; // 0 4
unsigned char st_info; // 4 1
unsigned char st_other; // 5 1
Elf64_Half st_shndx; // 6 2
Elf64_Addr st_value; // 8 8
Elf64_Xword st_size; // 16 8
/* size: 24 bytes */
};Script hex_to_elf64_sym.py decodes hex dump to struct elf64_sym.
import struct
import sys
FMT_ELF64_SYM = "=IBBHQQ"
def hex_to_elf64_sym(hex_str: str):
data = bytes.fromhex(hex_str)
name, info, other, shndx, value, size = struct.unpack(FMT_ELF64_SYM, data)
print("name info other shndx value size")
print(hex(name), hex(info), hex(other),
hex(shndx), hex(value), hex(size))
hex_to_elf64_sym(sys.argv[1])$ readelf --wide --sections main
[Nr] Name Type Address Off Size ES Flg Lk Inf Al
[14] .text PROGBITS 0000000000001040 001040 00013b 00 AX 0 0 16
[23] .data PROGBITS 0000000000004000 003000 000014 00 WA 0 0 8
[26] .symtab SYMTAB 0000000000000000 003048 000378 18 27 18 8
[27] .strtab STRTAB 0000000000000000 0033c0 0001d3 00 0 0 1$ readelf --string-dump=.strtab main
[ 134] g_int
[ 163] sum
[ 187] main$ xxd -p -g 1 -c 24 -s 0x003048 -l 0x000378 main
340100001100170010400000000000000400000000000000
6301000012000e0029110000000000001800000000000000
8701000012000e0041110000000000003a00000000000000$ hex_to_elf64_sym.py 340100001100170010400000000000000400000000000000
name info other shndx value size
['0x134', '0x11', '0x0', '0x17', '0x4010', '0x4']$ hex_to_elf64_sym.py 6301000012000e0029110000000000001800000000000000
name info other shndx value size
['0x163', '0x12', '0x0', '0xe', '0x1129', '0x18']| First Line | ||
|---|---|---|
| st_name | 0x134 | Index 0x134 in .strtab: g_int |
| st_info | 0x11 | Type object, global |
| st_other | 0x0 | Visibility default |
| st_shndx | 0x17 | Section 0x17 = 23 = .data |
| st_value | 0x4010 | Offset 0x4010 |
| st_size | 0x4 | Size of 4 bytes |
| Second Line | ||
|---|---|---|
| st_name | 0x163 | Index 0x136 in .strtab: sum |
| st_info | 0x11 | Type func, global |
| st_other | 0x0 | Visibility default |
| st_shndx | 0x17 | Section: 0xe = 14 = .text |
| st_value | 0x4010 | Offset 0x1129 |
| st_size | 0x18 | Size of 24 bytes |