我正在尝试理解ELF格式,目前我对程序头中定义的段有些疑问。我有一小段代码,用g++(在Linux上的x86_x64)将其转换为ELF文件:
#include <stdlib.h>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
if (argc == 1)
{
cout << "Hello world!" << endl;
}
return 0;
}
使用命令 g++ -c -m64 -D ACIS64 main.cpp -o main.o
和 g++ -s -O1 -o Main main.o
编译。
现在,使用readelf命令获取以下段的列表:
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040
0x00000000000001f8 0x00000000000001f8 R E 8
INTERP 0x0000000000000238 0x0000000000400238 0x0000000000400238
0x000000000000001c 0x000000000000001c R 1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x0000000000000afc 0x0000000000000afc R E 200000
LOAD 0x0000000000000df8 0x0000000000600df8 0x0000000000600df8
0x0000000000000270 0x00000000000003a0 RW 200000
DYNAMIC 0x0000000000000e18 0x0000000000600e18 0x0000000000600e18
0x00000000000001e0 0x00000000000001e0 RW 8
NOTE 0x0000000000000254 0x0000000000400254 0x0000000000400254
0x0000000000000044 0x0000000000000044 R 4
GNU_EH_FRAME 0x00000000000009a4 0x00000000004009a4 0x00000000004009a4
0x0000000000000044 0x0000000000000044 R 4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 10
GNU_RELRO 0x0000000000000df8 0x0000000000600df8 0x0000000000600df8
0x0000000000000208 0x0000000000000208 R 1
通过Bless Hex Editor,我正在查看代码并尝试找到每个片段。
我在ELF头之后找到了PHDR段,并且它有整个程序头的大小。它具有8字节的对齐方式,并且可读/可执行。[!] 我不明白为什么可执行。
我找到了解释器声明的段,就在PHDR之后。它具有解释器路径的大小和1字节的对齐方式。正确
现在我有了一个可读和可执行的段,[!]我认为这是代码段。我不明白为什么它从0x0000000000000000开始。难道这不应该从入口点开始吗?为什么它的大小是0xafc字节?文件的可执行部分有多少?另外,我不明白为什么对齐方式是0x200000字节。这是为一个在内存中保留的LOAD段预留的空间吗? 这就是这个段的结束位置,之后跟着764个
0x0
字节:
- 下一个(可读/可写)的[!]我认为是存储变量的段。它在某个类似于部分标头开始的地方结束。
- 现在下一个是动态头部。它从上面那个里面开始,位置是0xe18。[!]我认为这是一个存储对外部函数和变量引用的段,但我不确定。它可读/可写。我不知道这个段是什么以及为什么它“在”上面的LOAD段内
- 一个NOTE段,包含一些我认为现在不重要的信息
- GNU特定段,其中一个偏移和大小都等于
0x0000000000000000
,其他干扰其他段,我也不理解。
我来自PE世界,在那里每件事都有自己定义良好的偏移量和大小,而在这里我看到这些奇怪的地址和大小,我感到困惑。