这里我们来探讨一下 elf 文件的执行流程
当然 这也是我很久以前 就想了解的东西了
不过 苦于 缺少各种调试环境, 呵呵 所以 一直搁置于此
调试环境 至关重要
这里主要是走一下 elf 的执行流程, fork, exec, libc_start_main, main
root@ubuntu:~/ClionWorkStations/HelloWorld# cat Test01Sum.c
#include "stdio.h"int main(int argc, char** argv) {int x = 2;
int y = 3;
int z = x + y;printf(" x + y = %d\n ", z);}
readelf 查看 elf 的文件信息
root@ubuntu:~/ClionWorkStations/HelloWorld# readelf -a Test01Sum
ELF Header:Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64Data: 2's complement, little endianVersion: 1 (current)OS/ABI: UNIX - System VABI Version: 0Type: EXEC (Executable file)Machine: Advanced Micro Devices X86-64Version: 0x1Entry point address: 0x400480Start of program headers: 64 (bytes into file)Start of section headers: 8496 (bytes into file)Flags: 0x0Size of this header: 64 (bytes)Size of program headers: 56 (bytes)Number of program headers: 9Size of section headers: 64 (bytes)Number of section headers: 38Section header string table index: 35Section Headers:[Nr] Name Type Address OffsetSize EntSize Flags Link Info Align[ 0] NULL 0000000000000000 000000000000000000000000 0000000000000000 0 0 0[ 1] .interp PROGBITS 0000000000400238 000002380000000000000040 0000000000000000 A 0 0 1[ 2] .note.ABI-tag NOTE 0000000000400278 000002780000000000000020 0000000000000000 A 0 0 4[ 3] .note.gnu.build-i NOTE 0000000000400298 000002980000000000000024 0000000000000000 A 0 0 4[ 4] .gnu.hash GNU_HASH 00000000004002c0 000002c0000000000000001c 0000000000000000 A 5 0 8[ 5] .dynsym DYNSYM 00000000004002e0 000002e00000000000000060 0000000000000018 A 6 1 8[ 6] .dynstr STRTAB 0000000000400340 00000340000000000000006a 0000000000000000 A 0 0 1[ 7] .gnu.version VERSYM 00000000004003aa 000003aa0000000000000008 0000000000000002 A 5 0 2[ 8] .gnu.version_r VERNEED 00000000004003b8 000003b80000000000000020 0000000000000000 A 6 1 8[ 9] .rela.dyn RELA 00000000004003d8 000003d80000000000000018 0000000000000018 A 5 0 8[10] .rela.plt RELA 00000000004003f0 000003f00000000000000030 0000000000000018 AI 5 24 8[11] .init PROGBITS 0000000000400420 00000420000000000000001a 0000000000000000 AX 0 0 4[12] .plt PROGBITS 0000000000400440 000004400000000000000030 0000000000000010 AX 0 0 16[13] .plt.got PROGBITS 0000000000400470 000004700000000000000008 0000000000000000 AX 0 0 8[14] .text PROGBITS 0000000000400480 0000048000000000000001b2 0000000000000000 AX 0 0 16[15] .fini PROGBITS 0000000000400634 000006340000000000000009 0000000000000000 AX 0 0 4[16] .rodata PROGBITS 0000000000400640 000006400000000000000012 0000000000000000 A 0 0 4[17] .eh_frame_hdr PROGBITS 0000000000400654 000006540000000000000034 0000000000000000 A 0 0 4[18] .eh_frame PROGBITS 0000000000400688 0000068800000000000000f4 0000000000000000 A 0 0 8[19] .init_array INIT_ARRAY 0000000000600e00 00000e000000000000000008 0000000000000000 WA 0 0 8[20] .fini_array FINI_ARRAY 0000000000600e08 00000e080000000000000008 0000000000000000 WA 0 0 8[21] .jcr PROGBITS 0000000000600e10 00000e100000000000000008 0000000000000000 WA 0 0 8[22] .dynamic DYNAMIC 0000000000600e18 00000e1800000000000001e0 0000000000000010 WA 6 0 8[23] .got PROGBITS 0000000000600ff8 00000ff80000000000000008 0000000000000008 WA 0 0 8[24] .got.plt PROGBITS 0000000000601000 000010000000000000000028 0000000000000008 WA 0 0 8[25] .data PROGBITS 0000000000601028 000010280000000000000010 0000000000000000 WA 0 0 8[26] .bss NOBITS 0000000000601038 000010380000000000000008 0000000000000000 WA 0 0 1[27] .comment PROGBITS 0000000000000000 000010380000000000000035 0000000000000001 MS 0 0 1[28] .debug_aranges PROGBITS 0000000000000000 0000106d0000000000000030 0000000000000000 0 0 1[29] .debug_info PROGBITS 0000000000000000 0000109d000000000000016a 0000000000000000 0 0 1[30] .debug_abbrev PROGBITS 0000000000000000 00001207000000000000010d 0000000000000000 0 0 1[31] .debug_line PROGBITS 0000000000000000 000013140000000000000097 0000000000000000 0 0 1[32] .debug_str PROGBITS 0000000000000000 000013ab000000000000016d 0000000000000001 MS 0 0 1[33] .debug_loc PROGBITS 0000000000000000 00001518000000000000011b 0000000000000000 0 0 1[34] .debug_ranges PROGBITS 0000000000000000 000016330000000000000060 0000000000000000 0 0 1[35] .shstrtab STRTAB 0000000000000000 00001fc50000000000000165 0000000000000000 0 0 1[36] .symtab SYMTAB 0000000000000000 000016980000000000000708 0000000000000018 37 55 8[37] .strtab STRTAB 0000000000000000 00001da00000000000000225 0000000000000000 0 0 1
Key to Flags:W (write), A (alloc), X (execute), M (merge), S (strings), l (large)I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)O (extra OS processing required) o (OS specific), p (processor specific)There are no section groups in this file.Program Headers:Type Offset VirtAddr PhysAddrFileSiz MemSiz Flags AlignPHDR 0x0000000000000040 0x0000000000400040 0x00000000004000400x00000000000001f8 0x00000000000001f8 R E 8INTERP 0x0000000000000238 0x0000000000400238 0x00000000004002380x0000000000000040 0x0000000000000040 R 1[Requesting program interpreter: /root/Desktop/linux/glibc-2.23/install/lib/ld-linux-x86-64.so.2]LOAD 0x0000000000000000 0x0000000000400000 0x00000000004000000x000000000000077c 0x000000000000077c R E 200000LOAD 0x0000000000000e00 0x0000000000600e00 0x0000000000600e000x0000000000000238 0x0000000000000240 RW 200000DYNAMIC 0x0000000000000e18 0x0000000000600e18 0x0000000000600e180x00000000000001e0 0x00000000000001e0 RW 8NOTE 0x0000000000000278 0x0000000000400278 0x00000000004002780x0000000000000044 0x0000000000000044 R 4GNU_EH_FRAME 0x0000000000000654 0x0000000000400654 0x00000000004006540x0000000000000034 0x0000000000000034 R 4GNU_STACK 0x0000000000000000 0x0000000000000000 0x00000000000000000x0000000000000000 0x0000000000000000 RW 10GNU_RELRO 0x0000000000000e00 0x0000000000600e00 0x0000000000600e000x0000000000000200 0x0000000000000200 R 1Section 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 .jcr .dynamic .got .got.plt .data .bss 04 .dynamic 05 .note.ABI-tag .note.gnu.build-id 06 .eh_frame_hdr 07 08 .init_array .fini_array .jcr .dynamic .got Dynamic section at offset 0xe18 contains 25 entries:Tag Type Name/Value0x0000000000000001 (NEEDED) Shared library: [libc.so.6]0x000000000000000f (RPATH) Library rpath: [/root/Desktop/linux/glibc-2.23/install/lib]0x000000000000000c (INIT) 0x4004200x000000000000000d (FINI) 0x4006340x0000000000000019 (INIT_ARRAY) 0x600e000x000000000000001b (INIT_ARRAYSZ) 8 (bytes)0x000000000000001a (FINI_ARRAY) 0x600e080x000000000000001c (FINI_ARRAYSZ) 8 (bytes)0x000000006ffffef5 (GNU_HASH) 0x4002c00x0000000000000005 (STRTAB) 0x4003400x0000000000000006 (SYMTAB) 0x4002e00x000000000000000a (STRSZ) 106 (bytes)0x000000000000000b (SYMENT) 24 (bytes)0x0000000000000015 (DEBUG) 0x00x0000000000000003 (PLTGOT) 0x6010000x0000000000000002 (PLTRELSZ) 48 (bytes)0x0000000000000014 (PLTREL) RELA0x0000000000000017 (JMPREL) 0x4003f00x0000000000000007 (RELA) 0x4003d80x0000000000000008 (RELASZ) 24 (bytes)0x0000000000000009 (RELAENT) 24 (bytes)0x000000006ffffffe (VERNEED) 0x4003b80x000000006fffffff (VERNEEDNUM) 10x000000006ffffff0 (VERSYM) 0x4003aa0x0000000000000000 (NULL) 0x0Relocation section '.rela.dyn' at offset 0x3d8 contains 1 entries:Offset Info Type Sym. Value Sym. Name + Addend
000000600ff8 000300000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0Relocation section '.rela.plt' at offset 0x3f0 contains 2 entries:Offset Info Type Sym. Value Sym. Name + Addend
000000601018 000100000007 R_X86_64_JUMP_SLO 0000000000000000 printf@GLIBC_2.2.5 + 0
000000601020 000200000007 R_X86_64_JUMP_SLO 0000000000000000 __libc_start_main@GLIBC_2.2.5 + 0The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.Symbol table '.dynsym' contains 4 entries:Num: Value Size Type Bind Vis Ndx Name0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (2)2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)3: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__Symbol table '.symtab' contains 75 entries:Num: Value Size Type Bind Vis Ndx Name0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000400238 0 SECTION LOCAL DEFAULT 1 2: 0000000000400278 0 SECTION LOCAL DEFAULT 2 3: 0000000000400298 0 SECTION LOCAL DEFAULT 3 4: 00000000004002c0 0 SECTION LOCAL DEFAULT 4 5: 00000000004002e0 0 SECTION LOCAL DEFAULT 5 6: 0000000000400340 0 SECTION LOCAL DEFAULT 6 7: 00000000004003aa 0 SECTION LOCAL DEFAULT 7 8: 00000000004003b8 0 SECTION LOCAL DEFAULT 8 9: 00000000004003d8 0 SECTION LOCAL DEFAULT 9 10: 00000000004003f0 0 SECTION LOCAL DEFAULT 10 11: 0000000000400420 0 SECTION LOCAL DEFAULT 11 12: 0000000000400440 0 SECTION LOCAL DEFAULT 12 13: 0000000000400470 0 SECTION LOCAL DEFAULT 13 14: 0000000000400480 0 SECTION LOCAL DEFAULT 14 15: 0000000000400634 0 SECTION LOCAL DEFAULT 15 16: 0000000000400640 0 SECTION LOCAL DEFAULT 16 17: 0000000000400654 0 SECTION LOCAL DEFAULT 17 18: 0000000000400688 0 SECTION LOCAL DEFAULT 18 19: 0000000000600e00 0 SECTION LOCAL DEFAULT 19 20: 0000000000600e08 0 SECTION LOCAL DEFAULT 20 21: 0000000000600e10 0 SECTION LOCAL DEFAULT 21 22: 0000000000600e18 0 SECTION LOCAL DEFAULT 22 23: 0000000000600ff8 0 SECTION LOCAL DEFAULT 23 24: 0000000000601000 0 SECTION LOCAL DEFAULT 24 25: 0000000000601028 0 SECTION LOCAL DEFAULT 25 26: 0000000000601038 0 SECTION LOCAL DEFAULT 26 27: 0000000000000000 0 SECTION LOCAL DEFAULT 27 28: 0000000000000000 0 SECTION LOCAL DEFAULT 28 29: 0000000000000000 0 SECTION LOCAL DEFAULT 29 30: 0000000000000000 0 SECTION LOCAL DEFAULT 30 31: 0000000000000000 0 SECTION LOCAL DEFAULT 31 32: 0000000000000000 0 SECTION LOCAL DEFAULT 32 33: 0000000000000000 0 SECTION LOCAL DEFAULT 33 34: 0000000000000000 0 SECTION LOCAL DEFAULT 34 35: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c36: 0000000000600e10 0 OBJECT LOCAL DEFAULT 21 __JCR_LIST__37: 00000000004004b0 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones38: 00000000004004f0 0 FUNC LOCAL DEFAULT 14 register_tm_clones39: 0000000000400530 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux40: 0000000000601038 1 OBJECT LOCAL DEFAULT 26 completed.759441: 0000000000600e08 0 OBJECT LOCAL DEFAULT 20 __do_global_dtors_aux_fin42: 0000000000400550 0 FUNC LOCAL DEFAULT 14 frame_dummy43: 0000000000600e00 0 OBJECT LOCAL DEFAULT 19 __frame_dummy_init_array_44: 0000000000000000 0 FILE LOCAL DEFAULT ABS elf-init.c45: 0000000000000000 0 FILE LOCAL DEFAULT ABS Test01Sum.c46: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c47: 0000000000400778 0 OBJECT LOCAL DEFAULT 18 __FRAME_END__48: 0000000000600e10 0 OBJECT LOCAL DEFAULT 21 __JCR_END__49: 0000000000000000 0 FILE LOCAL DEFAULT ABS 50: 0000000000600e08 0 NOTYPE LOCAL DEFAULT 19 __init_array_end51: 0000000000600e18 0 OBJECT LOCAL DEFAULT 22 _DYNAMIC52: 0000000000600e00 0 NOTYPE LOCAL DEFAULT 19 __init_array_start53: 0000000000400654 0 NOTYPE LOCAL DEFAULT 17 __GNU_EH_FRAME_HDR54: 0000000000601000 0 OBJECT LOCAL DEFAULT 24 _GLOBAL_OFFSET_TABLE_55: 0000000000400630 2 FUNC GLOBAL DEFAULT 14 __libc_csu_fini56: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTab57: 0000000000601028 0 NOTYPE WEAK DEFAULT 25 data_start58: 0000000000601038 0 NOTYPE GLOBAL DEFAULT 25 _edata59: 0000000000400634 0 FUNC GLOBAL DEFAULT 15 _fini60: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@@GLIBC_2.2.561: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@@GLIBC_62: 0000000000601028 0 NOTYPE GLOBAL DEFAULT 25 __data_start63: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__64: 0000000000601030 0 OBJECT GLOBAL HIDDEN 25 __dso_handle65: 0000000000400640 4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used66: 00000000004005c0 101 FUNC GLOBAL DEFAULT 14 __libc_csu_init67: 0000000000601040 0 NOTYPE GLOBAL DEFAULT 26 _end68: 0000000000400480 42 FUNC GLOBAL DEFAULT 14 _start69: 0000000000601038 0 NOTYPE GLOBAL DEFAULT 26 __bss_start70: 0000000000400576 67 FUNC GLOBAL DEFAULT 14 main71: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses72: 0000000000601038 0 OBJECT GLOBAL HIDDEN 25 __TMC_END__73: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable74: 0000000000400420 0 FUNC GLOBAL DEFAULT 11 _initVersion symbols section '.gnu.version' contains 4 entries:Addr: 00000000004003aa Offset: 0x0003aa Link: 5 (.dynsym)000: 0 (*local*) 2 (GLIBC_2.2.5) 2 (GLIBC_2.2.5) 0 (*local*) Version needs section '.gnu.version_r' contains 1 entries:Addr: 0x00000000004003b8 Offset: 0x0003b8 Link: 6 (.dynstr)000000: Version: 1 File: libc.so.6 Cnt: 10x0010: Name: GLIBC_2.2.5 Flags: none Version: 2Displaying notes found at file offset 0x00000278 with length 0x00000020:Owner Data size DescriptionGNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag)OS: Linux, ABI: 2.6.32Displaying notes found at file offset 0x00000298 with length 0x00000024:Owner Data size DescriptionGNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)Build ID: 40a7a5576d0c3e9280e8fd00051f817befc922c6
在这一个层面主要是包含两个部分, fork + exec
1. fork 当前进程
2. 然后更新 子进程的执行文件为待执行 elf
3. 然后 之后执行 elf 的相关业务
执行 "./Test01Sum"
首先是 fork, 可以看到执行 Test01Sum 的进程是 275
然后是 exec 更新子进程待执行的 elf
这里可以看到待执行文件为 "./Test01Sum"
然后 核心业务处理是在 binfmt_elf. load_elf_binary
主要包含了读取 elfHeader, programHeaders, 加载 interpreter, 加载 interpreter 的 elfHeader, programHeaders, mmap LOAD 的 segment, 更新 bss, data, code 的相关偏移, 初始化执行程序的栈帧, 更新子进程的入口, 子进程开始处理业务
这里的 elf_entry, 如果是静态链接, 则为 elf 的 entry_point, 否则为 interpreter 的 entry_point
我们看一下 elf 的 entry_point 的代码
主要是构造了 libc_start_main 的参数, 传入了诸如 main, init, fini, argc, argv 等等相关参数
main, 就是用户代码的 main 编译好了之后生成的代码
在 libc_start_main 中调用了 main
main 的代码地址为 0x400576, 对应于 elf 中的 main
然后 这时候我们的 main 才开始跑起来
然后就是 用户代码中的 main 的代码的执行了
上面的这部分代码段时属于 LOAD 的 segment 的一部分, 被完全 mmap 进来, 因此是一样的
当然 以上仅仅是一个 大体的脉络
实际上有很多有意思的细节, 在其中
完