如何计算ELF32程序头中p_offset的值?

时间:2014-07-02 08:16:44

标签: gcc elf sections memory-segmentation

我想在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

鉴于此示例,我有以下问题:

  1. 如何计算给定细分的正确p_offset值?首先计算p_offset是如何计算的?

  2. 为什么第二个LOAD段与p_align值不对齐?具体来说,为什么它从0x08049f08而不是0x08049000开始?

  3. 为什么p_offset不小于0xf08,因为ELF文件中位于其前面的eh_frame部分以偏移0x56C结尾且文件具有此部分与从init_array开始的下一个(0xf08)之间的2460个零字节?为什么这些部分之间有2460个零字节?

0 个答案:

没有答案