pwn学习day1——ELF文件结构

0x01 介绍

ELF(Executable and Linkable Format)是一种常见的可执行文件和共享库格式,其结构如下:

  1. ELF header:包含了 ELF 文件的基本属性信息
  2. Program header table:描述了程序在内存中的加载情况,包括可执行代码段、数据段等。
  3. Section header table:描述了 ELF 文件中所有节区的信息,如代码节区、数据节区等。
  4. 节区数据:包含了 ELF 文件中的实际数据,如代码、数据等。

ELF 文件的结构可以根据不同的操作系统和体系结构而有所差异。

来点通俗的解释:

  1. 头部(Header):ELF文件的头部包含了整个文件的基本信息,如文件类型、机器架构、入口点地址等。可以将头部看作是文件的元数据,就像书的封面上包含了书的基本信息。
  2. 节区表(Section Table):节区表是一个数据结构,它描述了ELF文件中各个节区的位置和属性。类似于书的目录,它告诉你在书中的哪个位置可以找到某个章节或内容。
  3. 代码节区(Code Section):代码节区包含了程序的实际指令,即可执行的机器码。这部分就像是一本书中的具体章节内容,包含了实际的文字和故事情节。
  4. 数据节区(Data Section):数据节区存储了程序中使用的全局变量、静态变量和常量等数据。可以把它看作是书中的附录或者注释部分,包含了与故事情节相关的补充信息。
  5. 符号表(Symbol Table):符号表包含了程序中定义的函数和变量的信息,比如名称、地址等。可以将符号表类比为书的索引,你可以通过索引查找到书中特定关键字或人物的出现位置。
  6. 动态链接表(Dynamic Linking Table):动态链接表包含了程序在运行时所需的动态链接信息,比如依赖的共享库和符号解析的过程。它就像是一本参考书,提供了额外的信息和解释。

0x02 ELF header

/usr/include/elf.h 或ELF规范里可以查到ELF头部的定义:

typedef struct
{
  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;               /* ELF头部的大小 */
  Elf64_Half    e_phentsize;            /* 程序头表的条目大小 */
  Elf64_Half    e_phnum;                /* 程序头表的条目数 */
  Elf64_Half    e_shentsize;            /* 节头表的条目大小 */
  Elf64_Half    e_shnum;                /* 节头表的条目数 */
  Elf64_Half    e_shstrndx;             /* 节头表中与节名称字符串相关联的条目的索引 */
} Elf64_Ehdr;

ELF header包含以下部分:

标识信息 (e_ident)

