我想在 ELF32 二进制文件上应用一些自定义代码转换。首先,我解析 ELF 文件,然后应用转换,然后将 ELF 部分重新组合到一个新的输出文件中。
在我开始实施任何转换之前,我在将 ELF 部分写回新的二进制文件时偶然发现了一个问题,即:当我将这些部分写入新的 ELF 时,我需要正确对齐这些部分。p_align
为此,我尝试使用程序头中的值,但这是不正确的。p_offset
似乎是我在写入 ELF 文件时应该使用的值,但我不知道它是如何计算的。
给你一个例子来说明我的意思。我有以下简单的 C 代码:
int main(int argc, char* argv[]){
return 0;
}
我使用 GCC 4.8.2 构建了一个 32 位 ELF 可执行文件。然后我用来readelf -h a.out
打印这个 ELF32 二进制文件的程序头并得到以下输出:
Elf file type is EXEC (Executable file)
Entry point 0x80482f0
There are 9 program headers, starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x08048034 0x08048034 0x00120 0x00120 R E 0x4
INTERP 0x000154 0x08048154 0x08048154 0x00013 0x00013 R 0x1
[Requesting program interpreter: /lib/ld-linux.so.2]
LOAD 0x000000 0x08048000 0x08048000 0x0056c 0x0056c R E 0x1000
LOAD 0x000f08 0x08049f08 0x08049f08 0x00114 0x00118 RW 0x1000
DYNAMIC 0x000f14 0x08049f14 0x08049f14 0x000e8 0x000e8 RW 0x4
NOTE 0x000168 0x08048168 0x08048168 0x00044 0x00044 R 0x4
GNU_EH_FRAME 0x000490 0x08048490 0x08048490 0x0002c 0x0002c R 0x4
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x10
GNU_RELRO 0x000f08 0x08049f08 0x08049f08 0x000f8 0x000f8 R 0x1
鉴于这个例子,我有以下问题:
如何计算
p_offset
给定段的正确值?当初是怎么p_offset
计算的?为什么第二个 LOAD 段没有与其
p_align
值对齐?具体来说,为什么它开始于0x08049f08
而不是0x08049000
?为什么
p_offset
不小于0xf08
,因为在eh_frame
ELF 文件中它前面的部分以偏移量结束,0x56C
并且文件在此部分和下一个 (init_array
) 开始的部分之间有 2460 个零字节0xf08
?为什么这些部分之间有 2460 个零字节呢?