基础技术-ELF系列(1)-ELF文件基础

news2024/11/14 1:33:16

成就更好的自己

本篇是基础技术系列中ELF相关技术的首篇文章。

尽管网上有许多关于ELF相关内容的文章,但总体而言,要么是一些非常基础且重复性强的内容,要么直接深入探讨相对高深的主题,缺乏系统化分析和解释。

接下来,在本系列和专栏后续文章中,我们将以更加通俗的方式对ELF相关内容进行系统化分析。


目录

ELF的由来与作用

ELF文件的结构

ELF文件作执行用途

ELF文件作链接用途

ELF文件结构


ELF的由来与作用

ELF,叫做可执行可链接格式,是可执行文件、目标代码、共享库和核心转储的通用标准文件格式。

它首先在Unix操作系统版本的应用程序二进制接口(ABI)规范中发布,随后在工具接口标准中发布,它很快被不同的Unix系统供应商所接受。

从设计上来说,ELF格式灵活、可扩展且跨平台。它支持不同的字节序和地址大小,因此不会排除任何特定的CPU或指令集架构。这使得它能够被许多不同硬件平台上的许多不同操作系统采用。

请注意,ELF是一种约定的格式,是一种format!所谓的ELF文件是指遵循ELF的格式进行组建的文件,而不是某种特定的文件!

ELF在不同场景下有着不同的存在文件形式和作用,但这些文件都是遵循ELF的格式进行组建的:

  1. 可执行文件:编译链接出来的可执行文件,通过./就可以运行的那种。
  2. 目标代码:编译打包出来的.o.a文件,通过链接器链接用的。
  3. 共享库:编译出来的可重定位.so文件,也执行时进行LinkLoad用的。
  4. 核心转储:使用gdb调试或段错误时生成的core文件,保存了产生该文件时的某个进程的内存状态映像,用于debug或其他操作。

ELF文件的结构

大多数文章从这里开始就要千篇一律的讲解ELF结构了,这里我先按下不表。为了方便各位看官理解后续内容,我先讲点别的。

ELF之所以叫做可执行可链接格式,就是因为他最主要的作用就是两件事——1.执行2.链接。

ELF文件作执行用途

ELF文件作执行用途的情况一般有这么几个常见场景:

  • 不使用动态链接库编出的可执行文件,elf头如下:

  • 使用动态链接库编出的可执行文件,elf头如下:

  • 编出的动态链接库,elf头如下:

很明显,ELF文件用作执行用途的情况下,不管静态编译还是动态编译出来的,只要他作执行用途,那就会有入口点地址。众所周知,启动一个程序的主要步骤就是创建进程空间(进程控制块什么的)->分配内存页->将可执行文件和动态链接库(可能需要)中的内容(程序与数据)加载到内存->跳转到程序入口点->开始执行程序。

可执行文件和动态链接库都是能被执行的,因此上述过程中的加载待运行的程序与数据到内存这个步骤是ELF文件作为执行用途所必须的。

那程序加载器是如何知道可执行文件中的什么内容应该放到进程内存空间中的什么位置呢?因为用作执行用途的ELF文件中含有一个区域叫做程序头表(program headers tab),这个头表是虚拟出来的概念,是若干程序头(program headers)共同组成的一种表,他会告诉程序加载器将要执行的可执行文件中的各个数据块应该放在进程内存空间的什么位置;可执行文件中所谓的需要进行搬移的各个数据块,就是ELF文件中段(segment)这个概念。

好的,通俗的总结一下:

  1. ELF文件中的程序头和段是ELF文件用作执行用途的基本信息和概念;
  2. 程序加载器将ELF文件中的内容加载到内存的时候就是基于段进行加载的;
  3. 每个段都有一个对应的程序头,用于描述该段的信息,有多少程序头就有多少段;
  4. 可通过图片中Number of program headers 判断有多少程序头,通过Size of program headers判断每个程序头的长度;
  5. 这些程序头在ELF文件中的存放是连续的,存放的起始地址偏移就是图片中的程序头起点;

(上述部分内容涉及到程序加载和进程内存模型,属于计算机基础,不知道的建议买一本黑皮书看看,这里不展开)

ELF文件作链接用途

ELF文件作执行用途的情况一般有这么几个常见场景:

  • 编出的.o文件或静态链接库

很明显,与作执行用途的ELF文件相比,用作链接用途的ELF文件不能进行执行操作,也就没有入口点地址和程序头地址,也没有必要将文件中的内容加载到内存中;因此也就没有程序表头和段的概念。

用作链接用途的ELF文件通常使用在生成可执行程序的链接过程,这个过程简单来讲就是若干个可重定位可链接文件(.o或.a文件)进行相互链接并统一规划程序或数据的地址空间。

链接器如何在这些可链接文件中定位查找对应的符号并将指定的程序和数据进行地址重定位呢?因为用作链接用途的ELF文件中含有一个区域叫做节头表(section headers tab),这个头表是虚拟出来的概念,是若干节头(section headers)共同组成的一种表,他会告诉程序链接器需要的符号去哪里找,找到之后怎样如何进行地址重定位;可链接文件中在链接过程中具有相同意义和功能的数据放在了一起作为一个数据块,根据数据块的意义和功能不同得到ELF文件中节(section)这个概念。

