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:
How does one calculate the correct
p_offset
values for a given segment? How was thep_offset
calculated in the first place?Why is the second LOAD segment not aligned with respect to its
p_align
value? Specifically, why does it start at0x08049f08
instead of0x08049000
?Why is the
p_offset
not smaller than0xf08
, because theeh_frame
section that precedes it inside the ELF file ends at offset0x56C
and the file has 2460 zero bytes between this section and the next one (init_array
) which starts at0xf08
? Why are there 2460 zero bytes between these sections anyway?