1

I want to apply some custom code transformations on ELF32 binaries. First I parse the ELF file, then I apply the transformation(s) and afterwards I put the ELF sections back together in a new output file.

Before I even start implementing any transformations I stumbled upon a problem when writing the ELF sections back to a new binary file, that is: I needed to properly align the sections when I write them to the new ELF. I tried using the value of p_align from the program headers for this purpose, but that is not correct. p_offset seems to be the value which I should use when writing to an ELF file, but I have no clue how it is computed.

To give you an example as to what I mean. I have the following simple C code:

int main(int argc, char* argv[]){
  return 0;
}

I used GCC 4.8.2 to build a 32-bit ELF executable. Then I used readelf -h a.out to print the program headers for this ELF32 binary and got the following output:

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

Given this example, I have the following questions:

  1. How does one calculate the correct p_offset values for a given segment? How was the p_offset calculated in the first place?

  2. Why is the second LOAD segment not aligned with respect to its p_align value? Specifically, why does it start at 0x08049f08 instead of 0x08049000?

  3. Why is the p_offset not smaller than 0xf08, because the eh_frame section that precedes it inside the ELF file ends at offset 0x56C and the file has 2460 zero bytes between this section and the next one (init_array) which starts at 0xf08? Why are there 2460 zero bytes between these sections anyway?

Benny
  • 607
  • 7
  • 20
  • I'm only commenting on _p_align_. I think _p_align_ is largely ignored. _binfmt_elf_ doesn't really use it for anything [link] (https://github.com/torvalds/linux/blob/master/fs/binfmt_elf.c). It may be like _p_paddr_, useful in embedded scenarios but not for virtually addressed cases. – Olsonist Mar 12 '19 at 22:44

0 Answers0