如何使用hexdump正确查看ELF文件的程序头、段头等结构?
ELF二进制结构手动定位指南
我正在学习elf文件布局,目前在阅读Executable_and_Linkable_Format相关文档。
最初我用readelf -a查看elf(.o目标文件),但该工具输出的是解析后的结构化结果,不是我需要的原始二进制内容,因此我改用hexdump -C查看文件的原始二进制形态。
我通过以下流程生成测试用ELF文件:
- 用
as -Og -g ... -o ...命令执行汇编 - 用
ld ... -o ...命令执行链接 - 最终用
hexdump -C ...命令查看生成文件的二进制内容
使用的示例汇编代码如下:
.section .data iary: .int 1, 2 lary: .long 3, 4 .section .text .globl _start _start: movq $0, %rdi leaq iary(, %rdi, 4), %rbx movl iary(, %rdi, 4), %ecx movq $1, %rdi leaq iary(, %rdi, 4), %rbx movl iary(, %rdi, 4), %ecx #=============================== movq $0, %rdi leaq lary(, %rdi, 4), %rbx movl lary(, %rdi, 4), %ecx movq $1, %rdi leaq lary(, %rdi, 4), %rbx movl lary(, %rdi, 4), %ecx movq $60, %rax syscall
我的目标是在hexdump输出中定位program header(程序头)、section header(段头/节头)等核心ELF结构,不确定当前使用的查找方法是否正确。
相关hexdump输出截图:
待解答的问题对应截图:
正确定位方法
不需要靠内容特征猜结构位置,直接从ELF头的固定偏移读指针即可,64位ELF头的字段偏移是标准固定的:
- 第一步先校验魔数:文件起始位置的4字节必须是
7f 45 4c 46(对应ASCII字符\x7fELF),你提供的截图开头可以直接看到该值,说明hexdump的偏移对齐没有错误。 - 定位程序头表:从文件起始位置算,偏移
0x20处的8字节无符号整数是程序头表的文件起始偏移;偏移0x36处的2字节无符号整数是单个程序头表项的长度,偏移0x38处的2字节无符号整数是程序头表的总项数。注意:.o格式的可重定位目标文件本身不需要程序头(程序头供系统加载器使用,仅可执行文件、共享库会填充该表),这个位置的值为0是正常情况,不需要刻意查找。 - 定位节头表(段头表):从文件起始位置算,偏移
0x28处的8字节无符号整数是节头表的文件起始偏移;偏移0x3a处的2字节无符号整数是单个节头表项的长度,偏移0x3c处的2字节无符号整数是节头表的总项数,偏移0x3e处的2字节是节名字符串表对应的节头索引,用来解析各个节的名称。
直接按照ELF头中读出的偏移跳转,就能找到对应结构的起始位置,连续排列的等长结构体数组就是对应表项,不需要靠猜内容匹配。
校验方法很简单:用readelf -h输出的ELF头字段值,和你在hexdump对应偏移手动读出的值做对比,完全一致就说明定位正确。
内容的提问来源于stack exchange,提问作者OnlyWick
相关产品推荐
相关产品推荐

