Why are you giving Segmentation fault in my Assembly inline?

Asked

Viewed 315 times

7

I’m trying to call the job execve("bin/sh"...) using Assembly, but in instruction: mov %rsi,0x8(%rsi) i carry 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"


);
}
  • 3

    This question seems to be out of date because it is in English.

  • 1

    malz, first question here, and here it is in English, guenta aê

  • I’m looking for the code in question and I can’t find it in the article. Where it comes from? Smashing The Stack For Fun And Profit - Aleph One

  • is between pages 14 and 15, I changed here and there since my processor is 64 Bits, by the way, your explanation was good but I already knew this part of the protected memory, I know I can not execute code outside the .text. I did not formulate well my question, I wonder how I can fix this without altering the permissions. Anyway, thank you so much for your help.

2 answers

2


First a little theory:

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

At the bottom of the process memory (there next to the address 0xffffffffffffffff) is the beginning of the stack. This one grows up and there’s the stack pointer pointing to its top. To make the stack grow just decrease that pointer.

I will describe the execution of the code step by step:

  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 nonwritable (code) page. And the operating system will stop you from doing that by killing your lawsuit for trying something illegal. The solution would 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 function mprotect, and on Windows, VirtualProtect.

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’ve helped.

  • Specifying the suffix is not necessary in this case. (In the question it states that the problem is in execution, the code compiles.) "If the suffix is not specified, and there are no memory operands for the Instruction, GAS infers the operand size from the size of the Destination Register operand (the final operand)." (Wikibooks)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.