加载器、链接器、动态链接器概念
动态链接器:
共享库(shared library)是致力于解决静态库缺陷的一个现代创新产物。共享库是一个目标模块,在运行或加载时,可以加载到任意的内存地址,并和一个在内存中的程序链接起来。这个过程称为动态链接(dynamic linking),是由一个叫做动态链接器(dynamic linker)的程序来执行的。
链接器:
将多个可重定位目标文件生成可执行目标文件的过程称为链接,完成此功能的部件称为链接器(ld)
加载器
加载器(loader)将可执行目标文件中的代码和数据从磁盘复制到内存中,然后通过跳转到程序的第一条指令或入口点来运行该程序。这个将程序复制到内存并运行的过程叫做加载。

修改一个二进制文件的动态链接器方法:
patchelf --set-interpreter /path/to/new/dynamic/linker your_program
readelf -h a.out输出ELF header的信息:
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: 0x41cc40
Start of program headers: 64 (bytes into file)
Start of section headers: 82900248 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
# program header的大小是56字节
Size of program headers: 56 (bytes)
# 9个program header
Number of program headers: 9
# section header的大小是64字节
Size of section headers: 64 (bytes)
# 42个section header
Number of section headers: 42
Section header string table index: 39
readelf -W -S a.out输出section header的信息:
There are 42 section headers, starting at offset 0x4f0f518:
Section Headers:
[Nr] Name Type Address Off Size ES Flg Lk Inf Al
[ 0] NULL 0000000000000000 000000 000000 00 0 0 0
[ 1] .interp PROGBITS 0000000000400238 000238 00001c 00 A 0 0 1
[ 2] .note.ABI-tag NOTE 0000000000400254 000254 000020 00 A 0 0 4
[ 3] .note.gnu.build-id NOTE 0000000000400274 000274 000024 00 A 0 0 4
[ 4] .gnu.hash GNU_HASH 0000000000400298 000298 001574 00 A 5 0 8
[ 5] .dynsym DYNSYM 0000000000401810 001810 007080 18 A 6 1 8
[ 6] .dynstr STRTAB 0000000000408890 008890 00ab28 00 A 0 0 1
[ 7] .gnu.version VERSYM 00000000004133b8 0133b8 000960 02 A 5 0 2
[ 8] .gnu.version_r VERNEED 0000000000413d18 013d18 0001f0 00 A 6 11 8
[ 9] .rela.dyn RELA 0000000000413f08 013f08 004350 18 A 5 0 8
[10] .rela.plt RELA 0000000000418258 018258 002c40 18 A 5 12 8
[11] .init PROGBITS 000000000041ae98 01ae98 000018 00 AX 0 0 4
[12] .plt PROGBITS 000000000041aeb0 01aeb0 001d90 10 AX 0 0 4
[13] .text PROGBITS 000000000041cc40 01cc40 6f6418 00 AX 0 0 16
[14] .fini PROGBITS 0000000000b13058 713058 00000e 00 AX 0 0 4
[15] .rodata PROGBITS 0000000000b13080 713080 3d2a47 00 A 0 0 32
[16] .eh_frame_hdr PROGBITS 0000000000ee5ac8 ae5ac8 02a6ac 00 A 0 0 4
[17] .eh_frame PROGBITS 0000000000f10178 b10178 0c054c 00 A 0 0 8
[18] .gcc_except_table PROGBITS 0000000000fd06c4 bd06c4 040b90 00 A 0 0 4
[19] .tdata PROGBITS 0000000001211260 c11260 004020 00 WAT 0 0 16
[20] .tbss NOBITS 0000000001215280 c15280 3ed340 00 WAT 0 0 16
[21] .ctors PROGBITS 0000000001215280 c15280 000878 00 WA 0 0 8
[22] .dtors PROGBITS 0000000001215af8 c15af8 000018 00 WA 0 0 8
[23] .jcr PROGBITS 0000000001215b10 c15b10 000008 00 WA 0 0 8
[24] .data.rel.ro PROGBITS 0000000001215b20 c15b20 03fbc8 00 WA 0 0 32
[25] .dynamic DYNAMIC 00000000012556e8 c556e8 000230 10 WA 6 0 8
[26] .got PROGBITS 0000000001255918 c55918 001618 08 WA 0 0 8
[27] .got.plt PROGBITS 0000000001256f30 c56f30 000ed8 08 WA 0 0 8
[28] .data PROGBITS 0000000001257e20 c57e20 012090 00 WA 0 0 32
[29] .bss NOBITS 000000000126a000 c69eb0 d1f378 00 WA 0 0 512
[30] .comment PROGBITS 0000000000000000 c69eb0 00002d 01 MS 0 0 1
[31] .debug_aranges PROGBITS 0000000000000000 c69edd 10b000 00 0 0 1
[32] .debug_pubnames PROGBITS 0000000000000000 d74edd 5c5559 00 0 0 1
[33] .debug_info PROGBITS 0000000000000000 133a436 3196bee 00 0 0 1
[34] .debug_abbrev PROGBITS 0000000000000000 44d1024 0f823a 00 0 0 1
[35] .debug_line PROGBITS 0000000000000000 45c925e 34c2d0 00 0 0 1
[36] .debug_str PROGBITS 0000000000000000 491552e 3ccbc5 01 MS 0 0 1
[37] .debug_pubtypes PROGBITS 0000000000000000 4ce20f3 0ecf79 00 0 0 1
[38] .debug_ranges PROGBITS 0000000000000000 4dcf06c 140310 00 0 0 1
[39] .shstrtab STRTAB 0000000000000000 4f0f37c 000198 00 0 0 1
[40] .symtab SYMTAB 0000000000000000 4f0ff98 7c0938 18 41 312397 8
[41] .strtab STRTAB 0000000000000000 56d08d0 3433eb 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
# 后面缩写的ES Flg Lk Inf Al每一列的含义:
# ES == sh_entsize, Lk == sh_link, Inf == sh_info and Al == sh_addalign.
readelf -W -l a.out输出program header的信息:
Elf file type is EXEC (Executable file)
Entry point 0x41cc40
There are 9 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000040 0x0000000000400040 0x0000000000400040 0x0001f8 0x0001f8 R E 0x8
INTERP 0x000238 0x0000000000400238 0x0000000000400238 0x00001c 0x00001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x000000 0x0000000000400000 0x0000000000400000 0xc11254 0xc11254 R E 0x200000
LOAD 0xc11260 0x0000000001211260 0x0000000001211260 0x058c50 0xd78118 RW 0x200000
DYNAMIC 0xc556e8 0x00000000012556e8 0x00000000012556e8 0x000230 0x000230 RW 0x8
NOTE 0x000254 0x0000000000400254 0x0000000000400254 0x000044 0x000044 R 0x4
TLS 0xc11260 0x0000000001211260 0x0000000001211260 0x004020 0x3f1360 R 0x10
GNU_EH_FRAME 0xae5ac8 0x0000000000ee5ac8 0x0000000000ee5ac8 0x02a6ac 0x02a6ac R 0x4
GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x8
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 .text .fini .rodata .eh_frame_hdr .eh_frame .gcc_except_table
03 .tdata .ctors .dtors .jcr .data.rel.ro .dynamic .got .got.plt .data .bss
04 .dynamic
05 .note.ABI-tag .note.gnu.build-id
06 .tdata .tbss
07 .eh_frame_hdr
08
查看具体哪个section内容的16进制显示以及它的ascii字符串显示:
# 查看.interp的内容
readelf -W -x .strtab a.out
Hex dump of section '.interp':
0x00400238 2f6c6962 36342f6c 642d6c69 6e75782d /lib64/ld-linux-
0x00400248 7838362d 36342e73 6f2e3200 x86-64.so.2.
参考链接:
- 深入浅出ELF https://zhuanlan.zhihu.com/p/254882216
- 程序的本质之二ELF文件的文件头、section header和program header https://blog.csdn.net/npy_lp/article/details/102604380
- readelf -l输出section header每一列的含义 https://stackoverflow.com/a/15870451/2873403
浙公网安备 33010602011771号