特定二进制文件的readelf -S
提供以下输出
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .interp PROGBITS 0000000000400238 00000238
000000000000001c 0000000000000000 A 0 0 1
[ 2] .note.ABI-tag NOTE 0000000000400254 00000254
0000000000000020 0000000000000000 A 0 0 4
[ 3] .hash HASH 0000000000400278 00000278
0000000000000a7c 0000000000000004 A 4 0 8
[ 4] .dynsym DYNSYM 0000000000400cf8 00000cf8
.
.
.
第一部分.interp
的虚拟地址与偏移量之间的差为0x400000
。我很好奇:
如何计算?
您只是自己计算了一下:0x400238 - 0x238 == 0x400000
。您的问题可能是“为什么选择此特定地址?”。
这是Linux x86_64
位置从属二进制文件的默认链接地址。您可以使用-Ttext=...
链接器标志更改该地址。对于ix86
(32位)二进制文件,默认值是不同的:它是0x8048000
。
我不确定为什么选择这些特定的默认值。
是否有程序确定的方法?
确定:从文件的开头读取Elf64_Ehdr
。它会告诉您到程序标头(.e_phoff
)开头的偏移量。寻找该偏移量,然后读取Elf64_Phdr
。现在遍历它们,它们的.p_vaddr
和.p_offset
将具有相同的值。
P.S。您正在查看程序sections,这些程序未使用且不能保证存在于完全链接的二进制文件中。您应该正在查看程序段。用readelf -Wl a.out
检查它们。