Suppose the binary is PIC, how can I load it into memory and execute the entry point?
I'm doing this to get familiar with ELF so execve is not allowed.
1 Answer
These are the basic steps:
- Read the program headers to find the LOAD directives and determine the total length of mappings you'll need, in pages.
- Map the lowest-address LOAD directive with the total length (which may be greater than the file length), letting
mmapassign you an address. This will reserve contiguous virtual address space. - Map the remining LOAD directives over top of parts of this mapping using
MAP_FIXED. - Use the program headers to find the
DYNAMICvector, which will in turn give you the address of the relocation vector(s). - Apply the relocations. Assuming your binary was a static-linked PIE binary, they should consist entirely of
RELATIVErelocations (just adding the base load address), meaning you don't have to perform any symbol lookups or anything fancy. Construct an ELF program entry stack consisting of the following sequence of system-word-sized values in an array on the stack:
ARGC ARGV[0] ARGV[1] ... ARGV[ARGC-1] 0 ENVIRON[0] ENVIRON[1] ... ENVIRON[N] 0 0(This step requires ASM!) Point the stack pointer at the beginning of this array and jump to the loaded program's entry point address (which can be found in the program headers).
12 Comments
Random832
Er, I thought the point of it being position independent code is it doesn't have relocations - it has global offset table or whatever.
Je Rog
@Random832 ,will I still be able to implement a loader and execute the binary if it's not PIC in the first place?
R.. GitHub STOP HELPING ICE
@Random832: You always have the potential for data relocations. How else could
static int x, *y=&x; work? And of course the GOT is full of relocations. The only way to avoid having any relocations is to avoid having any global data.ninjalj
@R..: I don't think a statically-linked non-PIE executable needs any relocation.
ninjalj
@R..: you should also pass the
auxv array to the program. |
mainfunction.