ELF文件格式解析

 ELF(Executable and Linkable Format) 即可执行可链接文件格式,是目前操作系统上最常见的可执行文件格式。不同系统的目标文件不一样,Windows是PE(Portable Executable),linux是ELF(Executable Linkable Format),它们都是COFF(Common file format)格式的变种。

1、基本格式

      ELF格式的目标文件和可执行文件在结构上没有本质差异,ELF不仅仅描述目标文件,也用于描述可执行文件,Windows下的dll和.lib, Linux下的.so和.a文件都是按照类ELF格式存储,下图描述了ELF链接视图(.o文件、.so文件)和执行视图,链接视图描述了各个段(section)的组成,如.text、.data、bss段。执行视图由segment组成,segment用于表示一个一定长度的区域,按照只读/可读写划分,不区分数据的属性,如代码段、数据段。

      目标文件是未经过链接的,里面的符号和地址没有调整导致无法运行。例如直接运行目标文件,系统提示无法执行该二进制文件。

$ . hello.o
bash: .: hello.o: cannot execute binary file
$ file hello.o
hello.o: Intel amd64 COFF object file, no line number info, not stripped, 7 sections, symbol offset=0x2a0, 22 symbols, 1st section name ".text"

     ELF文件格式在字节对齐和元素解析时,与系统架构、字长有密切关系,ELF 文件由ELF header和各种段组成,其结构图如下所示。详细文档可以查阅Executable and Linkable Format (ELF) - eLinux.org。

2、ELF文件头

     ELF 文件的最前面是文件头,描述了ELF文件的基本属性,比如ELF文件版本、目标机器型号、程序入口地址。

     详细的描述可以参考:ELF Header

复制代码

#define EI_NIDENT 16typedef struct {unsigned char   e_ident[EI_NIDENT];Elf32_Half      e_type;Elf32_Half      e_machine;Elf32_Word      e_version;Elf32_Addr      e_entry;Elf32_Off       e_phoff;Elf32_Off       e_shoff;Elf32_Word      e_flags;Elf32_Half      e_ehsize;Elf32_Half      e_phentsize;Elf32_Half      e_phnum;Elf32_Half      e_shentsize;Elf32_Half      e_shnum;Elf32_Half      e_shstrndx;
} Elf32_Ehdr;$ readelf -h /bin/ls 
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:                              DYN (Position-Independent Executable file)Machine:                           Advanced Micro Devices X86-64Version:                           0x1Entry point address:               0x6180Start of program headers:          64 (bytes into file)Start of section headers:          145256 (bytes into file)Flags:                             0x0Size of this header:               64 (bytes)Size of program headers:           56 (bytes)Number of program headers:         11Size of section headers:           64 (bytes)Number of section headers:         30Section header string table index: 29

复制代码

上面结构体里成员类型长度的定义为:

名称

大小

说明

Elf32_Addr

4

无符号程序地址

Elf32_Half

2

无符号中等整数

Elf32_Off

4

无符号文件偏移

Elf32_SWord

4

有符号大整数

Elf32_Word

4

无符号大整数

unsigned char

1

无符号字符型整数

Elf32_Ehdr 各个成员简介:

  • e_ident magic bytes (0x7fELF), class, ABI version....是一组包含多个标志的数组。
  • e_typeobject file type—ET{REL,DYN,EXEC,CORE} 00-未知, 01--RT_REL,02--ET_EXEC, 03---ET_DY
  • e_machine required architecture—EM X86 64, ... 其中3h=386, 28h=ARM
  • e_version EV CURRENT, always ”1”
  • e_entry virt. addr. of entry point, dl start, jmp *%r12
  • e_phoff program header offset
  • e_shoff section header offset
  • e_flags CPU-specific flags
  • e_ehsize ELF header size
  • e_phentsize size of program header entry, consistency check
  • e_phnum number of program header entries
  • e_shentsize size of section header entry
  • e_shnum number of section header entries
  • e_shstrndx section header string table index

     其中e_ident 对应了对各字段,有MAGIC、Class、Data、Version、 ABI这几个参数。