包括ELF文件类型、机器架构、版本等信息。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ixcuzz1v-1687964972116)(https://cdn.nlark.com/yuque/0/2023/png/12758072/1680406734442-e07376a0-a049-480e-aa09-7f03f2a8a374.png)]

e_ident数组始终以4个字节的幻数为开头,以此来标识ELF文件,幻数由十六进制0x7f和ELF的ASCII码组成。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-noUMO1MZ-1687964972117)(https://cdn.nlark.com/yuque/0/2023/png/12758072/1680406667485-1257259c-efac-43b3-947b-002fcc1f6318.png)]

幻数后面的字节提供了有关ELF二进制文件类型规范的详细信息,后面那些字节的索引分别称为EI_CLASS、EI_DATA、EI_VERSION、EI_OSABI、EI_ABIVERSION以及EI_PAD等

  • EI_CLASS标识该二进制文件用于32位还是64位体系结构,前者设置为常量ELFCLASS32(1),后者设置为常量ELFCLASS64(2)
  • EI_DATA标识架构的字节序,也就是多字节值是大端序还是小端序,ELFDATA2LSB(1)表示小端序,ELFDATA2MSB(2)表示大端序
  • EI_VERSION标识ELF规范版本,现在只有一个值EV_CURRENT也就是1
  • EI_OSABI和EI_ABIVERSION标识关于应用程序二进制接口和操作系统的信息
  • EI_PAD包含多个字节,保留为了以后使用

readelf可以查看ELF头

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UqHMtPt9-1687964972118)(https://cdn.nlark.com/yuque/0/2023/png/12758072/1680407629546-32bd0e3e-d83f-46d0-bd72-d2b7dbaafea0.png)]

e_type、e_machine和e_version

文件类型 (e_type)

描述ELF文件的类型,如可执行文件、共享库、目标文件等。

机器架构 (e_machine)

描述ELF文件所使用的机器架构,例如x86、ARM等。

版本信息 (e_version)

描述ELF头部和节头表的版本号。

入口地址 (e_entry)

描述可执行文件入口点的虚拟内存地址。

e_phoff和e_shoff

程序头表偏移量 (e_phoff)

描述程序头表在文件中的偏移量。

节头表偏移量 (e_shoff)

描述节头表在文件中的偏移量。

标志 (e_flags)

描述ELF文件的各种属性,如是否为可重定位文件。

ELF头部大小 (e_ehsize)

描述ELF头部的大小。

e_*entsize和e_*num

程序头表项大小 (e_phentsize)

描述每个程序头表项的大小。

程序头表项数量 (e_phnum)

描述程序头表中有多少个表项。

节头表项大小 (e_shentsize)

描述每个节头表项的大小。

节头表项数量 (e_shnum)

描述节头表中有多少个表项。

字符串表索引 (e_shstrndx)

描述字符串表在节头表中的索引。

0x03 Program header table 程序头表

ELF(Executable and Linkable Format)文件的Program header table(程序头表)是一部分用于描述可执行文件和可链接文件的结构信息的表格。它包含了与程序运行相关的段(segment)信息。每个段描述了文件中的一个连续内存区域,这些区域在程序运行时被加载到内存中。

Program header table中的每一项都是一个程序头(Program Header),包含了以下字段:

  1. p_type:段的类型,指示段的作用和属性。常见的类型包括可加载段(PT_LOAD)、动态链接信息(PT_DYNAMIC)、符号表(PT_SYMTAB)等。
  2. p_flags:段的标志位,描述段的属性,如可读(PF_R)、可写(PF_W)、可执行(PF_X)等。
  3. p_offset:段在文件中的偏移量,表示该段的数据在文件中的位置。
  4. p_vaddr:段的虚拟地址,表示该段在内存中的加载地址。
  5. p_paddr:段的物理地址,一般在可执行文件中没有特定用途。
  6. p_filesz:段在文件中的大小,表示段的数据在文件中的长度。
  7. p_memsz:段在内存中的大小,表示段在内存中占用的长度。对于需要额外的内存空间的段,文件大小和内存大小可能不同。
  8. p_align:段在文件和内存中的对齐方式,表示段的起始位置在文件和内存中的偏移量需要满足的对齐要求。

Program header table的项数由e_phnum字段确定,该字段记录了Program header table中的项数。

总而言之,Program header table用于描述ELF文件中各个段的属性和位置信息,以便在程序加载和执行时进行正确的内存映射。  

0x04 Section Header Table(节头表)

ELF(Executable and Linkable Format)文件的Section Header Table(节头表)是一个重要的数据结构,用于描述和组织文件中的各个节(Section)。它包含了一系列节头(Section Header),每个节头对应一个节,用于存储关于该节的信息。Section Header Table位于ELF文件的头部信息中,可以通过解析ELF文件的头部来访问。

每个Section Header包含以下字段:

  1. Name(名称):存储该节的名称,是一个对字符串表(String Table)的索引,用于查找具体的节名称。

  2. Type(类型):指定该节的类型,如代码段(.text)、数据段(.data)、符号表(.symtab)等。不同类型的节承载着不同的功能和数据。

  3. Flags(标志):描述该节的属性和特征,如是否可读、可写、可执行等。

  4. Address(地址):指定该节在内存中的起始地址或者文件中的偏移地址。

  5. Offset(偏移量):指定该节在ELF文件中的偏移量,表示该节在文件中的位置。

  6. Size(大小):指定该节的大小,以字节为单位。

  7. Link(关联):指定其他相关节的索引,具体含义根据不同的节类型而定。

  8. Info(信息):包含与该节相关的其他信息,如符号表索引、重定位信息等。

  9. Address Alignment(地址对齐):指定该节在内存中的对齐方式。

  10. Entry Size(入口大小):对于某些特定类型的节,指定每个入口的大小。

    Section Header Table通过这些节头信息,提供了对ELF文件中各个节的描述和组织。它是ELF文件格式的重要组成部分,用于实现文件的装载、链接和执行等操作。

0x05 节区数据

ELF (Executable and Linkable Format)文件的节区(Section)是用来组织和存储程序的各种数据和代码的。一个ELF文件通常由多个节区组成,每个节区负责存储不同类型的数据。以下是一些常见的节区类型和它们可能包含的内容:

  1. 代码节区(Text Section):存储可执行代码。
  2. 数据节区(Data Section):存储初始化的全局和静态变量。
  3. BSS节区(BSS Section):存储未初始化的全局和静态变量。
  4. 符号表节区(Symbol Table Section):包含符号表,其中记录了程序中使用的函数、变量和其他符号的信息。
  5. 字符串表节区(String Table Section):包含字符串表,用于存储其他节区中使用的字符串。
  6. 重定位节区(Relocation Section):包含重定位信息,用于在链接过程中修正地址。
  7. 动态链接节区(Dynamic Linking Section):存储动态链接器使用的信息,如共享库的依赖关系和重定位信息。
  8. 调试节区(Debug Section):包含调试信息,如源代码行号、局部变量等。
  9. 初始化节区(Initialization Section):存储程序的初始化代码,用于在程序加载时执行一些初始化操作。
  10. 可执行节区(Executable Section):存储可执行程序的二进制代码。
  11. 其他自定义节区:开发者可以定义自己的节区类型,用于存储特定的数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值