良许Linux教程网 干货合集 简单认识认识ELF文件

简单认识认识ELF文件

几种常见的ELF文件

在Linux下,我们经gcc编译之后生成的可执行文件属于ELF文件:

image-20231008200639444
image-20231008200639444

ELF是一类文件类型,而不是特指某一后缀的文件。ELF(Executable and Linkable Format,可执行与可链接格式)文件格式,在Linux下主要有如下三种文件:

  • 可执行文件(.out):Executable File,包含代码和数据,是可以直接运行的程序。其代码和数据都有固定的地址 (或相对于基地址的偏移 ),系统可根据这些地址信息把程序加载到内存执行。
  • 可重定位文件(.o文件):Relocatable File,包含基础代码和数据,但它的代码及数据都没有指定绝对地址,因此它适合于与其他目标文件链接来创建可执行文件或者共享目标文件。
  • 共享目标文件(.so):Shared Object File,也称动态库文件,包含了代码和数据,这些数据是在链接时被链接器(ld)和运行时动态链接器(ld.so.l、libc.so.l、ld-linux.so.l)使用的。

ELF格式可结构大致为:

image-20231008200642752
image-20231008200642752

(图片来源:百度百科)

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

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

readelf工具的使用

在Linux下,我们可以使用readelf 命令工具可以查看ELF格式文件的一些信息。

下面我们先准备一个动态链接相关的demo,就拿我们之前分享的文章:静态链接与动态链接补充(Linux)中的demo来做演示:

image-20231008200645812
image-20231008200645812

文件1(main.c):

#include "test.h"

int main(void)
{
 print_hello();
 return 0;
}

文件2(test.c):

#include "test.h"

void print_hello(void)
{
 printf("hello world\n");
}

文件3(test.h):

#ifndef __TEST_H
#define __TEST_H

#include 

void print_hello(void);

#endif

执行相关命令生成相关文件:.out文件.o文件.so文件。如:

image-20231008200648957
image-20231008200648957

下面我们使用readelf命令来查看这三类文件的一些信息。readelf命令格式为:

readelf 

查看可执行文件头部信息:

image-20231008200651659
image-20231008200651659

查看可执行文件头部信息是,我们发现这样一个问题,头部信息中的类型竟然是共享库文件,而我们查看的是可执行文件,自相矛盾?

查了一些资料:

https://blog.csdn.net/cclethe/article/details/83387685

发现:gcc编译默认加了--enable-default-pie选项:

image-20231008200654386
image-20231008200654386

Position-Independent-Executable是Binutils,glibc和gcc的一个功能,能用来创建介于共享库和通常可执行代码之间的代码–能像共享库一样可重分配地址的程序,这种程序必须连接到Scrt1.o。

标准的可执行程序需要固定的地址,并且只有被装载到这个地址时,程序才能正确执行。

PIE能使程序像共享库一样在主存任何位置装载,这需要将程序编译成位置无关,并链接为ELF共享对象。

引入PIE的原因是让程序能装载在随机的地址,通常情况下,内核都在固定的地址运行,如果能改用位置无关,那攻击者就很难借助系统中的可执行码实施攻击了。

类似缓冲区溢出之类的攻击将无法实施。而且这种安全提升的代价很小。

也就是说,pie这是一种保护我们可执行程序的一种手段。这里我们只是做实验,我们可以加-no-pie参数先把pie给关掉:

image-20231008200657083
image-20231008200657083

可以看到,类型终于对得上了。ELF头部信息还包含有Entry point address(入口地址)、Start of program headers(程序头的起始字节)、Start of section headers(节头的起始字节)等信息。

查看可重定位文件头部信息:

image-20231008200701217
image-20231008200701217

**
**

查看共享目标文件头部信息:

image-20231008200704364
image-20231008200704364

同样的,readelf 搭配其它参数可以查看ELF文件的其它信息:

image-20231008200707071
image-20231008200707071

objdump工具的使用

objdump工具用于显示一个或多个目标文件的信息。objdump命令格式:

objdump

可执行文件、可重定位文件与共享目标文件都属于目标文件,所以都可以使用这个命令来查看一些信息。

查看可重定位文件反汇编信息:

image-20231008200710879
image-20231008200710879

**
**

查看可执行文件反汇编信息:

image-20231008200714130
image-20231008200714130

**
**

查看共享目标文件反汇编信息:

image-20231008200716752
image-20231008200716752

总结

以上就是本次的分享。简单地介绍了ELF文件的一些信息,同时介绍了分析ELF文件的两个工具。

ELF文件的内容很多,并且比较抽象,详细分析起来是个深坑。我们大致先进行一个简单的了解,之后如果深入学习时再做另外的分享。

以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !

137e00002230ad9f26e78-265x300
本文由 良许Linux教程网 发布,可自由转载、引用,但需署名作者且注明文章出处。如转载至微信公众号,请在文末添加作者公众号二维码。
良许

作者: 良许

良许,世界500强企业Linux开发工程师,公众号【良许Linux】的作者,全网拥有超30W粉丝。个人标签:创业者,CSDN学院讲师,副业达人,流量玩家,摄影爱好者。
上一篇
下一篇

发表评论

联系我们

联系我们

公众号:良许Linux

在线咨询: QQ交谈

邮箱: yychuyu@163.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部