前言
最近在研究嵌入式系统下的动态链接库,接触到ELF解析相关的代码。基于实用主义的思想,决定给广大程序员朋友分享下ELF的分析和解析细节。基于维基百科的描述:ELF(Executable and Linkable Format)是linux下的目标文件,包含可执行文件,可链接文件,core dump文件等。本文后面基于xtensa平台下的目标文件来分析ELF,和其他平台下是一致的。
工具介绍
工欲善其事,必先利其器。 我这里选择两种工具供大家来参考分析,大家可以看自己的喜好来选择。
- 图形化工具
首推开源图形化工具:XELFViewer
GitHub - horsicq/XELFViewer: ELF file viewer/editor for Windows, Linux and MacOS.
- 编译器工具
bin | description |
xt-readelf | 分析ELF的主要工具 |
xt-objdump | 辅助readelf来分析目标文件的反汇编和机器码内容等 |
ELF结构
要想了解ELF的结构,只需要知道主要的三个部分:ELF文件的header,Program header和section header;在32bit的ELF中,对应如下的三个数据结构:
ELF解析
咱们通过XELFViewer这个图形化工具来分析上面提到的三个部分
- ELF文件header解析
- Program header
从上面的elf header图示里面的e_phoff和e_phnum这两个变量我们可以找到program header的起始地址(0x34)和数量(a),便可以找到从相对于文件偏移的0x34开始的10个program header的结构,如下图所示:
Name | value | description |
p_type | 1 | PT_LOAD 表示可以加载的 |
p_offset | 0x180 | 表示这个program header所表示的段在文件的偏移 |
p_vaddr | 0x00000000 | 虚拟地址 |
p_paddr | 0x00000000 | 物理地址 |
p_filesz | 0x4ab | 文件系统中的大小 |
p_memsz | 0x4ab | 内存中的大小 |
p_flags | 0x5 | 0x1(X可执行),0x2(可写),0x4(可读) |
p_align | 0x80 | 对齐大小 |
- Section header
从上面的elf header图示里面的e_shoff和e_shnum这两个变量我们可以找到section header的起始地址(0x1434)和数量(0x12),便可以找到从相对于文件偏移的0x1434开始的18个section header的结构,如下图所示:
结语
通过以上的分析已经program和section两个部分的对比,我们就可以很看出program header指示的部分和section header指示的部分其实是重叠的,section是编译器视角,而program是程序加载执行视角。他们之间的关系可以通过下面的图示表现出来。