好的,通俗的总结一下:

  1. ELF文件中的节头和节是ELF文件用作链接用途的基本信息和概念;
  2. 程序链接器将ELF文件中的内容进行链接时就是以节为单位进行符号查找等功能的;
  3. 每个节都有一个对应的节头,用于描述该节的信息,有多少节头就有多少节;
  4. 可通过图片中Number of section headers 判断有多少节头,通过Size of section headers判断每个节头的长度;
  5. 这些节头在ELF文件中的存放是连续的,存放的起始地址偏移就是图片中的start of section headers;

(上述部分内容涉及到编译过程,属于编译原理,不知道的建议买一本黑皮书看看,这里不展开)

ELF文件结构

现在看到的就是所有文章中基本都会用到的一张很经典的图,ELF文件结构,为了方便理解我做亿些小小的注释:

ELF文件主要结构如下:

  1. ELF头:描述整个ELF文件的头,包含了一些ELF文件的基础信息,就是上文中通过readelf –h看到的那些信息,其中前文那些图中的size of this header表示该文件头的长度。该部分在任何ELF文件中都是必须存在的。
  2. 若干程序头组成的程序头表:包含每个段的描述信息。该部分在没有执行功能的ELF文件中可以不存在。
  3. 若干节(若干段):ELF文件中的主要内容,由若干节的内容组成,在能够被执行的ELF文件中,也可以说是若干段的内容组成。同时站在两边的视角去看,如果段概念存在的情况下,每个段不重复的包含至少0个节。该部分为ELF文件的主体数据内容,必须存在。
  4. 若干节头组成的节头表:包含每个节的描述信息。该部分在一般ELF文件中都会存在,除非通过工具人为删除掉。

好的,通俗的总结一下:

一个未经任何人为修改阉割的ELF文件应至少有ELF头+若干节+若干节头组成;若ELF文件可被执行,则由ELF头+若干程序头+若干节+若干节头组成,其中将节(可以不是所有节)划入若干段的范围内。节是站在链接和文件基本构成的角度考虑的,段则是ELF文件具有被执行能力后,站在执行角度考虑的。

举个例子,下图是通过readelf –a得到的,可以看到该ELF文件有8个段,每个段是由那些节映射组成的。(.tbss等.xxx都是节的名称)。

一个ELF文件若人为阉割了节头,具有链接功能的ELF文件就会失去链接功能;具有执行功能的ELF文件就不可查看ELF文件内符号信息等大部分信息,但不会影响执行功能(因为程序头表还在,但动态链接库除外,动态链接库程序头和节头都需要)。

本篇结束,下一篇ELF文件进阶内容。

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

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

相关文章

Redis - 缓存场景

学习资料 学习的黑马程序员哔站项目黑马点评,用作记录和探究原理。 Redis缓存 缓存 :就是数据交换的缓冲区,是存储数据的临时地方,读写性能较高 缓存常见的场景: 数据库查询加速:通过将频繁查询的数据缓存起来&…

论文阅读--ActionCLIP

原来的动作识别问题在于标注太难太贵,将动作表示为短语的latent space太大 本文的贡献:(1)将CLIP的image encoder换成video encoder,方法与CLIP4Clip几乎一样 (2)CLIP的ground truth来自于文本…

使用pyqt绘制一个爱心!

使用pyqt绘制一个爱心! 介绍效果代码 介绍 使用pyqt绘制一个爱心! 效果 代码 import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget from PyQt5.QtGui import QPainter, QPen, QBrush, QColor from PyQt5.QtCore import Qt, Q…

【气象常用】间断时间序列图

效果图: 主要步骤: 1. 数据准备:随机数组 2. 图像绘制:绘制间断的时间序列 详细代码:着急的直接拖到最后有完整代码 步骤一:导入库包及图片存储路径并设置中文字体为宋体,西文为新罗马&…

没有telnet情况下判断主机端口是否开放的方法

没有telnet情况下判断主机端口是否开放的方法 方式一 ssh -v 101.132.64.231 -p 80显示结果 如果有显示 debug1: Connection established. 就说明端口是开放的 端口未开放的情况是显示 方式二 echo >/dev/tcp/101.132.64.231/3306效果如下 如果没有任何输出,…

Redis开发实战

单机部署安装 服务端下载,安装,启动去官网下载最新的版本:http://redis.io/download ,这里用的是3.0.2解压后,进入解压好的文件夹redis的安装非常简单,因为已经有现成的Makefile文件,所以直接先…

Photoshop插件(UXP)编写过程中,如何更新sp-checkbox的选中状态

✨问题说明 sp-checkbox是uxpSpectrum UXP Widgets下的一个小组件&#xff0c;内置样式大概是这样&#xff1a; 那么&#xff0c;如果用js动态的改变选中的状态&#xff0c;应该如何做呢&#xff1f; 如果直接是html来写&#xff1a; <sp-checkbox checked>Checked<…