Name

Value

Purpose

EI_MAG0

0

File identification

EI_MAG1

1

File identification

EI_MAG2

2

File identification

EI_MAG3

3

File identification

EI_CLASS

4

File class

EI_DATA

5

Data encoding

EI_VERSION

6

File version

EI_OSABI

7

Operating system/ABI identification

EI_ABIVERSION

8

ABI version

EI_PAD

9

Start of padding bytes

EI_NIDENT

16

Size of e_ident[]

1)MAGIC是ELF标志码:魔数,占4字节,byte0固定为0x7F,byte1--byte3是'E', 'L', 'F' 的ASCII码。

2)EI_CLASS 是CPU字长类型。

Name

Value

Meaning

ELFCLASSNONE

0

Invalid class

ELFCLASS32

1

32-bit objects

ELFCLASS64

2

64-bit objects

3)EI_DATA

0:非法格式

1:小端字节序LSB

2:大端字节序MSB

4)EI_VERSION: ELF版本号,为1

5)EI_OSABI

Name

Value

Meaning

ELFOSABI_NONE

0

No extensions or unspecified

ELFOSABI_HPUX

1

Hewlett-Packard HP-UX

ELFOSABI_NETBSD

2

NetBSD

ELFOSABI_LINUX

3

Linux

ELFOSABI_SOLARIS

6

Sun Solaris

ELFOSABI_AIX

7

AIX

ELFOSABI_IRIX

8

IRIX

ELFOSABI_FREEBSD

9

FreeBSD

ELFOSABI_TRU64

10

Compaq TRU64 UNIX

ELFOSABI_MODESTO

11

Novell Modesto

ELFOSABI_OPENBSD

12

Open BSD

ELFOSABI_OPENVMS

13

Open VMS

ELFOSABI_NSK

14

Hewlett-Packard Non-Stop Kernel

64-255

Architecture-specific value range

3、段表--Section

1)段表的结构

    ELF 文件中有很多段,段表(Section Header Table)就是保存这些段的基本属性的结构。段表描述了ELF各个段的信息,如段名、段的长度、在文件中的偏移、读写权限等。段表在ELF文件中 的偏移是由文件头的e_shoff成员决定的。

复制代码

typedef struct{Elf32_Word sh_name;Elf32_Word sh_type;Elf32_Word sh_flags;Elf32_Addr sh_addr;Elf32_Off  sh_offset;Elf32_Word sh_size;Elf32_Word sh_link;Elf32_Word sh_info;Elf32_Word sh_addralign;Elf32_Word sh_entsize;
}Elf32_Shdr

复制代码

Elf32_Shdr成员含义:

  • sh_name 段名,但此次只是记录了段名字符串在 .shstrtab 中的偏移
  • sh_type 段的类型
  • sh_flags 段的标志位
  • sh_addr 段的虚拟地址,如果此段可以被加载则表示在进程中的虚拟地址,否则为0
  • sh_offset 如果此段位于文件中则表示此段在文件中的偏移
  • sh_size 段的长度
  • sh_link This member holds a section header table index link, whose interpretation depends on the section type.
  • sh_info This member holds extra information, whose interpretation depends on the section type.
  • sh_addralign 段对齐,以2的n次方表示,如果为0或1,表示没有对齐要求。
  • sh_entsize Section Entry Size段的长度

 sh_type :段的类型。

Name

Value

SHT_NULL

0

SHT_PROGBITS

1

SHT_SYMTAB

2

SHT_STRTAB

3

SHT_RELA

4

SHT_HASH

5

SHT_DYNAMIC

6

SHT_NOTE

7

SHT_NOBITS

8

SHT_REL

9

SHT_SHLIB

10

SHT_DYNSYM

11

SHT_LOPROC

0x70000000

SHT_HIPROC

0x7fffffff

SHT_LOUSER

0x80000000

SHT_HIUSER

0xffffffff

sh_flag:段的标志位,表示该段在进程的虚拟地址空间中的属性,如是否可读、写、执行。

