浅谈ELF的认识

一、引入ELF

1.1 第一个视角先了解点基础的知识

  当我们创建一个Hello.c文件后,会使用gcc命令编译运行生成一个a.out的可执行文件,但是在这背后还隐藏了许多的动作,有了这个动作的支持,我们最终才可以生成一个可执行文件。我们先看一个hello.c文件到a.out文件中间发生了什么?

图来自 原文章
在这里插入图片描述
背后逻辑简述:(引入名词:目标文件 与 动态库)

  汇编器将汇编语言翻译为机器语言,生成一个可重定位目标文件,该文件作为输入传入到连接器,连接器生成一个 可执行目标文件。该可执行目标文件加载到存储器里供系统调用,系统就一步步提取我们程序的指令,分配进程。
  以我们程序的printf函数为例子,这个函数存在与printf.o 的函数库里。要调用printf函数,两个方式:

  • 1 ) 在编译链接时,把库函数printf.o的全部信息加载到可执行文件里面(代价就是使得可执行文件比较大,但是运行的时候不需要再次调用库函数)生成后缀为 .a 的文件;

  • 2 ) 在编译链接时不发生操作,只在运行时链接库函数(可以节省资源开支,gcc默认)生成后缀为 .so 的文件;

  正式一点,我们将这两种方式命名为:静态库与动态库,gcc默认采用动态库

目标文件:

  • 可重定位目标文件(.o) (Executable File)

      包含代码和数据,是可以直接运行的程序。其代码和数据都有固定的地址 (或相对于基地址的偏移 ),系统可根据这些地址信息把程序加载到内存执行。

  • 可执行目标文件(.out) (Relocatable File)

     包含基础代码和数据,但它的代码及数据都没有指定绝对地址,因此它适合于与其他目标文件链接来创建可执行文件或者共享目标文件。

  • 共享目标文件(.so) (Shared Object File)

      也称动态库文件,包含了代码和数据,这些数据是在链接时被链接器(ld)和运行时动态链接器(ld.so.l、libc.so.l、ld-linux.so.l)使用的。

1.2 第二个视角先了解点基础的知识

  从第一个视角的介绍中,我们了解到一个文件从被创建到运行具体的流程,探究了它背后的一些秘密,然而我们为什么要知道这些呢,接下来就从宏观的角度从操作系统的角度介绍一下ELF文件的作用,我们的理解不应该局限于个别的场景。

操作系统 概念中介绍到:
  当很多条的进程在同时请求资源,但是物理内存只有4GB,于是引用虚拟内存通过特定的置换算法转化为物理内存,使得程序可以正常运作。

我们运行一个程序时候,

 1.用户请求运行程序时,操作系统会读取存储在磁盘上的可执行文件,在linux系统上这个文件就是我们的 elf格式文件,为用户分配4G的虚拟内存空间,
 
 2. 根据文件的信息指示,把不同的文件内容放到为你分配的这3G虚拟内存
 
 3. 然后根据文件的指示,系统设置设置代码段和数据段寄存器

 4.然后根据文件的指示,    跳转到用户的代码的入口地址(一般就是我们的main函数)

二、 介绍 ELF

  现在我们已经知道了一个可执行文件产生背后的简单逻辑,在不同的系统平台上面,可行性文件的叫法也不一致,在Unix和X86-64 Linux上称为ELF(Executable and Linkable Format, ELF),正如目标文件有上述三类一样,ELF也会有上述三个文件分类(不同名字而已,内容一致)

(现在我们已经知道了如何从无到有一个ELF文件,下面了解一下ELF具体的内容吧)

EIF文件结构

首先,ELF文件格式提供了两种视图,分别是链接视图和执行视图。

简易图:

在这里插入图片描述
标准参考图:
在这里插入图片描述

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

  实际上,一个文件中不一定包含全部内容,而且它们的位置也未必如同所示这样安排,只有ELF头的位置是固定的,其余各部分的位置、大小等信息由ELF头中的各项值来决定。

在这里插入图片描述

  1. 程序头部表(Program Header Table),如果存在的话,告诉系统如何创建进程映像。
对于可执行文件来说,文件头包含的一下信息与进程启动相关

e_entry      程序入口地址

e_phoff      segment偏移

e_phnum      segment数量
  1. 节区头部表(Section Header Table)包含了描述文件节区的信息,比如大小、偏移等。

  2. section表,对可执行文件来说,没有用,在链接的时候有用,是对代码段数据段在链接是的一种描述。

  3. 数据段和代码段最重要

    

OK,ELF表基本结构已经了解到了,接下来看看怎么使用命令调用查看信息

三、应用

在Linux下,我们可以使用 readelf 命令工具可以查看ELF格式文件的一些信息
在这里插入图片描述

接下来我们来看Section Header Table格式
在这里插入图片描述

用hexdump或者使用010 Editor工具把目标文件的字节全部打印出来看
在这里插入图片描述
定位到.text的范围,然后将这个表编码

3.3 .text节
通过使用objdump工具可以把程序中的机器指令进行反汇编得到其汇编代码

在这里插入图片描述
在这里插入图片描述
草,我写不下去了,

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值