首页
社区
课程
招聘
[原创] ELF文件结构详解
发表于: 2019-11-17 16:08 27118

[原创] ELF文件结构详解

2019-11-17 16:08
27118

博客:www.wireghost.cn

Elf文件有2个平行视角:一个是程序链接角度,一个是程序装载角度。从链接的角度来看,Elf文件是按“Section”(节)的形式存储;而在装载的角度上,Elf文件又可以按“Segment”(段)来划分。实际上,Section和Segment难以从中文的翻译上加以区分。因为很多时候Section也被翻译成段,比如Section Header Table,有的资料叫段表、有的称为节区。后面在讲解时,就不对其加以区分。。

链接分为2种方式:一种是静态链接、一种是动态链接。
静态链接是在编译链接时直接将需要执行的代码拷贝到调用处;动态链接则是在编译的时候不直接拷贝可执行代码,而是通过记录一系列符号和参数,在程序运行或加载时将这些信息传递给操作系统,由系统负责将所需的动态库加载到内存,然后当程序运行到指定的代码时,去共享执行内存中已经加载的动态库可执行代码,最终达到运行时链接的目的。
程序是静态链接还是动态链接,由编译器的链接参数指定。具体来说,在Android上用C++进行ndk编程时,可以通过设置Application.mk的相关内容,将相应的运行库作为动态库或静态库。

为了方便自己学习和记忆,编写了一个例子so。这里我仅贴了部分代码,用于后面的分析与测试。

在介绍Elf文件格式前,先看看Elf文件中用到的数据类型:

Elf文件头描述了整个文件基本属性,如段表偏移、程序头部偏移等重要信息。它的定义如下:


前面有提过,Elf文件链接时是以Section的形式进行存储。其中,节区头部(段表)就是保存这些Section基本属性的结构。它描述了Elf中各个节的信息,比如每个节的名称、长度、在文件中的偏移、读写权限及其他属性,是一个以Elf32_Shdr结构体为元素的数组,而这个结构体又被称为段描述符。
因为sh_name是在段表字符串表中的索引,所以实际在解析时需要先定位到.shstrtab表,该表是专门用来存放Section名称的字符串表。而它对应的描述符在段表数组中的下标,则在Elf文件头中有给出,通常都是最后一个下标。在拿到节区名称后,再通过sh_offset、sh_size确定每一个节区在文件中的位置与长度。
最后,用readelf命令来查看下目标文件中的段,对照相应输出来分析确认段表结构(PS:段表数组中,第一个元素总是无效的描述符,全部为0)

.text代码段中保存程序指令,具体可以去查看arm、thumb指令集的opcode。。

".rodata"段存放的是只读数据,一般是程序里的只读变量(如const修饰的变量)和字符串常量;".data"段保存的是已经初始化的全局静态变量和局部静态变量。
PS:有时候编译器会把字符串常量放到".data"段,而不是单独放到".rodata"只读数据段。

.bss段中存放的是未初始化的全局变量和局部静态变量,这个Section在Elf文件中没有被分配空间。。

在声明一个函数或变量时,可以加上attribute((section("自定义section名")))前缀的方式,将其添加到自定义段。

Elf文件中用到的字符串,如段名、函数名、变量名称等,均保存在字符串表中。其中,shstrtab段表字符串表仅用来保存段名,而strtab或dynstr section则是存放普通字符串,如函数、变量名等符号名称,字符串之间以"00"截断。。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 13
支持
分享
最新回复 (10)
雪    币: 12502
活跃值: (3053)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
很赞,尤其是重定位部分,如果能把解析符号部分讲一下就更好了。就是 hash,dynstr,symtab这些的配合关系,这些也是很重要的内容。
2019-11-17 19:09
0
雪    币: 545
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
先收藏了,谢谢分享
2019-11-18 15:29
0
雪    币: 1380
活跃值: (1626)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
4
很喜欢你画的图,用什么工具画的啊,截图也那么漂亮
2019-11-19 11:29
0
雪    币: 4764
活跃值: (1770)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
楼主有源码不,新手求工程源码
2019-11-20 12:16
0
雪    币: 14865
活跃值: (6088)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
详细。
lz应该写个相关工具
2019-11-20 14:15
0
雪    币: 5
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
优秀
2019-11-23 19:30
0
雪    币: 28
活跃值: (125)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
大佬。二进制每次启动的时候,got全局偏移表在内存中相对于二进制程序的基地址的偏移是固定的嘛
2020-6-12 13:27
0
雪    币: 178
活跃值: (1306)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
感谢分享
2022-1-18 16:14
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
10
NB
sossai前辈
我最近托人在打听你联系方式
我在这学习这个方面
如果可以请赐教一二
2023-9-20 18:29
0
雪    币: 116
活跃值: (1012)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
如听仙乐耳暂明
2023-9-21 20:23
0
游客
登录 | 注册 方可回帖
返回
//