ELF文件格式解析

ELF文件格式提供了两种视图,分别是链接视图和执行视图。链接视图是以节(section)为单位,执行视图是以段(segment)为单位。链接视图就是在链接时用到的视图,而执行视图则是在执行时用到的视图。

这里写图片描述

尽管图中显示各个组成部分都是有序的,但是实际上除了ELF header之外,其他部分都是没有规定顺序的。

1. ELF Header

typedef 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;   // Program Header Table的偏移量
       ELF32_Off e_shoff;   // Section Header Table的偏移量
       ELF32_Word e_flags;  // 相关处理器的标志
       ELF32_Half e_ehsize; // ELF Header结构大小
       ELF32_Half e_phentsize; // Program Header Table的表项大小
       ELF32_Half e_phnum;     // Program Header Table的表项数目
       ELF32_Half e_shentsize; // Section Header Table表项大小
       ELF32_Half e_shnum;     // Section Header Table表项数目
       ELF32_Half e_shstrndx;  // 字符串表在Section Header Table中的索引
}Elf32_Ehdr;

除了ELF Header之外,其他部分都是没有规定顺序的,所以,这里可以通过ELF Header的e_phoff以及e_shoff字段来确定Program Header Table和Section Header Table的位置。另外,通过e_shstrndx可以确定字符串表在Section Header Table中位置,例如,如果e_shstrndx为25,那么值25表示的是Section Header Table中第25项是字符串表(String Table, .shstrtab)。

2. Section Header Table

一个ELF文件中到底有哪些具体的 Sections,由包含在这个ELF文件中的 Section Header Table决定。在Section Header Table中,针对每一个Section,都有一个相应的条目(entry),用来描述对应的这个Section的相关信息。

typedef struct {
    Elf32_Word sh_name;  // 对应Section的名字
    Elf32_Word sh_type;  // 对应Section类型
    Elf32_Word sh_flags; // 对应Section在进程中执行的特性(读、写)
    Elf32_Addr sh_addr;  // 对应Section在内存中的虚拟地址
    Elf32_Off  sh_offset;// 对应Section在文件中的偏移
    Elf32_Word sh_size; // 对应Section的大小
    Elf32_Word sh_link;  
    Elf32_Word sh_info;
    Elf32_Word sh_addralign;
    Elf32_Word sh_entsize;
} Elf32_Shdr;

需要注意的是,sh_name值实际上是String Table(.shstrtab)中的索引,也就是说sh_name对应的并不是一个字符串,而且表示的一个索引值,通过这个索引值,我们可以在String Table中找到对应的字符串,而String table(.shstrtab)中存储着所有Section的名字。

3. Section

分析一些so文件中重要的Section,包括符号表、重定位表、GOT表等。

-Symbol Table(.dynsym)

符号表记录了该文件中的所有符号,所谓的符号就是经过修饰了的函数名或者变量名。

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跟上面Section Header Table的sh_name一样,表示的是符号名在字符串表中的索引。

-String Table(.dynstr)

.dynstr和.shstrtab结构完全相同,不过一个存储的是符号名称的字符串,而另一个是Section名称的字符串。

-重定位表

重定位是将符号引用与符号定义进行连接的过程

typedef struct {
    Elf32_Addr r_offset; // 符号在got表的偏移地址
    Elf32_Word r_info;  // 进行重定位的符号在符号表索引
} Elf32_Rel;

typedef struct {
    Elf32_Addr r_offset;
    Elf32_Word r_info;
    Elf32_Word r_addend;
} Elf32_Rela;

-全局偏移表(GOT)

全局偏移表(GOT)用来将位置独立的地址计算重定向到绝对位置。

-过程链接表(PLT)

过程链接表(PLT)能够把位置独立的函数调用重定向到绝对位置。

4. Program Header Table

程序头部(Program Header)描述与程序执行直接相关的目标文件结构信息。

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;        //在内存映像中占用的字节数。可以为0。
    Elf32_Word p_flags;        //相关的标志。
    Elf32_Word p_align;        //在文件中和内存中如何对齐。
} Elf32_phdr;

参考文章:
ELF文件格式解析
linux第三次实践:ELF文件格式分析

欢迎关注微信公众号:DroidMind
精品内容独家发布平台


呈现与博客不一样的技术干货

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值