0

Is it possible changing few bytes for converting an elf binary from PIE to No-PIE (ELF)? I know that in the header if e_type is: - 3 then the program is PIE - 2 then the program is No-PIE

So I tried to change that byte and in fact readelf -h shows me:

ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x630
  Start of program headers:          64 (bytes into file)
  Start of section headers:          6576 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         9
  Size of section headers:           64 (bytes)
  Number of section headers:         29
  Section header string table index: 28

Then I changed the e_entry from 0x630 to 0x400630.

readelf -h output:

ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x400630
  Start of program headers:          64 (bytes into file)
  Start of section headers:          6576 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         9
  Size of section headers:           64 (bytes)
  Number of section headers:         29
  Section header string table index: 28

However if I try to launch the program it crashes.

$ strace ./elf-patched.exe 
execve("./elf-patched.exe", ["./elf-patched.exe"], 0x7ffe0c2b88c0 /* 66 vars */) = -1 EPERM (Operation not permitted)
+++ killed by SIGSEGV +++
[1]    7239 segmentation fault (core dumped)  strace ./elf-patched.exe

What other bytes should I change (If it's possible with few modifications) ?

3
  • 1
    Hi and welcome to RE.SE. What are you trying to achieve? And please don't repeat your question. I am looking for the reason you want to do that conversion in the first place. With some more context it's well possible there are other routes available to achieve your actual goal.
    – 0xC0000022L
    Commented Dec 13, 2019 at 20:04
  • My actual goal is to pwn the binary with a ROP chain, however I need the binary to be No-PIE to make the ROP chain works.
    – meowmeowxw
    Commented Dec 16, 2019 at 8:30
  • That is, you need "deterministic" addresses that you can hardcode?
    – 0xC0000022L
    Commented Dec 16, 2019 at 8:56

1 Answer 1

1

It is not possible with few modifications.

https://www2.cs.arizona.edu/~debray/Publications/disasm.pdf

2.2 Position-Independent Code

Many compilers can be instructed to emit code that does not rely on being bound to any particular position in the program’s address space. These code sequences are often referred to as position-independent code(PIC). In particular, PIC sequences do not contain any relocatable addresses embedded in the instructions. This property enables the code to work regardless of its memory location at runtime. Furthermore, PIC does not need to be patched by the loader, enabling it to be mapped as read-only data—which is useful for shared code such as dynamically linked libraries [14]. When a compiler is emitting position-independent code it typically creates jump tables that are also position-independent. These tables are usually embedded in the text segment of the executable and consist of a sequence of offsets rather than virtual addresses. A jump that uses the offset table first loads a nearby address,1 then uses this to index into the table and retrieve an offset. The offset is added to the address that was previously loaded and then used in an indirect jump to reach the desired destination. The problems posed by position-independent jump tables are three-fold: (i) the offset tables, which are really no different than data, appear in the instruction stream; (ii) the code sequences that perform the indirect jumps are often complicated and may not adhere to a single pattern that is easily recognizable; and (iii) it is entirely possible that an offset table does not contain relocation entries. Taken together,these properties make the task of disassembling PIC sequences involving jump tables more difficult than standard code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.