ElfReader-Elf文件类型

ElfReader-Elf文件类型

参考文献链接

https://github.com/jianhong-li/ElfReader

https://www.cnblogs.com/lwyeric/p/13582022.html

ELF 文件解析程序

说明: 用Java解析 ELF 不是一个好的idea, 特别是对于字节序, 无符号数 , 以及内存对齐等相关的操作处理 比较难受,特别是对于BYTE类型居然是有符号的. 这个在做字节扩展的时候,踩了很多坑. 另外定义对象头等处理 也不如C语言写起来自然. 权当给大家用作分析 ELF相对验证使用.

项目内容说明

这是一个解析ELF文件的Demo程序,主要是用于学习Linux ELF文件的基本构成, 从自己解析的角度弄明白一个ELF文件的结构是怎样构成的. 这样可以更深刻的理解其布局. 作者曾经解析过CLASS文件的基本格式, 这个可以看作C++版本的class文件解析.

原文件二进制映射

 

解析结果

 

 什么是ELF

ELF根据它的英文名称Executable and Linkable Format又叫做可执行与可链接格式,因此,ELF其实是一种Linux下的文件格式。

ELF文件类型

①可重定位文件(Relocatable File)
②可执行文件(Executable File)
③共享目标文件(Shared Object File)

我们分别来看下这三种文件:

ELF组成

ELF文件由4部分组成,分别是ELF头(ELF header)、程序头表(Program header table)、节(Section)或段(Segment)和节头表(Section header table)。

  • —ELF header:用来描述整个文件的组织;
  • —Program header table:描述文件中的各种segments;
  • —Section/Segment:Section是从链接角度描述ELF,Segment是从执行角度描述ELF;
  • —Section header table:包含了文件节区的信息,如大小,偏移

我们先来看一下Program header table和Section header table联系:
要知道这两个表的联系我就得先知道ELF文件格式提供了两种视图:分别是链接视图和执行视图

为什么需要两种视图?
当ELF文件被加载到内存后,系统会将多个具有相同权限的section合并成一个segment。操作系统通常是以页为基本单位来管理内存分配,一般页的大小为4KB。同时,内存的权限管理粒度也是以页为单位,页内的内存是具有同样的权限属性。ELF文件被映射时,是以系统的页长度为单位,每个section在映射时的长度都是系统页长度的整数倍,若section的长度不是其整数倍,则多余部分会占一个页,然而一个ELF文件具有多个section,会导致内存浪费严重,而将多个section合并后会以段为基准,减少了页面内部碎片,节省里空间,提高了内存利用率。

ELF header

ELF文件头位于ELF文件的起始位置,它包含整个文件的静态信息,可以通过readelf命令进行查看,ELF文件头结构以及相关参数定义在/usr/include/elf.h中,分为32位和64位两种版本,分别为Elf32_Ehdr和Elf_64_Ehdr,它们绝大多数内容都是一样的。

typedef struct {

Elf32_Half e_type;      //Elf文件类型

Elf32_Half e_machine;     //ELF文件的CPU平台属性

Elf32_Word e_version;     //ELF版本信息

Elf32_Addr e_entry;         //入口地址

Elf32_Off e_phoff;            //程序头表的文件偏移(以字节为单位)。如果文件没有程序头表,则此成员值为零。

Elf32_Off e_shoff;            //节头表的文件偏移(以字节为单位)。如果文件没有节头表,则此成员值为零。

Elf32_Word e_flags;         //与文件关联的特定于处理器的标志。标志名称采用 EF_machine_flag 形式。

Elf32_Half e_ehsize;         //ELF 头的大小(以字节为单位)

Elf32_Half e_phentsize;    //文件的程序头表中某一项的大小(以字节为单位)。所有项的大小都相同

Elf32_Half e_phnum;        //程序头表中的项数。

Elf32_Half e_shentsize;    //节头的大小(以字节为单位)。节头是节头表中的一项。所有项的大小都相同

Elf32_Half e_shnum;        //节头表中的项数

Elf32_Half e_shstrndx;     //与节名称字符串表关联的项的节头表索引。

} Elf32_Ehdr;

我们可以使用readelf命令查看ELF header:

 

使用readelf -l hello查看program header和section header的信息:

 

 

 

参考文献链接

https://github.com/jianhong-li/ElfReader

https://www.cnblogs.com/lwyeric/p/13582022.html

posted @ 2022-11-12 05:09  吴建明wujianming  阅读(221)  评论(0编辑  收藏  举报