Linux(类Unix)系统可执行程序ELF文件格式详解

news2024/12/23 13:16:18

我们知道一个Linux程序饱和程序代码和初始数据,那么这些程序二进制代码和初始数据在可执行程序文件中是怎么进行存储呢?这便是ELF文件格式要解决的问题。

一个Linux执行程序的内存结构粗略可划分为 代码段、数据段、BSS、堆、栈,如下图所示:

其中 BSS、堆、栈 中的内容是在程序运行过程中动态生成的, 而 代码段 和 数据段 内容是程序代码编译过程中生成的,因此,需要将 代码段 和 数据段 内容写入ELF文件,以便程序加载时可以重ELF文件读取数据,对内存空间的 代码段 和 数据段 进行初始化。对于 BSS、堆、栈 等,ELF文件中只需要保存内存使用规划数据即可,即内存起始地址、内存使用量等。上述只是一个简易粗略的内存使用情况划分,实际内存使用情况要比这个复杂,部分细小的数据段,比如 全局偏移表、过程链接表 等,我们暂时先放一放,后面会细说。

ELF除了要保存 代码段、数据段 的数据,以及各内存段的内存使用规划数据以外,还可能需要保存 程序版本信息、调试信息、动态链接符号表、动态链接的字符串 等等,而这些数据都被划分为一个个Section进行存储,然后在ELF文件中存放一个Section的索引表指向这些Seciton,以便进行定位。

ELF同时作为可执行程序的打包方式,为了简化可执行程序的加载流程,将程序加载过程中行为相近的Section规划到一段连续内存,并将其定义为一个Segment,以便整个Segment一起加载。同样,在ELF文件中存放一个Segment的索引表指向各个Segment,以便对它们进行定位。

综上所述,ELF文件的整体结构设计如下图所示:

1.ELF header,描述了程序版本等基本信息,以及Program header table 和 Section header table在ELF文件内的起始位置和大小;

2.Program header table,其实就是我们前面提到的Segment索引表;

3.Section header table,即前文提到的Setion索引表;

4..text\.rodata\.data,即前文提到的各个Setion,Section header table中记录了各个Setion的起始位置和大小,将一个或多个连续分布的Section划归为一个Segment,然后再Program header table中记录了各个Segment的起始位置和大小;

在了解了ELF文件整体结构设计后,我们来看看各个部分的数据结构是如何设计的。

ELF文件头(ELF header)

ELF头(ELF header)位于文件的开始位置。 它的主要目的是定位文件的其他部分。 文件头主要包含以下字段:

  • ELF文件鉴定 - 一个字节数组用来确认文件是否是一个ELF文件,并且提供普通文件特征的信息;
  • 文件类型 - 确定文件类型。 这个字段描述文件是一个重定位文件,或可执行文件,或...;
  • 目标结构;
  • ELF文件格式的版本;
  • 程序入口地址;
  • 程序头表的文件偏移;
  • 节头表的文件偏移;
  • ELF头(ELF header)的大小;
  • 程序头表的表项大小;
  • 其他字段...

你可以在内核源码种找到表示ELF64 header的结构体 elf64_hdr

typedef struct elf64_hdr {
    unsigned char    e_ident[EI_NIDENT];
    Elf64_Half e_type;
    Elf64_Half e_machine;
    Elf64_Word e_version;
    Elf64_Addr e_entry;
    Elf64_Off e_phoff;
    Elf64_Off e_shoff;
    Elf64_Word e_flags;
    Elf64_Half e_ehsize;
    Elf64_Half e_phentsize;
    Elf64_Half e_phnum;
    Elf64_Half e_shentsize;
    Elf64_Half e_shnum;
    Elf64_Half e_shstrndx;
} Elf64_Ehdr;

这个结构体定义在 elf.h

Section索引

所有的数据都存储在ELF文件的节(sections)中。 我们通过节头表中的索引(index)来确认节(sections)。 节头表表项包含以下字段:

  • 节的名字;
  • 节的类型;
  • 节的属性;
  • 内存地址;
  • 文件中的偏移;
  • 节的大小;
  • 到其他节的链接;
  • 各种各样的信息;
  • 地址对齐;
  • 这个表项的大小,如果有的话;

而且,在linux内核中结构体 elf64_shdr 如下所示:

