Search code examples
cassemblyexecuteterminateshellcode

Executed shellcode terminates main program


I am trying to execute shellcode in a memory region. While it works so far, I am confronted with another problem right now: The main-c-program exits after I called the shellcode-program. Is there a (simple) way around this other than working with threads?

I think that this has something to do with the mov rax, 60 and the following syscall, exiting the program. Right?

Main-C-Code

#include <string.h>
#include <sys/mman.h>

const char shellcode[] = "\xeb\x1e\xb8\x01\x00\x00\x00\xbf\x01\x00\x00\x00\x5e\xba\x0d\x00\x00\x00\x0f\x05\xb8\x3c\x00\x00\x00\xbf\x00\x00\x00\x00\x0f\x05\xe8\xdd\xff\xff\xff\x48\x65\x6c\x6c\x6f\x2c\x20\x57\x6f\x72\x6c\x64\x21";

// Error checking omitted for expository purposes
int main(int argc, char **argv)
{
  // Allocate some read-write memory
  void *mem = mmap(0, sizeof(shellcode), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);

  // Copy the shellcode into the new memory
  memcpy(mem, shellcode, sizeof(shellcode));

  // Make the memory read-execute
  mprotect(mem, sizeof(shellcode), PROT_READ|PROT_WRITE|PROT_EXEC);

  // Call the shellcode
  void (*func)();
  func = (void (*)())mem;
  (void)(*func)();

  // This text will never appear
  printf("This text never appears");

  // Now, if we managed to return here, it would be prudent to clean up the memory:
  // (I think that this line of code is also never reached)
  munmap(mem, sizeof(shellcode));

  return 0;
}

Basis of the Shellcode (assembler (Intel))

global _start

_start:
    jmp message

code:
    mov     rax, 1
    mov     rdi, 1
    pop     rsi
    mov     rdx, 13
    syscall

    mov    rax, 60
    mov    rdi, 0
    syscall

message:
    call code
    db "Hello, World!"

Solution

  • I actually found it out by myself. If anyone is interested, the simple solution was to alter the assembler-code as follows:

    global _start
    
    _start:
        jmp message
    
    code:
        mov     rax, 1
        mov     rdi, 1
        pop     rsi
        mov     rdx, 13
        syscall
    
        ret        # Instead of "mov.., mov..., syscall"
    
    message:
        call code
        db "Hello, World!"