我正在尝试学习 ELF 格式并正在实现一个 ELF 解析器。到目前为止,我已经实现了 ELF 标头解析器,并且正在解析段,特别是
.text
段。由于以下原因,我被困在这里:
当我构建 go 二进制文件时,具有
LOAD
类型的程序头具有可读和可执行标志(据我理解,它指向 .text
段,其 p_offset 为 0)。这必须意味着整个文件是可读且可执行的(因为 p_filesz
几乎与二进制文件的大小相同。)
当我编译 C 或 Rust 程序时,问题不存在,并且
p_offset
字段已正确设置为非零值。
我不想使用节信息来解析 go 二进制文件中的
.text
段,因为它与剥离的所有节信息一起工作,所以我一定错过了一些东西。
简而言之,如何在具有可读和可执行标志的可加载程序头中找到
.text
值为 0 的 ELF 二进制文件中的 p_offset
段。
此外,这是我正在使用的 go 二进制文件的删节版
readelf
转储:
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040
0x0000000000000150 0x0000000000000150 R 0x1000
NOTE 0x0000000000000f9c 0x0000000000400f9c 0x0000000000400f9c
0x0000000000000064 0x0000000000000064 R 0x4
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x000000000007adfa 0x000000000007adfa R E 0x1000
谢谢!
我尝试阅读 System V ELF 规范、x86-64 补充,尝试查找有关此主题的文章并向 ChatGPT 和 Bard 寻求帮助。
简而言之,如何在具有可读和可执行标志的可加载程序头中找到 p_offset 值为 0 的 ELF 二进制文件中的 .text 段。
有not
.text
部分——它根本不存在(.text
部分存在,但你对它不感兴趣)。
相反,多个部分被分组在一起,并被
LOAD
部分“覆盖”。
当我构建 go 二进制文件时,具有
类型的程序头具有可读和可执行标志(据我理解,它指向LOAD
段,其.text
为 0)。这必须意味着整个文件是可读且可执行的(因为p_offset
几乎与二进制文件的大小相同。)p_filesz
是的,就是这个意思,而且这“没有什么问题”。链接器选择将所有内容放入一个段中(您可以在 readelf -Wl a.out
输出中看到段到段的映射)。