typedef struct elf64_shdr {
    Elf64_Word sh_name;
    Elf64_Word sh_type;
    Elf64_Xword sh_flags;
    Elf64_Addr sh_addr;
    Elf64_Off sh_offset;
    Elf64_Xword sh_size;
    Elf64_Word sh_link;
    Elf64_Word sh_info;
    Elf64_Xword sh_addralign;
    Elf64_Xword sh_entsize;
} Elf64_Shdr;

 这个结构体定义在 elf.h

Segment索引

在可执行文件或者共享链接库中所有的节(sections)都被分为多个段(segments)。 程序头是一个结构的数组,每一个结构都表示一个段(segments)。 它的结构就像这样:

typedef struct elf64_phdr {
    Elf64_Word p_type;
    Elf64_Word p_flags;
    Elf64_Off p_offset;
    Elf64_Addr p_vaddr;
    Elf64_Addr p_paddr;
    Elf64_Xword p_filesz;
    Elf64_Xword p_memsz;
    Elf64_Xword p_align;
} Elf64_Phdr;

 这个结构体定义在 elf.h.

综上所述,我们对ELF文件进行解析的过程大致如下:

1.读取位于ELF文件起始位置的ELF header数据结构,从中获取程序信息,以及Section索引表 和 Segment索引表 的起始位置和大小;

2.对于可执行程序ELF文件,读取Segment索引表,挨个遍历elf64_phdr 对象,从中获取该Segment的信息,以及在ELF文件中的起始位置和大小,以及对应的内存位置和内存大小。根据Segment索引将数据从ELF文件载入指定的内存中,即可完成程序载入过程;

3.对于其他类型ELF文件,读取Section索引表,挨个遍历elf64_shdr 对象,从中获取该Section的信息,及其在ELF文件中的起始位置和大小,以及对应的内存位置。根据需要,按照Section索引读取Section内容做相应处理;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/508758.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Golang Gin 使用路由分类处理请求

在前面已经学习了gin框架如何处理请求,解析请求,返回数据。 在实际的项目当中,项目往往是以模块化来进行划分和开发的,所谓的模块化就是按照功能来划分,比如会有产品模块,会有用户模块,会将用户…

如何用ChatGPT协助搭建品牌视觉体系(VI)?

该场景对应的关键词库(18个): VI体系、品牌、目标市场、品牌DNA、人群特征、设计理念、标志设计、配色方案、字体选择、图形元素、价值观、形象、客户经理、需求、品牌定位、目标受众、主色调、辅助色 提问模板(2个)&…

并发编程09:ThreadLocal

文章目录 9.1 ThreadLocal简介9.1.1 面试题9.1.2 是什么?9.1.3 能干吗?9.1.4 API介绍9.1.5 永远的helloworld讲起9.1.6 总结 9.2 ThreadLocal源码分析9.2.1 源码解读9.2.2 Thread、ThreadLocal、ThreadLocalMap关系9.2.3 总结 9.3 ThreadLocal内存泄漏问…

基于html+css的图展示53

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

网络:TCP协议三次握手与四次挥手