freemarker ftl模板 格式、列表、图片

文章目录 前言一、freemarker实现内容替换二、ftl 模板1.word另存ftl2.编辑ftl文件2.1 了解一下常用的标记及其说明2.2 list处理2.3 红线2.4 图片 总结 前言 固定内容word生成&#xff1a;freemarker ftl模板 动态表格生成&#xff1a;https://blog.csdn.net/mr_wanter/articl…

基于MetaGPT构建LLM多智能体

前言 你好&#xff0c;我是GISer Liu&#xff0c;在上一篇文章中&#xff0c;我们用了两万多字详细拆解了单个Agent的组成&#xff0c;并通过Github Trending订阅智能体理解MetaGPT框架的订阅模块如何解决应用问题&#xff0c;但是对于复杂&#xff0c;并行的任务&#xff0c;单…

Java进阶学习笔记20——枚举

认识枚举&#xff1a; 枚举是一种特殊的类。 枚举类的格式&#xff1a; 说明&#xff1a; 第一行是罗列枚举的对象名称。只能写合法的标识符&#xff08;名称&#xff09;&#xff0c;多个名称用逗号隔开。 这些名称本质上都是常量&#xff0c;每个变量都会记住枚举类的一个…

HIVE3.1.3+ZK+Kerberos+Ranger2.4.0高可用集群部署

目录 一、集群规划 二、介质下载 三、基础环境准备 1、解压文件 2、配置环境变量 四、配置zookeeper 1、创建主体 2、修改zoo.cfg 3、新增jaas.conf 4、新增java.env 5、重启ZK 6、验证ZK 五、配置元数据库 六、安装HIVE 1、创建Hiver的kerberso主体 2…

U盘引导盘制作Rufus v4.5.2180

软件介绍 Rufus小巧实用开源免费的U盘系统启动盘制作工具和格式化U盘的小工具&#xff0c;它可以快速将ISO镜像文件制作成可引导的USB启动安装盘&#xff0c;支持Windows或Linux启动&#xff0c;堪称写入镜像速度最快的U盘系统制作工具。 软件截图 更新日志 github.com/pbat…

Digital Image Processing System(DIPS)

数字图像处理系统 Digital Image Processing System&#xff08;DIPS&#xff09; 早前版本&#xff1a; ​​​​​​​DIPS_YTPC OCR-CSDN博客

(南京观海微电子)——TFT LCM的作用

VCOM介绍 VCOM是液晶分子偏转的参考电压 &#xff0c;要求要稳定&#xff0c;对液晶显示有直接影响&#xff0c;具体的屏不同的话 也是不同的。 电压的具体值是根据输入的数据以及Vcom电压大小来确定的&#xff0c;用来显示各种不同灰阶&#xff0c;也就是实现彩色显示GAMMA简…

【知识蒸馏】deeplabv3 logit-based 知识蒸馏实战,对剪枝的模型进行蒸馏训练

本文将对【模型剪枝】基于DepGraph(依赖图)完成复杂模型的一键剪枝 文章中剪枝的模型进行蒸馏训练 一、逻辑蒸馏步骤 加载教师模型定义蒸馏loss计算蒸馏loss正常训练 二、代码 1、加载教师模型 教师模型使用未进行剪枝&#xff0c;并且已经训练好的原始模型。 teacher_mod…

Strategy设计模式

Strategy设计模式举例。 看图&#xff1a; 代码实现&#xff1a; #include <iostream>using namespace std;class FlyBehavior { public:virtual void fly() 0; };class QuackBehavior { public:virtual void quack() 0; };class FlyWithWings :public FlyBehavior …

新人攻略:避开这3大坑,让老员工主动带你飞!

进入职场的新人们&#xff0c;常常会感到困惑和挑战。他们可能会发现自己在与老员工的交流中遇到难题&#xff0c;甚至发现老员工并不愿意花费时间和精力去指导他们。这背后的原因是什么呢&#xff1f;又该如何改善这一现象呢&#xff1f;本文将从新员工的角度出发&#xff0c;…

无人机飞手:ASFC无人机和航模爱好者证书详解

ASFC无人机和航模爱好者证书是由中国航空运动协会&#xff08;ASFC&#xff09;颁发的一种无人机操作资格认证。这种证书在无人机和航模爱好者群体中享有广泛的认可度&#xff0c;并被视为操作无人机的一种重要资质。 ASFC证书的定义和用途十分明确。它是民航局颁发的民用无人驾…

C++中的继承详解

1.继承的概念及定义 1.1继承的概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许程序员在保 持原有类特性的基础上进行扩展&#xff0c;增加功能&#xff0c;这样产生新的类&#xff0c;称派生类。继承呈现了面向对象 程序设计的…

产品数据特性驱动设计

一、什么是数据特性 一个产品在宏观的视角下,是不同功能模块的有机组合;在微观的视角上,是千丝万缕的数据连接。 基于模块化设计思想,对产品进行业务化梳理,对业务进行模块化拆分出功能模块,功能模块就是产品的“逻辑”,而功能中的数据就是“特性”。 业务:比较固定…