elf文件结构

elf文件结构
有三种类型
可重定位文件(Relocatable File),包含由编译器生成的代码以及数据。链接器会将它与其它目标文件链接起来从而创建可执行文件或者共享目标文件。在 Linux 系统中,这种文件的后缀一般为 .o 。

可执行文件(Executable File),就是我们通常在 Linux 中执行的程序。

共享目标文件(Shared Object File),包含代码和数据,这种文件是我们所称的库文件,一般以 .so 结尾。一般情况下,它有以下两种使用情景
链接器(Link eDitor, ld)可能会处理它和其它可重定位文件以及共享目标文件,生成另外一个目标文件。
动态链接器(Dynamic Linker)将它与可执行文件以及其它共享目标组合在一起生成进程镜像
目标文件既会参与程序链接又会参与程序执行。出于方便性和效率考虑,根据过程的不同,目标文件格式提供了其内容的两种并行视图,如下
在这里插入图片描述链接视图

在这里插入图片描述文件开始处是 ELF 头部,给出文件的组织情况
program header table 告诉系统如何创建进程
section header table 描述文件节区信息

ELF Header
描述elf文件的概要信息

#define EI_NIDENT   16

typedef struct {
    unsigned char   e_ident[EI_NIDENT];'\x7felf'(魔数)
    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;

e_ident放魔数,64还是32,小端还是大端,EV_CURRENT(版本必须是),填充
e_type是什么类型的elf文件
e_mechine是什么机器架构
e_version 是EV_CURRENt
e_entey 是 程序入口点的虚拟地址
e_phoff是程序头部表的字节偏移
e_shoff是节头表(段表)的字节偏移
e_flags不知道有什么用
e_ehsize头部的字节长度(head)
e_phentsize头部每个表相的字节长度(Program Header ENTry SIZE)
e_phnum 头部表的项数(Program Header entry NUMbe)
e_shentsize节头的字节长度
e_shnum节头的项数
e_shstrndx(看不懂)

Program Header Table

Program Header Table 是一个结构体数组,每一个元素的类型是 Elf32_Phdr,描述了一个段或者其它系统在准备程序执行时所需要的信息。其中,ELF 头中的 e_phentsize 和 e_phnum 指定了该数组每个元素的大小以及元素个数。一个目标文件的段包含一个或者多个节。程序的头部只有对于可执行文件和共享目标文件有意义
该结构用于定位 ELF 文件中的每个节区的具体位置。

typedef struct {
    ELF32_Word  p_type;//段类型
    ELF32_Off   p_offset;//文件到该段的偏移
    ELF32_Addr  p_vaddr;//段的虚拟地址
    ELF32_Addr  p_paddr;//段的物理地址
    ELF32_Word  p_filesz;/* 文件镜像段大小 */
    ELF32_Word  p_memsz;/* 内存镜像段大小 */
    ELF32_Word  p_flags;//标记
    ELF32_Word  p_align;//对齐相关
} Elf32_Phdr;

内存中任何段的虚拟地址与文件中对应的虚拟地址之间的差值对于任何一个可执行文件或共享对象来说是一个单一常量值。这个差值就是基地址,基地址的一个用途就是在动态链接期间重新定位程序
段内容
一个段可能包括一到多个节区,但是这并不会影响程序的加载。尽管如此,我们也必须需要各种各样的数据来使得程序可以执行以及动态链接等等
Section Header Table
其实这个数据结构是在 ELF 文件的尾部

该结构用于定位 ELF 文件中的每个节区的具体位置。

首先,ELF头中的 e_shoff 项给出了从文件开头到节头表位置的字节偏移。e_shnum 告诉了我们节头表包含的项数;e_shentsize 给出了每一项的字节大小。

其次,节头表是一个数组,每个数组的元素的类型是 ELF32_Shdr ,每一个元素都描述了一个节区的概要内容

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;

sh_name 节名称
sh_type 节类型
sh_flags 描述节是否可写,可执行,需要分配内存等属性
sh_addr 在内存镜像的位置
sh_offset在文件的偏移
sh_size 节区的字节大小
sh_link 此成员给出节区头部表索引链接
sh_info 此成员给出附加信息
sh_addralign 某些节区的地址需要对齐
sh_entsize(不晓得)

elf中一些特殊的表(段)

.rel.xxxx (重定位表 用来描述修改段的内容 调指令的) sh_type为SHT_REL ()

typedef struct {
    Elf32_Addr r_offset;//重定位入口点的偏移
    Elf32_Word r_info;//类型和符号
}Elf32_Re;

.strtab 字符串表
.shstrtab 段表
.symtab 符号表(经常被删。。。)
Elf32_Sym的数组

typedef struct {
  Elf32_Word st_name;//符号名
  Elf32_Addr st_value;//值 common块之类的
  Elf322_Word st_size;//符号大小
  unsigned char st_info;//符号类型和绑定信息
  unsigned char st_other;//没用
  Elf32_Half st_shndx;//符号所在段
}

(动态链接 延迟绑定的)
got
plt (dl_runtime_resolve())
.got保留全局变量引用的地址
.got.plt(函数引用的地址)(数组)
0 .dynamic段的地址
1 id
2 _d1_runtime_resolve(的地址)
.dynsym(动态符号表)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值