ELF文件解析(一):Segment和Section
ELF 是Executable and Linking Format的缩写,即可执行和可链接的格式,是Unix/Linux系统ABI (Application Binary Interface)规范的一部分。
Unix/Linux下的可执行二进制文件、目标代码文件、共享库文件和core dump文件都属于ELF文件。
下面的图来自于文档 Executable and Linkable Format (ELF),描述了ELF文件的大致布局。

左边是ELF的链接视图,可以理解为是目标代码文件的内容布局。右边是ELF的执行视图,可以理解为可执行文件的内容布局。
注意目标代码文件的内容是由section组成的,而可执行文件的内容是由segment组成的。
要注意区分段(segment)和节(section)的概念,这两个概念在后面会经常提到。
我们写汇编程序时,用.text,.bss,.data这些指示,都指的是section,比如.text,告诉汇编器后面的代码放入.text section中。
目标代码文件中的section和section header table中的条目是一一对应的。section的信息用于链接器对代码重定位。
而文件载入内存执行时,是以segment组织的,每个segment对应ELF文件中program header table中的一个条目,用来建立可执行文件的进程映像。
比如我们通常说的,代码段、数据段是segment,目标代码中的section会被链接器组织到可执行文件的各个segment中。
.text section的内容会组装到代码段中,.data, .bss等节的内容会包含在数据段中。
在目标文件中,program header不是必须的,我们用gcc生成的目标文件也不包含program header。
一个好用的解析ELF文件的工具是readelf。对我本机上的一个目标代码文件sleep.o执行readelf -S sleep.o,输出如下:
There are 12 section headers, starting at offset 0x270:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .text PROGBITS 0000000000000000 00000040
0000000000000015 0000000000000000 AX 0 0 1
[ 2] .rela.text RELA 0000000000000000 000001e0
0000000000000018 0000000000000018 I 9 1 8
[ 3] .data PROGBITS 0000000000000000 00000055
0000000000000000 0000000000000000 WA 0 0 1
[ 4] .bss NOBITS 0000000000000000 00000055
0000000000000000 0000000000000000 WA 0 0 1
... ... ... ...
[11] .shstrtab STRTAB 0000000000000000 00000210
0000000000000059 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
l (large), p (processor specific)
readelf -S是显示文件中的Section信息,sleep.o中共有12个section, 我们省略了其中一些Section的信息。
可以看到,除了我们熟悉的.text, .data, .bss,还有其它Section,这等我们以后展开讲Section的时候还会专门讲到。
看每个Section的Flags我们也可以得到一些信息,比如.text section的Flags是AX,表示要分配内存,并且是可执行的,这一节是代码无疑了。
.data 和 .bss的Flags的Flags都是WA,表示可写,需分配内存,这都是数据段的特征。
使用readelf -l可以显示文件的program header信息。我们对sleep.o执行readelf -l sleep.o。会输出There are no program headers in this file.。
program header和文件中的segment一一对应,因为目标代码文件中没有segment,program header也就没有必要了。
可执行文件的内容组织成segment,因此program header table是必须的。
section header不是必须的,但没有strip过的二进制文件中都含有此信息。
对本地可执行文件sleep执行readelf -l sleep,输出如下:
Elf file type is DYN (Shared object file)
Entry point 0x1040
There are 11 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000000040 0x0000000000000040
0x0000000000000268 0x0000000000000268 R 0x8
INTERP 0x00000000000002a8 0x00000000000002a8 0x00000000000002a8
0x000000000000001c 0x000000000000001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000560 0x0000000000000560 R 0x1000
LOAD 0x0000000000001000 0x0000000000001000 0x0000000000001000
0x00000000000001d5 0x00000000000001d5 R E 0x1000
LOAD 0x0000000000002000 0x0000000000002000 0x0000000000002000
0x0000000000000110 0x0000000000000110 R 0x1000
LOAD 0x0000000000002de8 0x0000000000003de8 0x0000000000003de8
0x0000000000000248 0x0000000000000250 RW 0x1000
DYNAMIC 0x0000000000002df8 0x0000000000003df8 0x0000000000003df8
0x00000000000001e0 0x00000000000001e0 RW 0x8
NOTE 0x00000000000002c4 0x00000000000002c4 0x00000000000002c4
0x0000000000000044 0x0000000000000044 R 0x4
GNU_EH_FRAME 0x0000000000002004 0x0000000000002004 0x0000000000002004
0x0000000000000034 0x0000000000000034 R 0x4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 0x10
GNU_RELRO 0x0000000000002de8 0x0000000000003de8 0x0000000000003de8
0x0000000000000218 0x0000000000000218 R 0x1
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt
03 .init .plt .text .fini
04 .rodata .eh_frame_hdr .eh_frame
05 .init_array .fini_array .dynamic .got .got.plt .data .bss
06 .dynamic
07 .note.ABI-tag .note.gnu.build-id
08 .eh_frame_hdr
09
10 .init_array .fini_array .dynamic .got
如输出所示,文件中共有11个segment。只有类型为LOAD的段是运行时真正需要的。
除了段信息,还输出了每个段包含了哪些section。比如第二个LOAD段标志为R(只读)E(可执行)的,它的编号是03,表示它包含哪些section的那一行内容为:
03 .init .plt .text .fini。
可以发现.text包含在其中,这一段就是代码段。
再比如第三个LOAD段,索引是04,标志为R(只读),但没有可执行的属性,它包含的section有.rodata .eh_frame_hdr .eh_frame,其中rodata表示只读的数据,也就是程序中用到的字符串常量等。
最后一个LOAD段,索引05,标志RW(可读写),它包含的节是.init_array .fini_array .dynamic .got .got.plt .data .bss,可以看到.data和.bss都包含其中,这段是数据段无疑。
今天先讲到这里,后面的内容这样组织:
- 首先讲一下Elf文件的header,因为文件一开始几十个字节就是Elf header的数据,这个数据结构包含了很多信息,还能告诉我们program header table, section header table在文件中什么位置。
- 接下来会讲一下如何解读section header table,以及section的数据如何组织的。
- 然后会讲program header table,以及segment的数据组织。section是如何组织成段的,这一点我们也要弄请求。
- 最后我们会讲程序如果被loader加载到内存中,生成进程映像的。
欢迎继续关注。
ELF文件解析(一):Segment和Section的更多相关文章
- ELF文件解析(二):ELF header详解
上一篇讲了ELF文件的总体布局,以及section和segment的概念.按照计划,今天继续讲 ELF header. 讲新的内容之前,先更正一个错误:上一篇中讲section header tabl ...
- Android ELF文件解析
0X01 ELF初认识 elf文件是linux下的二进制文件,相当于windows下的PE文件,Android系统里的dll. 解析elf文件两个用处:1.so加固:2.frida(xposed)检 ...
- ELF文件解析器支持x86x64ELF文件
此文为静态分析ELF文件结构,遍历其中Elf_Ehdr文件头信息,遍历Elf_Shdr节表头信息,并将所有节放置在左侧树控件上,遍历Elf_Phdr程序头也放置在左侧树控件上,并着重分析字符串表,重定 ...
- python3 elf文件解析
原地址:https://github.com/guanchao/elfParser 作者是用python2写的,现在给出我修改后的python3版本.(测试发现有bug,以后自己写个,0.0) 1 # ...
- segment and section for c++ elf
http://blog.csdn.net/jiafu1115/article/details/12992497 写一个汇编程序保存成文本文件max.s. 汇编器读取这个文本文件转换成目标文件max.o ...
- bin文件和elf文件
ELF文件格式是一个开放标准,各种UNIX系统的可执行文件都采用ELF格式,它有三种不同的类型: 可重定位的目标文件(Relocatable,或者Object File) 可执行文件(Executab ...
- Linux之ELF文件初探
对比windowsPE文件与概述 在windows中可执行文件是pe文件格式,Linux中可执行文件是ELF文件,其文件格式是ELF文件格式,在Linux下的ELF文件除了可执行文件(Excutabl ...
- ELF Format 笔记(三)—— Section Types
ilocker:关注 Android 安全(新入行,0基础) QQ: 2597294287 ELF 文件中会包含很多 section,所有的 section 都在 section header tab ...
- ELF文件中section与segment的区别
http://blog.csdn.net/joker0910/article/details/7655606 1. ELF中的section主要提供给Linker使用, 而segment提供给Load ...
随机推荐
- App WebView实例化
a,高级设置里的环境变量 jdk的配置 b,下载Google的sdk,里面直接包含eclipse 1,新建一个项目 2,起个名字 3,设么走不做,next 4,只操作选择显示的三种方式 5,next什 ...
- python中Switch/Case实现
学习Python过程中,发现没有switch-case,过去写C习惯用Switch/Case语句,官方文档说通过if-elif实现.所以不妨自己来实现Switch/Case功能. 方法一 通过字典实现 ...
- Oracle数据库导入导出 imp/exp备份还原
Oracle数据导入导出imp/exp Oracle数据导入导出imp/exp 在cmd的dos命令提示符下执行,而不是在sqlplus里面,但是格式一定要类似于: imp/exp 用户名/密 ...
- BZOJ2733[HNOI2012]永无乡——线段树合并+并查集+启发式合并
题目描述 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达 ...
- java访问权限表
private(私有的) 默认的(什么都不写) protected(受保护的) public(公共的 ) 同一个类中 yes yes yes yes 同一个包中不同类之间 no yes yes ...
- vs2017 C4996 错误
严重性 代码 说明 项目 文件 行 禁止显示状态错误 C4996 'strcpy': This function or variable may be ...
- 洛谷P3959 宝藏(NOIP2017)(状压DP,子集DP)
洛谷题目传送门 Dalao的题解多数是什么模拟退火.DFS剪枝.\(O(3^nn^2)\)的状压DP之类.蒟蒻尝试着把状压改进了一下使复杂度降到\(O(3^nn)\). 考虑到每条边的贡献跟它所在的层 ...
- ioi2018集训队自选题:最短路练习题
题意:链接 定义pos[i]表示i这个值在数组里的下标. 我们先用单调栈找到每个元素左边和右边第一个比它大的元素$l_i$和$r_i$,然后建一棵二叉树,我们就叫做maxtree吧 (upd:mdzz ...
- A1090. Highest Price in Supply Chain
A supply chain is a network of retailers(零售商), distributors(经销商), and suppliers(供应商)-- everyone invo ...
- caffe 错误
一些caffe错误 训练时很快梯度爆炸,loss猛增至nan 如果找不到数据上的原因的话,可以怀疑caffe框架有问题,换用其它版本试试.比如我遇到的问题是在训练时使用了Accuracy层,而该层的实 ...