一、理解TCP报文 TCP报文格式_TCP报文包含哪些内容: TCP报头中的源端口号和目的端口号同IP数据报中的源IP与目的IP唯一确定一条TCP连接。 TCP在发送数据前必须在彼此间建立连接,这里连接意思是:双方需要内保存对方信息(例如&…

leecode100_第7题接雨水_双指针

1 题目 2 分析 简述:两个指针分别指向两端,通过判断柱子的升降趋势来判断是否可以接水。 思路如下: 变量l_max,r_max分别记录当前时刻,左右遍历过的柱子的最高的高度,因为它奠定了水能积多高。分情况判断&#xff1a…

2437. 有效时间的数目

2437.有效时间的数目 给你一个长度为 5 的字符串 time ,表示一个电子时钟当前的时间,格式为 “hh:mm” 。最早 可能的时间是 “00:00” ,最晚 可能的时间是 “23:59” 。 在字符串 time 中,被字符 ? 替换掉的数位是 未知的 &am…

【Python三方库】使用tle2czml库将tle数据转为czml数据

原文作者:我辈李想 版权声明:文章原创,转载时请务必加上原文超链接、作者信息和本声明。 文章目录 一、安装tle2czml二、tle2czmlc创建czml三、tle转成czml1.字符串2.文件(网络文件) 四、czml参数修改 一、安装tle2czm…

【PWN · ret2syscall】[Wiki] ret2syscall

初次接触到ret2syscall,而ret2syscall的题目目前没有在各大平台的题目类型筛选中找到,所以还是刷一刷Wiki的经典题目吧!过程中遇到很多问题,包括偏移量的计算、ret2syscall原理的理解等等。尝试以萌新的视角,来分享、解…

网页版的 Redis 可视化工具来了,已开源

介绍 轻量级Redis缓存图形化管理工具,包含redis的5种数据类型的CRUD操作 软件架构 后端 springboot 2.2.2.RELEASE JDK 1.8 jedis 3.2.0 commons-lang3 3.5 hutool-core 5.1.1 fastjson 1.2.62 h2database 1.4.200 前端 vue-admin 1.0.5 axios 0.15.3 …

【Linux】exec函数族

目录 1、exec函数族的介绍2、exec相关函数 1、exec函数族的介绍 2、exec相关函数 #include <unistd.h> int execl(const char *pathname, const char *arg0, ... /* (char *)0 */ ); /* - path 需要指定的执行的文件的路径或者名称&#xff0c;相对路径or绝对路径- arg …

港联证券“中特估值”重塑可转债市场

中国特色估值体系&#xff08;简称“中特估值”&#xff09;正在重构以银行为核心的可转债市场。 尽管周二市场有所回落&#xff0c;但如火如荼的中特估值行情对可转债市场的影响巨大。受益于中信银行等强势上涨的表现&#xff0c;银行转债集体活跃。其中&#xff0c;齐鲁转债、…

美国访问学者J1签证申请攻略

J1签证主要签发给那些想来美国短期交流学习、学术访问、接受培训等&#xff0c;感受美国文化的人员。J1交流访问者签证包含多种类别&#xff0c;更特别的是&#xff0c;J1签证还允许持有签证人半工半读。这个非移民签证提供更多机会给外国人士来美国交流学习、传播文化并且获得…

RabbitMQ的SpringAMQP的各种模式的案例

目录 Basic Queue 简单队列模型 任务模型&#xff08;Work queues&#xff0c;也被称为&#xff08;Task queues&#xff09;&#xff09; 发布/订阅的广播&#xff08;Fanout&#xff09;模式 发布/订阅的定向&#xff08;Direct&#xff09;模式 发布订阅的通配&#xff08;…

HEVC学习之率失真优化

一、理论部分 率失真理论&#xff1a; 在给定失真的前提下如何最大限度第去除冗余。 在视频编码中的率失真理论为在给定码率RT的前提下最大限度的减少视频信息的失真&#xff0c;用数学描述为第一个式子所示&#xff0c;其中m*为取得最小码率时的编码方式&#xff0c;S为编码方…

使用MASA全家桶从零开始搭建IoT平台(三)管理设备的连接状态

文章目录 前言分析方案1:遗嘱消息演示遗嘱消息的使用实施流程 方案2:使用WebHook开启WebHook演示Webhook编写代码 前言 获取一个设备的在线和离线状态&#xff0c;是一个很关键的功能。我们对设备下发的控制指令&#xff0c;设备处于在线状态才能及时给我们反馈。这里的在线和…

SOLIDWORKS钣金折弯参数设置技巧

折弯系数早期是没有计算方法的&#xff0c;工厂都是根据实际经验确定下来的经验公式。 记录下来一个经验数据表或简单的经验公式。后来才出现的中性层概念&#xff0c;即既不伸长也不压缩的那一层为中性层。可以用来计算展开长度。SOLIDWORKS钣金折弯参数也是整合了所有的计算…

【C++】类和对象(中)---构造函数和析构函数

个人主页&#xff1a;平行线也会相交&#x1f4aa; 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【C之路】&#x1f48c; 本专栏旨在记录C的学习路线&#xff0c;望对大家有所帮助&#x1f647;‍ 希望我们一起努力、成长&…

【AI大模型】讯飞星火大模型能否超越chatgpt?我们拭目以待!

文章目录 前言你有使用过这种对话式AI吗&#xff1f;你对这类型AI有什么看法或感受&#xff1f;对于“讯飞星火大模型将超越chatgpt&#xff1f;”这个命题你的态度是什么&#xff1f;简要说说原因你认为这类型的人工智能对于现在的社会有哪些意义&#xff1f;对于这类型的人工…

GEE开发之MODIS_MCD12Q1数据分析和获取

GEE开发之MODIS_土地类型分类 0.MCD12Q1介绍1.遥感影像查看2.MCD12Q1分类介绍3.年数据下载&#xff08;LC_Type1/year/500m&#xff09; 前言&#xff1a;主要介绍MODIS的MCD12Q1产品&#xff0c;包括MCD12Q1产品的介绍、使用和下载。 0.MCD12Q1介绍 Terra 和 Aqua 组合的中分…