ELF文件解析

本文详细介绍了ELF(Executable and Linkable Format)文件的结构,包括头信息、段头和节头等关键组成部分。头信息包含魔数、文件类型、机器类型、入口地址等,用于标识文件格式和提供加载信息。段头和节头则分别服务于运行期和链接期,描述了文件在内存中的布局和组织。文章还讲解了如何解读和分析段头、节头信息,以及动态链接节与段的相关内容。
摘要由CSDN通过智能技术生成

ELF介绍

Linux下可执行文件的格式是ELF(Executable amd Linkable Format),这种文件格式是基于COFF( Common File Format )文件标准的变种格式。ELF文件的全部定义可以在/usr/include/elf.h头文件和官网文档内进行查看。

下面所说的地址(虚拟地址或物理地址)一般不可以让内存直接拿来使用,但是可以通过该地址进行辅助计算,进而获得内存空间中正确的地址。

a.out: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=f593abe086161ce758678e314dd80a7e65f9bd7a, for GNU/Linux 3.2.0, not stripped

ELF文件中有头信息、段、节三个重要的概念需要进行了解。由于运行期和链接期中针对程序的划分方案有所差异,所以ELF文件针对两个不同的方案分化出了段和节两个概念,段为程序的运行期提供支持,节为程序的链接期提供支持。

在ELF文件中头信息的位置是固定在最顶部的,其他部分的位置并不是固定的,其中头信息可以检索到头表的起始位置。

在ELF文件中段或节由头(段头或节头)和身体(段或节)组成,头中定义了基本的属性。所有的头会组成一张头表,可以根据头表内不同头的属性索引到不同的身体部分。头表的首表项会记录整个头表的属性(如果存在),头表的属性也可以在头信息中获取。

常用工具

为了观察ELF文件,在Linux中常常使用readelf显示EFL文件的信息、objdump对ELF文件进行反汇编、hexdumpodvim使用不同的进制显示ELF文件中的内容。

头信息

头信息在ELF文件的开头,用于标明该文件是ELF文件、展示基本的信息、展示头表的基本信息。

头信息的存在是为了帮助计算机可不可以执行这个ELF文件(文件格式是否正确、架构是否匹配、ABI是否匹配等等)。

00000000  7f 45 4c 46 02 01 01 00 | 00 00 00 00 00 00 00 00  |.ELF............|
Magic
00000010  03 00 3e 00 01 00 00 00 | 40 10 00 00 00 00 00 00  |..>.....@.......|
文件类型 机器类型 版本 | 入口地址
00000020  40 00 00 00 00 00 00 00 | 60 36 00 00 00 00 00 00  |@.......`6......|
段索引地址 | 节索引地址 
00000030  00 00 00 00 40 00 38 00 | 0d 00 40 00 1d 00 1c 00  |....@.8...@.....|
标志 头信息大小 段大小 | 段数量 节大小 节数量 字符串表索引地址
​
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Position-Independent Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x1040
  Start of program headers:          64 (bytes into file)
  Start of section headers:          13920 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         13
  Size of section headers:           64 (bytes)
  Number of section headers:         29
  Section header string table index: 28

Magic

标明文件是ELF文件格式以及展示必要的信息。

位置1:7f,特定标志
位置2-4:45 4c 46 = E L F
位置5:ELF文件的执行类型
    00:无效的类型
    01:32位程序
    02:64位程序
位置6:数据编码格式
    00:无效的类型
    01:高位数据存放在内存的低地址中,低位数据存放在内存的高地址中
    02:低位数据存放在内存的低地址中,高位数据存放在内存的高地址中
位置7:版本
    0:无效的版本
    1:默认值
位置8:内核ABI(Application Binary Interface 应用程序接口)类型
位置9:ABI版本
位置10-16:保留位置

文件类型

标明不同类型的ELF文件。

0 无效的文件类型
1 可重定位文件      编译过程产生的中间文件,链接器可以将中间文件和其他文件或信息进行组合生成可执行文件
2 可执行文件        可以执行的文件
3 动态链接库文件    可执行文件运行时可以从动态链接库文件内获取需要执行的逻辑
4 转储文件          程序在某一时刻保存下来的信息

机器类型

标明ELF文件是运行在哪种体系结构的计算机中的。

入口地址

标明可执行程序的入口地址。

段头表

包含段头表的索引地址(如果没有段,那么对应的地址就是0)、段头的大小、段头的数量。

段头表内的段头在文件内连续存放的。

节头表

包含节头表的索引地址(如果没有节,那么对应的数值就是0)、节头的大小、节头的数量、字符串表在节头表中的位置。

节头表内的节头在文件内连续存放的。

标志位

标明特定处理器的信息。

段头

在ELF文件中,段和段头(段头也可以叫做程序头)并不是连续存放的,可以借助段头内的属性定位到ELF文件中对应段的位置。

因为段是运行期产生的概念,所有段头只对可执行文件或动态链接库这两个会被加载到内存中执行的文件有意义,其他类型的ELF文件可以忽略段头,因为它们不需要使用段,也就更不需要段头对段进行检索。

Elf file type is DYN (Position-Independent Executable file)
Entry point 0x1040
There are 13 program headers, starting at offset 64
Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000000040 0x0000000000000040
                 0x00000000000002d8 0x00000000000002d8  R      0x8
  INTERP         0x0000000000000318 0x0000000000000318 0x0000000000000318
                 0x000000000000001c 0x000000000000001c  R      0x1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  LOAD           0x0000000000000000 0x0000000000000
  • 20
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值