Name

Value

notes

SHF_WRITE

0x1

可读

SHF_ALLOC

0x2

需要分配空间

SHF_EXECINSTR

0x4

可执行

SHF_MASKPROC

0xf0000000

sh_link 和 sh_info: 如果段是与链接相关的,比如重定位表符号表等,sh_link和sh_info这两个成员所包含的意义如下所示。

sh_type

sh_link

sh_info

SHT_DYNAMIC

该段所使用的字符串表在段表中的下标

0

SHT_HASH

该段所使用的符号表在段表中的下标

0

SHT_REL

该段所使用的相应符号表在段表中的下标

该重定位表所作用的段在段表中的下标

SHT_RELA

该段所使用的相应符号表在段表中的下标

该重定位表所作用的段在段表中的下标

SHT_SYMTAB

操作系统相关的

操作系统相关的

SHT_DYNAMIC

操作系统相关的

操作系统相关的

other

SHN_UNDEF

0

2)重定位表

    rel.txt段就是重定位表,类型sh_type为SHT_REL(9)。链接器在处理目标文件时,对目标文件某些部位进行重定位,即代码段和数据段中的那部分绝对地址引用。这些重定位信息记录在ELF文件的重定位表中。

3)字符串表

    ELF中有很多字符串,如变量名段名等,但是字符串长度是不定长的,如果用固定的长度来表示比较困难,常见的做法是把字符串集中起来放到一个表中,然后使用字符串在表中的偏移来引用字符串。

4)符号表

    在ELF文件中,把函数和变量统称为符号(Sysbol),每个符号有一个相应的值叫做符号值。对函数和变量来说,符号值就是它们的地址。在ELF文件中,用.symtab这个段来记录符号表。

复制代码

typedef struct{Elf32_Word st_name;Elf32_Addr st_value;Elf32_Word st_size;unsigned char st_info;unsigned char st_other;Elf32_Half st_shndx;
}Elf32_Sym

复制代码

  • st_name 符号名,符号名称在字符串表中的索引
  • st_value 符号相应的值,可能是地址或一个绝对值数
  • st_size 符号大小
  • st_info 符号类型和绑定值
  • st_other 默认0
  • st_shndx 符号所在的段

st_info 高4位表示符号绑定信息,低4位表示符号类型。

Symbol Binding, ELF32_ST_BIND

Name

Value

STB_LOCAL

0

STB_GLOBAL

1

STB_WEAK

2

STB_LOPROC

13

STB_HIPROC

15

Symbol Types, ELF32_ST_TYPE

Name

Value

STT_NOTYPE

0

STT_OBJECT

1

STT_FUNC

2

STT_SECTION

3

STT_FILE

4

STT_LOPROC

13

STT_HIPROC

15

5)全局偏移表和跳转表

.plt和.got 动态链接的跳转表和全局入口表。

6)其它

代码段(.text): 代码数据

数据段(.data): 初始化过了的全局变量和局部静态变量

只读数据段(.rodata) 只读数据如const值、字符串常量。

.bss段:未初始化的全局变量和局部变量,是否为全局变量和局部变量预留空间和编译器的实现相关。

自定义段:在变量和函数前加__attribute__((section("name"))) 属性就可以把相应的函数或变量放到以name作为段名的段中。

4、ELF文件加载视图

    虽然ELF把可变数据和不可变数据分的很细,用户也可以自己添加段或命名一个段,但加载器把ELF文件加载到内存时,并不按照ELF的结构读取。例如目标文件.o里的代码段.text是section,链接时多个可重定位文件整合成一个可执行的文件,为了提高程序的效率,链接器把目标文件中相同的section 整合成一个segment,方便运行时加载器加载程序。由于虚拟内存的映射和优化的存在,ELF文件在加载到虚拟内存时,也会合并不同的段来达到节约资源的目的。

 

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

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

相关文章

【SpringCloud】RabbitMQ基础

