14 elf 文件执行的流程
创始人
2025-05-30 19:20:05

前言

这里我们来探讨一下 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

linux 层面的 elf 的执行

在这一个层面主要是包含两个部分, 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 

glibc 的 libc_start_main 

我们看一下 elf 的 entry_point 的代码 

主要是构造了 libc_start_main 的参数, 传入了诸如 main, init, fini, argc, argv 等等相关参数 

main, 就是用户代码的 main 编译好了之后生成的代码 

在 libc_start_main 中调用了 main 

main 的代码地址为 0x400576, 对应于 elf 中的 main 

然后 这时候我们的 main 才开始跑起来 

main 的执行 

然后就是 用户代码中的 main 的代码的执行了 

上面的这部分代码段时属于 LOAD 的 segment 的一部分, 被完全 mmap 进来, 因此是一样的 

当然 以上仅仅是一个 大体的脉络 

实际上有很多有意思的细节, 在其中 

相关内容

热门资讯

golang实现守护进程(2) 前言golang实现守护进程,包含功能:1. 守护进程只创建一次2. 平...
url 格式详解 统一资源定位系统(uniform resource locator; url ...
elasticsearch7.... elasticsearch版本:7.17.3 目标:实现对类型为text...
SpringBoot 加载系统... 开发环境: IDEA 2022.1.4+ MyBatis         代码参考:spri...
交换机概念和知识和命令 目录 一、华为交换机基础学习的一些重要概念和知识 二、交换机常用命令大全 三、不常用的交换机命令 ...
什么是 JavaScript ... 本文首发自「慕课网」,想了解更多IT干货内容,程序员圈内热闻࿰...
【C++】C++11——lam... 文章目录一、Lambda表达式引入二、Lambda表达式语法三、Lambda表达式交换两个值四、La...
Java分布式事务(十) 文章目录🔥分布式架构的理论知识_BASE理论🔥分布式事务解决方案_最...
vmware中centos7实... 前言 在开发收银系统SAAS版本时,采用的是centos服务器,经常需要...
计算机图形学 | 可编程渲染管... 计算机图形学 | 可编程渲染管线计算机图形学 | 可编程渲染管线3.1 从固定到可编程图形编程的发展...
linux下安装两个或多个to... 安装jdk,tomcat编辑环境变量profilevi /etc/profile加入以...
selenium的显示等待、隐... 关于selenium有三种等待方式,分别为显示等待、隐式等待、强制等待 1、强制等待 ...
测牛学堂:软件测试接口自动化之... requests库 用postman进行接口测试有一定的限制,我们测试更应该掌握的是用...
day36_jdbc 今日内容 上课同步视频:CuteN饕餮的个人空间_哔哩哔哩_bilibili 同步笔记沐沐霸的博客...
【java基础】Stream流... 文章目录基本介绍流的创建流的各种常见操作forEach方法filter方法map方法peek方法fl...
幂等性通用组件 一、什么是幂等性幂等是一个数学与计算机学概念,在数学中某一元运算为幂等时,...
Nacos服务注册 又是美好的一天呀~ 个人博客地址: huanghong.top 本文预估阅读时长为3...
令人惊艳的ChatGPT项目,... 自从 ChatGPT、Stable Diffusion 发布以来,各种相关开源项目百花...
舆情监测系统有哪些优势,TOO... 舆情监测系统是一种基于大数据技术的舆情分析工具,可以帮助企业、政府等机构实时监控公众对...
【Linux】基础IO流(上) 文章目录1. 预备知识2. 回忆C接口fopenfputsfprintfsnprintf追加方式——...
设计模式(二十七)----行为... 1 概述 如上图,设计一个软件用来进行加减计算。我们第一想法就是使用工具类ÿ...
精心整理前端主流框架学习路径 版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog....
typescript声明 前言 “d.ts”文件用于为 TypeScript 提供有关用 JavaScript 编写的 API...
HashMap源码分析 Java源码系列:下方连接 http://t.csdn.cn/Nwzed 文章目录...
一、基础算法3:二分 模板题+... 文章目录算法模板整数二分算法模板浮点数二分算法模板模板题数的范围原题链接题目题解数的三次方根原题链接...
Essential C++复习... 好久没写代码了,很多东西都忘记了。复盘一下C++编写基础头文件 与 输...
三十五、DRF中的过滤、Dja... 一、DRF中的过滤 REST framework 的通用列表视图的默认行为是返回模型管理器的整个查询...
基于RZ/G2UL Corte... 以太网接口是一种广泛应用的网络接口,它可以在不同的场合实现不同的功能。例如࿰...
nginx-会话保持-3 基于LNMP在负载均衡集群上部署wordpress(低配版) 在讲解会话...
【BBuf的CUDA笔记】九,... 0x0. 背景 随着年纪越来越大,读代码越来越困难,如果你发现看不懂同事...