Why are you giving segmentation fault in my Assembly inline?

7

I'm trying to call the execve("bin/sh"...) function using assembly, however in the statement: mov %rsi,0x8(%rsi) I get a segmentation error. This is the 64bit version of the article code "smash the stack for fun and profit".

void main()
{

__asm__(
    "jmp caller           \n"

    "jumper:              \n"
    "pop    %rsi          \n"
    "mov    %rsi,0x8(%rsi)\n"
    "xor    %rax,%rax     \n"
    "mov    %rax,0x7(%rsi)\n"
    "mov    %rax,0xc(%rsi)\n"
    "mov    0x3b,%al      \n"

    "mov    %rsi,%rbx     \n"
    "lea    0x8(%rsi),%rcx\n"
    "lea    0xc(%rsi),%rdx\n"
    "syscall              \n"

    "xor    %rbx,%rbx     \n"
    "mov    %rbx,%rax     \n"
    "inc    %rax          \n"
    "syscall              \n"

    "caller:              \n"
    "call jumper          \n"
    ".string \"/bin/sh\"  \n"


);
}
    
asked by anonymous 08.04.2014 / 04:19

2 answers

2

First of all, a little theory:

The memory is divided into pages, each with different access permissions. At the start of the process the code is loaded into a readable and executable (but not writable) part of the memory, at the top. Then enter initialized and uninitialized global variable data (zeroed) and constant data (such as literal strings and floats). After this begins the heap, which has a defined start and grows down.

At the bottom of the process memory (next to the address 0xffffffffffffffff ) is the beginning of the stack. It grows up and there's the stack pointer pointing to its top. To make the stack grow, just decrease this pointer.

I'll describe step-by-step code execution:

  jmp caller       # Pular imediatamente para o label caller.  
caller:
  call jumper      # Escreva o endereço da próxima instrução no topo da stack e
                   # decremente o ponteiro. Em seguida, pule para jumper.
jumper:
  pop %rsi         # Leia o endereço no topo da stack para o registrador RSI e incremente
                   # o ponteiro. Agora RSI (registrador usado nas instruções de iteração
                   # sob strings) contém o endereço de onde o código está.
  mov %rsi, 0x8(%rsi)     # Calcule o endereço RSI+8 e escreva o valor de RSI (um endereço)
                          # essa memória. BUUM! Segmentation Fault
                          # Equivalente em C: *(RSI+8) = (uint64_t)RSI  // RSI é um ponteiro

What happened is simple: You tried to write on a non-writable (code page) page. And the operating system will stop you from doing this, killing your process for trying something illegal. The solution would be to first change the permissions of the pages in question. The way to do this varies from system to system. On Linux you can use the mprotect function, and in Windows, VirtualProtect .

    
08.04.2014 / 16:16
0

To write the instructions in 64 bits it is necessary to use the suffix 'q':

"movq   %rsi,0x8(%rsi)\n"

Except for stack operations (pop, push, call, ret, enter, leave).

I hope I have helped.

    
08.04.2014 / 11:02