1.初识MQ 1.1.同步和异步通讯 微服务间通讯有同步和异步两种方式: 同步通讯:就像打电话,需要实时响应。 异步通讯:就像发邮件,不需要马上回复。 两种方式各有优劣,打电话可以立即得到响应,…

vue2-diff算法

1、diff算法是什么? diff算法是一种通过同层的树节点进行比较的高效算法。 其有两个特点: 比较只会在同层级进行,不会跨层级进行。 在diff比较的过程中,循环从两边向中间比较。 diff算法在很多场景中都有应用,在vue中&…

Jmeter(一) - 从入门到精通 - 环境搭建(详解教程)

1.JMeter 介绍 Apache JMeter是100%纯JAVA桌面应用程序,被设计为用于测试客户端/服务端结构的软件(例如web应用程序)。它可以用来测试静态和动态资源的性能,例如:静态文件,Java Servlet,CGI Scripts,Java Object,数据库和FTP服务器…

Hadoop学习:深入解析MapReduce的大数据魔力(二)

Hadoop学习:深入解析MapReduce的大数据魔力(二) 3.3 Shuffle 机制3.3.1 Shuffle 机制3.3.2 Partition 分区3.3.3 Partition 分区案例实操3.3.4 WritableComparable 排序3.3.5 Combiner 合并 3.4 OutputFormat 数据输出3.4.1 OutputFormat 接口…

HttpServletRequest和HttpServletResponse的获取与使用

相关笔记:【JavaWeb之Servlet】 文章目录 1、Servlet复习2、HttpServletRequest的使用3、HttpServletResponse的使用4、获取HttpServletRequest和HttpServletResponse 1、Servlet复习 Servlet是JavaWeb的三大组件之一: ServletFilter 过滤器Listener 监…

医学图像处理

医学图像处理 opencv批量分片高像素图像病理图像色彩特征提取基于 imgaug、skimage 实现色彩增强基于 Cycle-GAN 完成染色标准化 病理图像细微特征提取自动数据标注分类场景下的医学图像分析分割场景下的医学图像分析检测场景下的医学图像分析 , i ] k 8 < * I opencv批量…

4.DNS和负载均衡

文章目录 coreDNS概念部署croeDNS测试 kubernetes多master集群结构master节点部署 负载均衡配置部署nginx做四层反向代理安装高可用 keepalivednginx监控脚本修改k8s中组件的配置文件 coreDNS 概念 coreDNS是kubernetes的默认DNS实现。可以为集群中的service资源创建一个资源名…

PyTorch中加载模型权重 A匹配B|A不匹配B

在做深度学习项目时&#xff0c;从头训练一个模型是需要大量时间和算力的&#xff0c;我们通常采用加载预训练权重的方法&#xff0c;而我们往往面临以下几种情况&#xff1a; 未修改网络&#xff0c;A与B一致 很简单&#xff0c;直接.load_state_dict() net ANet(num_cla…

Java课设--学生信息管理系统(例1)

文章目录 前提一、运行效果二、Text实现类三、Manage选择类四、StudentWay学生方法类五、StudnetSql数据库类 前题 例1为无使用GUI图形界面&#xff0c;例2使用GUI图形界面&#xff01; 首先自己的JDBC驱动已经接好了&#xff0c;连接自己的数据库没有问题。连接数据库可以看…

《吐血整理》高级系列教程-吃透Fiddler抓包教程(33)-Fiddler如何抓取WebSocket数据包

1.简介 本来打算再写一篇这个系列的文章也要和小伙伴或者童鞋们说再见了&#xff0c;可是有人留言问WebSocket包和小程序的包不会抓&#xff0c;那就关于这两个知识点宏哥就再水两篇文章。 2.什么是Socket&#xff1f; 在计算机通信领域&#xff0c;socket 被翻译为“套接字…

物联网||不一样的点灯实验(2)|通过使用CMSIS库函数实现点灯实验-学习笔记(12)

