binutils
分析 ELF 文件的工具主要有如下几个:
$ dpkg -L binutils
/usr/bin/nm
/usr/bin/objdump
/usr/bin/readelf
实际上是它们都是指向 binutils-x86-64-linux-gnu 中文件的符号链接:
$ dpkg -L binutils-x86-64-linux-gnu
/usr/bin/x86_64-linux-gnu-nm
/usr/bin/x86_64-linux-gnu-objdump
/usr/bin/x86_64-linux-gnu-readelf
$ sudo apt install pax-utils
$ dpkg -L pax-utils
/usr/bin/dumpelf
/usr/bin/lddtree
/usr/bin/pspax
/usr/bin/scanelf
/usr/bin/scanmacho
/usr/bin/symtree
ELF file header
ELF 主要结构体定义:
$ man 5 elf
读取 ELF file header:
$ readelf -h main.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: 1560 (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: 13
Section header string table index: 12
$ readelf -h main
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: 0x700
Start of program headers: 64 (bytes into file)
Start of section headers: 6680 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 9
Size of section headers: 64 (bytes)
Number of section headers: 29
Section header string table index: 28
$ readelf -h libso.so.1.0.0
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: 0x620
Start of program headers: 64 (bytes into file)
Start of section headers: 6248 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 7
Size of section headers: 64 (bytes)
Number of section headers: 28
Section header string table index: 27
$ cat > gomain.go <<EOF
> package main
>
> import "fmt"
>
> func main() {
> fmt.Println("Hello world")
> }
> EOF
$ go build gomain.go
$ readelf -h gomain
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: EXEC (Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x452270
Start of program headers: 64 (bytes into file)
Start of section headers: 456 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 7
Size of section headers: 64 (bytes)
Number of section headers: 24
Section header string table index: 3
e_type This member of the structure identifies the object file type:
ET_NONE An unknown type.
ET_REL A relocatable file.
ET_EXEC An executable file.
ET_DYN A shared object.
ET_CORE A core file.
ET_REL
表示编译过程中的对象文件(gcc -c),ET_EXEC
表示静态链接的可执行文件,ET_DYN
表示动态链接的可执行文件或动态库,ET_CORE
表示 coredump 文件。
dumpelf 比 readelf 更接近底层实现(以数据结构的形式进行呈现):
$ dumpelf -v main
#include <elf.h>
/*
* ELF dump of 'main'
* 8536 (0x2158) bytes
*/
Elf64_Dyn dumpedelf_dyn_0[];
struct {
Elf64_Ehdr ehdr;
Elf64_Phdr phdrs[9];
Elf64_Shdr shdrs[29];
Elf64_Dyn *dyns;
} dumpedelf_0 = {
.ehdr = {
.e_ident = { /* (EI_NIDENT bytes) */
/* [0] EI_MAG: */ 0x7F,'E','L','F',
/* [4] EI_CLASS: */ 2 , /* (ELFCLASS64) */
/* [5] EI_DATA: */ 1 , /* (ELFDATA2LSB) */
/* [6] EI_VERSION: */ 1 , /* (EV_CURRENT) */
/* [7] EI_OSABI: */ 0 , /* (ELFOSABI_NONE) */
/* [8] EI_ABIVERSION: */ 0 ,
/* [9-15] EI_PAD: */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
},
.e_type = 3 , /* (ET_DYN) */
.e_machine = 62 , /* (EM_X86_64) */
.e_version = 1 , /* (EV_CURRENT) */
.e_entry = 0x700 , /* (start address at runtime) */
.e_phoff = 64 , /* (bytes into file) */
.e_shoff = 6680 , /* (bytes into file) */
.e_flags = 0x0 ,
.e_ehsize = 64 , /* (bytes) */
.e_phentsize = 56 , /* (bytes) */
.e_phnum = 9 , /* (program headers) */
.e_shentsize = 64 , /* (bytes) */
.e_shnum = 29 , /* (section headers) */
.e_shstrndx = 28
},
.phdrs = {
/* Program Header #0 0x40 */
{
.p_type = 6 , /* [PT_PHDR] */
.p_offset = 64 , /* (bytes into file) */
.p_vaddr = 0x40 , /* (virtual addr at runtime) */
...
// DT_RPATH String table offset to library search path
$ scanelf -r main
TYPE RPATH FILE
ET_DYN . main
// DT_NEEDED String table offset to name of a needed library
$ scanelf -n main
TYPE NEEDED FILE
ET_DYN libso.so.1,libc.so.6 main
Whenever a library defines a soname, it is that soname that is stored in the DT_NEEDED field of ELF objects linked against that library.
program headers (describing segments in execution view)
读取 ELF program headers:
$ readelf -l main
Elf file type is DYN (Shared object file)
Entry point 0x700
There are 9 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000000040 0x0000000000000040
0x00000000000001f8 0x00000000000001f8 R 0x8
INTERP 0x0000000000000238 0x0000000000000238 0x0000000000000238
0x000000000000001c 0x000000000000001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000bd8 0x0000000000000bd8 R E 0x200000
LOAD 0x0000000000000d88 0x0000000000200d88 0x0000000000200d88
0x0000000000000289 0x00000000000002a0 RW 0x200000
DYNAMIC 0x0000000000000d98 0x0000000000200d98 0x0000000000200d98
0x0000000000000210 0x0000000000000210 RW 0x8
NOTE 0x0000000000000254 0x0000000000000254 0x0000000000000254
0x0000000000000044 0x0000000000000044 R 0x4
GNU_EH_FRAME 0x0000000000000a40 0x0000000000000a40 0x0000000000000a40
0x000000000000004c 0x000000000000004c R 0x4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 0x10
GNU_RELRO 0x0000000000000d88 0x0000000000200d88 0x0000000000200d88
0x0000000000000278 0x0000000000000278 R 0x1
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .plt.got .text .fini .rodata .eh_frame_hdr .eh_frame
03 .init_array .fini_array .dynamic .got .data .bss
04 .dynamic
05 .note.ABI-tag .note.gnu.build-id
06 .eh_frame_hdr
07
08 .init_array .fini_array .dynamic .got
查看进程地址空间(内存视图):
$ man pmap
$ cat /proc/15929/maps
555555554000-555555555000 r-xp 00000000 08:05 412321 /home/runsisi/working/test/elf-symbol-experiment/main
555555754000-555555755000 r--p 00000000 08:05 412321 /home/runsisi/working/test/elf-symbol-experiment/main
555555755000-555555756000 rw-p 00001000 08:05 412321 /home/runsisi/working/test/elf-symbol-experiment/main
555555756000-555555777000 rw-p 00000000 00:00 0 [heap]
7ffff77e2000-7ffff79c9000 r-xp 00000000 08:05 7357802 /lib/x86_64-linux-gnu/libc-2.27.so
7ffff79c9000-7ffff7bc9000 ---p 001e7000 08:05 7357802 /lib/x86_64-linux-gnu/libc-2.27.so
7ffff7bc9000-7ffff7bcd000 r--p 001e7000 08:05 7357802 /lib/x86_64-linux-gnu/libc-2.27.so
7ffff7bcd000-7ffff7bcf000 rw-p 001eb000 08:05 7357802 /lib/x86_64-linux-gnu/libc-2.27.so
7ffff7bcf000-7ffff7bd3000 rw-p 00000000 00:00 0
7ffff7bd3000-7ffff7bd4000 r-xp 00000000 08:05 418522 /home/runsisi/working/test/elf-symbol-experiment/libso.so.1.0.0
7ffff7bd4000-7ffff7dd3000 ---p 00001000 08:05 418522 /home/runsisi/working/test/elf-symbol-experiment/libso.so.1.0.0
7ffff7dd3000-7ffff7dd4000 r--p 00000000 08:05 418522 /home/runsisi/working/test/elf-symbol-experiment/libso.so.1.0.0
7ffff7dd4000-7ffff7dd5000 rw-p 00001000 08:05 418522 /home/runsisi/working/test/elf-symbol-experiment/libso.so.1.0.0
7ffff7dd5000-7ffff7dfc000 r-xp 00000000 08:05 7352967 /lib/x86_64-linux-gnu/ld-2.27.so
7ffff7fc0000-7ffff7fc3000 rw-p 00000000 00:00 0
7ffff7ff5000-7ffff7ff7000 rw-p 00000000 00:00 0
7ffff7ff7000-7ffff7ffa000 r--p 00000000 00:00 0 [vvar]
7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0 [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00027000 08:05 7352967 /lib/x86_64-linux-gnu/ld-2.27.so
7ffff7ffd000-7ffff7ffe000 rw-p 00028000 08:05 7352967 /lib/x86_64-linux-gnu/ld-2.27.so
7ffff7ffe000-7ffff7fff000 rw-p 00000000 00:00 0
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
更详细的进程地址空间信息(pmap -X):
$ cat /proc/15929/smaps
555555554000-555555555000 r-xp 00000000 08:05 412321 /home/runsisi/working/test/elf-symbol-experiment/main
Size: 4 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Rss: 4 kB
Pss: 4 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 4 kB
Referenced: 4 kB
Anonymous: 4 kB
LazyFree: 0 kB
AnonHugePages: 0 kB
ShmemPmdMapped: 0 kB
Shared_Hugetlb: 0 kB
Private_Hugetlb: 0 kB
Swap: 0 kB
SwapPss: 0 kB
Locked: 0 kB
...
section headers (describing sections in linking view)
读取 ELF section headers:
$ readelf -S main
There are 29 section headers, starting at offset 0x1a18:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .interp PROGBITS 0000000000000238 00000238
000000000000001c 0000000000000000 A 0 0 1
[ 2] .note.ABI-tag NOTE 0000000000000254 00000254
0000000000000020 0000000000000000 A 0 0 4
[ 3] .note.gnu.build-i NOTE 0000000000000274 00000274
0000000000000024 0000000000000000 A 0 0 4
[ 4] .gnu.hash GNU_HASH 0000000000000298 00000298
0000000000000040 0000000000000000 A 5 0 8
[ 5] .dynsym DYNSYM 00000000000002d8 000002d8
0000000000000180 0000000000000018 A 6 1 8
[ 6] .dynstr STRTAB 0000000000000458 00000458
00000000000000d9 0000000000000000 A 0 0 1
...
反汇编指定的 section:
$ objdump -d -j .text main | grep -A 20 \<main\>:
000000000000080a <main>:
80a: 55 push %rbp
80b: 48 89 e5 mov %rsp,%rbp
80e: 48 8d 3d 7f 01 00 00 lea 0x17f(%rip),%rdi # 994 <_IO_stdin_used+0x4>
815: e8 a6 fe ff ff callq 6c0 <puts@plt>
81a: b8 00 00 00 00 mov $0x0,%eax
81f: e8 a8 00 00 00 callq 8cc <x_hello>
824: b8 00 00 00 00 mov $0x0,%eax
829: e8 b2 fe ff ff callq 6e0 <so_hello@plt>
82e: c6 05 db 07 20 00 62 movb $0x62,0x2007db(%rip) # 201010 <g_x_char>
835: 48 c7 05 d8 07 20 00 movq $0x2,0x2007d8(%rip) # 201018 <g_so_long>
83c: 02 00 00 00
840: 48 8d 3d 64 01 00 00 lea 0x164(%rip),%rdi # 9ab <_IO_stdin_used+0x1b>
847: e8 74 fe ff ff callq 6c0 <puts@plt>
84c: 0f b6 05 bd 07 20 00 movzbl 0x2007bd(%rip),%eax # 201010 <g_x_char>
853: 0f be c0 movsbl %al,%eax
856: 89 c2 mov %eax,%edx
858: 48 8d 35 b1 07 20 00 lea 0x2007b1(%rip),%rsi # 201010 <g_x_char>
85f: 48 8d 3d 5d 01 00 00 lea 0x15d(%rip),%rdi # 9c3 <_IO_stdin_used+0x33>
866: b8 00 00 00 00 mov $0x0,%eax
86b: e8 60 fe ff ff callq 6d0 <printf@plt>
...
relocation section
$ readelf -r main
Relocation section '.rela.dyn' at offset 0x578 contains 9 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000200d88 000000000008 R_X86_64_RELATIVE 800
000000200d90 000000000008 R_X86_64_RELATIVE 7c0
000000201008 000000000008 R_X86_64_RELATIVE 201008
000000200fd8 000100000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_deregisterTMClone + 0
000000200fe0 000400000006 R_X86_64_GLOB_DAT 0000000000000000 __libc_start_main@GLIBC_2.2.5 + 0
000000200fe8 000500000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
000000200ff0 000700000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_registerTMCloneTa + 0
000000200ff8 000800000006 R_X86_64_GLOB_DAT 0000000000000000 __cxa_finalize@GLIBC_2.2.5 + 0
000000201018 000b00000005 R_X86_64_COPY 0000000000201018 g_so_long + 0
Relocation section '.rela.plt' at offset 0x650 contains 3 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000200fc0 000200000007 R_X86_64_JUMP_SLO 0000000000000000 puts@GLIBC_2.2.5 + 0
000000200fc8 000300000007 R_X86_64_JUMP_SLO 0000000000000000 printf@GLIBC_2.2.5 + 0
000000200fd0 000600000007 R_X86_64_JUMP_SLO 0000000000000000 so_hello + 0
dynamic section
.dynamic: Holds all needed information for dynamic linking.
d_tag This member may have any of the following values:
DT_NULL Marks end of dynamic section
DT_NEEDED String table offset to name of a needed library
DT_PLTRELSZ Size in bytes of PLT relocation entries
DT_PLTGOT Address of PLT and/or GOT // exe .got / so .got.plt
DT_HASH Address of symbol hash table // .gnu.hash
DT_STRTAB Address of string table // .dynstr
DT_SYMTAB Address of symbol table // .dynsym
DT_RELA Address of Rela relocation table // .rela.dyn
DT_RELASZ Size in bytes of the Rela relocation table
DT_RELAENT Size in bytes of a Rela relocation table entry
DT_STRSZ Size in bytes of string table
DT_SYMENT Size in bytes of a symbol table entry
DT_INIT Address of the initialization function // .init
DT_FINI Address of the termination function // .fini
DT_SONAME String table offset to name of shared object
DT_RPATH String table offset to library search path (deprecated)
DT_SYMBOLIC Alert linker to search this shared object before the exe‐
cutable for symbols
DT_REL Address of Rel relocation table
DT_RELSZ Size in bytes of Rel relocation table
DT_RELENT Size in bytes of a Rel table entry
DT_PLTREL Type of relocation entry to which the PLT refers (Rela or
Rel)
DT_DEBUG Undefined use for debugging
DT_TEXTREL Absence of this entry indicates that no relocation entries
should apply to a nonwritable segment
DT_JMPREL Address of relocation entries associated solely with the
PLT // .rela.plt
DT_BIND_NOW Instruct dynamic linker to process all relocations before
transferring control to the executable
DT_RUNPATH String table offset to library search path
DT_LOPROC, DT_HIPROC
Values in the inclusive range [DT_LOPROC, DT_HIPROC] are
reserved for processor-specific semantics
$ readelf -d main
Dynamic section at offset 0xd98 contains 29 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libso.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000001d (RUNPATH) Library runpath: [.]
0x000000000000000c (INIT) 0x698
0x000000000000000d (FINI) 0x984
0x0000000000000019 (INIT_ARRAY) 0x200d88
0x000000000000001b (INIT_ARRAYSZ) 8 (bytes)
0x000000000000001a (FINI_ARRAY) 0x200d90
0x000000000000001c (FINI_ARRAYSZ) 8 (bytes)
0x000000006ffffef5 (GNU_HASH) 0x298
0x0000000000000005 (STRTAB) 0x458
0x0000000000000006 (SYMTAB) 0x2d8
0x000000000000000a (STRSZ) 217 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000015 (DEBUG) 0x0
0x0000000000000003 (PLTGOT) 0x200fa8
0x0000000000000002 (PLTRELSZ) 72 (bytes)
0x0000000000000014 (PLTREL) RELA
0x0000000000000017 (JMPREL) 0x650
0x0000000000000007 (RELA) 0x578
0x0000000000000008 (RELASZ) 216 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x000000000000001e (FLAGS) BIND_NOW
0x000000006ffffffb (FLAGS_1) Flags: NOW PIE
0x000000006ffffffe (VERNEED) 0x558
0x000000006fffffff (VERNEEDNUM) 1
0x000000006ffffff0 (VERSYM) 0x532
0x000000006ffffff9 (RELACOUNT) 3
0x0000000000000000 (NULL) 0x0
symbols
.dynsym + .symtab
$ readelf -s main
Symbol table '.dynsym' contains 16 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTab
2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND puts@GLIBC_2.2.5 (2)
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (2)
4: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
5: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
6: 0000000000000000 0 FUNC GLOBAL DEFAULT UND so_hello
7: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable
8: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@GLIBC_2.2.5 (2)
9: 0000000000201011 0 NOTYPE GLOBAL DEFAULT 23 _edata
10: 0000000000201028 0 NOTYPE GLOBAL DEFAULT 24 _end
11: 0000000000201018 8 OBJECT GLOBAL DEFAULT 24 g_so_long
12: 0000000000201011 0 NOTYPE GLOBAL DEFAULT 24 __bss_start
13: 0000000000000698 0 FUNC GLOBAL DEFAULT 11 _init
14: 0000000000000984 0 FUNC GLOBAL DEFAULT 15 _fini
15: 00000000000008b9 19 FUNC GLOBAL DEFAULT 14 common_func
Symbol table '.symtab' contains 70 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000238 0 SECTION LOCAL DEFAULT 1
2: 0000000000000254 0 SECTION LOCAL DEFAULT 2
3: 0000000000000274 0 SECTION LOCAL DEFAULT 3
4: 0000000000000298 0 SECTION LOCAL DEFAULT 4
5: 00000000000002d8 0 SECTION LOCAL DEFAULT 5
...
.dynsym: symbol tables dedicated to dynamically linked symbols.
$ readelf --dyn-syms main
Symbol table '.dynsym' contains 16 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTab
2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND puts@GLIBC_2.2.5 (2)
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (2)
4: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
5: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
6: 0000000000000000 0 FUNC GLOBAL DEFAULT UND so_hello
7: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable
8: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@GLIBC_2.2.5 (2)
9: 0000000000201011 0 NOTYPE GLOBAL DEFAULT 23 _edata
10: 0000000000201028 0 NOTYPE GLOBAL DEFAULT 24 _end
11: 0000000000201018 8 OBJECT GLOBAL DEFAULT 24 g_so_long
12: 0000000000201011 0 NOTYPE GLOBAL DEFAULT 24 __bss_start
13: 0000000000000698 0 FUNC GLOBAL DEFAULT 11 _init
14: 0000000000000984 0 FUNC GLOBAL DEFAULT 15 _fini
15: 00000000000008b9 19 FUNC GLOBAL DEFAULT 14 common_func
objdump 在显示符号时支持 demangle (-C
选项) 且信息更为直观(readelf 中的 Ndx 字段在 objdump 中直接翻译成了 section 名字):
.dynsym + .symtab
$ objdump -t -C main
main: file format elf64-x86-64
SYMBOL TABLE:
0000000000000238 l d .interp 0000000000000000 .interp
0000000000000254 l d .note.ABI-tag 0000000000000000 .note.ABI-tag
0000000000000274 l d .note.gnu.build-id 0000000000000000 .note.gnu.build-id
0000000000000298 l d .gnu.hash 0000000000000000 .gnu.hash
00000000000002d8 l d .dynsym 0000000000000000 .dynsym
0000000000000458 l d .dynstr 0000000000000000 .dynstr
0000000000000532 l d .gnu.version 0000000000000000 .gnu.version
0000000000000558 l d .gnu.version_r 0000000000000000 .gnu.version_r
0000000000000578 l d .rela.dyn 0000000000000000 .rela.dyn
0000000000000650 l d .rela.plt 0000000000000000 .rela.plt
0000000000000698 l d .init 0000000000000000 .init
00000000000006b0 l d .plt 0000000000000000 .plt
00000000000006f0 l d .plt.got 0000000000000000 .plt.got
0000000000000700 l d .text 0000000000000000 .text
0000000000000984 l d .fini 0000000000000000 .fini
0000000000000990 l d .rodata 0000000000000000 .rodata
...
.dynsym
$ objdump -T -C main
main: file format elf64-x86-64
DYNAMIC SYMBOL TABLE:
0000000000000000 w D *UND* 0000000000000000 _ITM_deregisterTMCloneTable
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 puts
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 printf
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __libc_start_main
0000000000000000 w D *UND* 0000000000000000 __gmon_start__
0000000000000000 DF *UND* 0000000000000000 so_hello
0000000000000000 w D *UND* 0000000000000000 _ITM_registerTMCloneTable
0000000000000000 w DF *UND* 0000000000000000 GLIBC_2.2.5 __cxa_finalize
0000000000201011 g D .data 0000000000000000 Base _edata
0000000000201028 g D .bss 0000000000000000 Base _end
0000000000201018 g DO .bss 0000000000000008 g_so_long
0000000000201011 g D .bss 0000000000000000 Base __bss_start
0000000000000698 g DF .init 0000000000000000 Base _init
0000000000000984 g DF .fini 0000000000000000 Base _fini
00000000000008b9 g DF .text 0000000000000013 Base common_func
参考资料
ELF-symbol-resolution
https://gist.github.com/DhavalKapil/2243db1b732b211d0c16fd5d9140ab0b
PLT and GOT - the key to code sharing and dynamic libraries
https://www.technovelty.org/linux/plt-and-got-the-key-to-code-sharing-and-dynamic-libraries.html
Executable and Linkable Format 101 - Part 1 Sections and Segments
https://www.intezer.com/executable-linkable-format-101-part1-sections-segments/
Executable and Linkable Format 101. Part 2: Symbols
https://www.intezer.com/executable-linkable-format-101-part-2-symbols/
Executable and Linkable Format 101 Part 3: Relocations
https://www.intezer.com/executable-and-linkable-format-101-part-3-relocations/
Executable and Linkable Format 101 Part 4: Dynamic Linking
https://www.intezer.com/executable-linkable-format-101-part-4-dynamic-linking/
ELF Object File Format
http://www.360doc.com/content/15/0722/19/7377734_486702882.shtml
ELF Sections & Segments and Linux VMA Mappings
http://www.360doc.com/content/17/1204/11/7377734_709762695.shtml
最后修改于 2019-09-08