文章目录 通过使用CMSIS库函数实现点灯实验1 如何使用CMIS库2 如何利用CMSIS库操作IO 两种实现方法的比较课后作业:完整代码&#xff1a;LED.C:test.c:led.h:systick.h:systick.c: 通过使用CMSIS库函数实现点灯实验 1 如何使用CMIS库 #####如何使用此驱动#####[. .](#)启用GPI…

langchain-ChatGLM源码阅读:参数设置

文章目录 上下文关联对话轮数向量匹配 top k控制生成质量的参数参数设置心得 上下文关联 上下文关联相关参数&#xff1a; 知识相关度阈值score_threshold内容条数k是否启用上下文关联chunk_conent上下文最大长度chunk_size 其主要作用是在所在文档中扩展与当前query相似度较高…

RichTextBox基本用法

作用&#xff1a;富文本编辑器&#xff0c;支持多种文本展示 常用属性&#xff1a; 允许显示多行 自动换行 展示滚动条 ScrollBars属性值&#xff1a; 1、Both&#xff1a;只有当文本超过RichTextBox的宽度或长度时&#xff0c;才显示水平滚动条或垂直滚动条&#xff0c;或两…

基于粒子群优化算法的配电网光伏储能双层优化配置模型[IEEE33节点](选址定容)(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f308;4 Matlab代码、数据、讲解 &#x1f4a5;1 概述 由于能源的日益匮乏&#xff0c;电力需求的不断增长等&#xff0c;配电网中分布式能源渗透率不断提高&#xff0c;且逐渐向主动配电网方…

【雕爷学编程】Arduino动手做(184)---快餐盒盖,极低成本搭建机器人实验平台2

吃完快餐粥&#xff0c;除了粥的味道不错之外&#xff0c;我对个快餐盒的圆盖子产生了兴趣&#xff0c;能否做个极低成本的简易机器人呢&#xff1f;也许只需要二十元左右 知识点&#xff1a;轮子&#xff08;wheel&#xff09; 中国词语。是用不同材料制成的圆形滚动物体。简…

Mac端口扫描工具

端口扫描工具 Mac内置了一个网络工具 网络使用工具 按住 Command 空格 然后搜索 “网络实用工具” 或 “Network Utility” 即可 域名/ip转换Lookup ping功能 端口扫描 https://zhhll.icu/2022/Mac/端口扫描工具/ 本文由 mdnice 多平台发布

【具生智能】前沿思考与总结(DALL-E-Bot TinyBot)

1. DALL-E-Bot DALL-E-Bot: Introducing Web-Scale Diffusion Models to Robotics (robot-learning.uk) **&#xff08;2023-05-04&#xff09;**DALL-E-Bot: Introducing Web-Scale Diffusion Models to Robotics DALL-E-Bot&#xff1a;将网络规模的扩散模型引入机器人 第…

C语言----动态内存分配(malloc calloc relloc free)超全知识点

目录 一.动态内存函数 1.malloc 2.free 3.calloc 4.malloc和calloc的区别 5.realloc 二.动态内存分配的常见错误 1.对null进行解引用操作 2.对动态开辟空间的越界访问 3.对非动态开辟内存使用free释放 4.使用free释放动态开辟内存的一部分 5.对同一块动态内存多次…

物联网|按键实验---学习I/O的输入及中断的编程|读取I/O的输入信号|中断的编程方法|轮询实现按键捕获实验-学习笔记(13)

文章目录 实验目的了解擒键的工作原理及电原理图 STM32F407中如何读取I/O的输入信号STM32F407对中断的编程方法通过轮询实现按键捕获实验如何利用已有内工程创建新工程通过轮询实现按键捕获代码实现及分析1 代码的流程分析2 代码的实现 Tips:下载错误的解决 实验目的 了解擒键…

Leetcode-每日一题【剑指 Offer 09. 用两个栈实现队列】

题目 用两个栈实现一个队列。队列的声明如下&#xff0c;请实现它的两个函数 appendTail 和 deleteHead &#xff0c;分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素&#xff0c;deleteHead 操作返回 -1 ) 示例 1&#xff1a; 输入&#xff1a; [&…