3
#include<stdio.h>
#include<stdlib.h>

char code[] ="\x52\x56\x57\x50\xB8\x41\x00\x00\x00\x50\xB8\x01\x00\x00\x00\xBF\x01\x00\x00\x00\x48\x89\xE6\xBA\x01\x00\x00\x00\x0F\x05\x58\x58\x5F\x5E\x5A\xC3";

int main(){
    void(*func)() = (void (*)())code;
    (*func)();
    return 0 ;
    
}

what I have here is a string which stores a binary code to print a character ('A') , I pass it as a function pointer to func , than i try to execute it . the output :

$ ./test
Segmentation fault (core dumped)

this is the assembly code :

0:  52                      push   rdx
1:  56                      push   rsi
2:  57                      push   rdi
3:  50                      push   rax
4:  b8 41 00 00 00          mov    eax,0x41
9:  50                      push   rax
a:  b8 01 00 00 00          mov    eax,0x1
f:  bf 01 00 00 00          mov    edi,0x1
14: 48 89 e6                mov    rsi,rsp
17: ba 01 00 00 00          mov    edx,0x1
1c: 0f 05                   syscall
1e: 58                      pop    rax
1f: 58                      pop    rax
20: 5f                      pop    rdi
21: 5e                      pop    rsi
22: 5a                      pop    rdx
23: c3                      ret
Ross Ridge
  • 38,414
  • 7
  • 81
  • 112
  • 5
    Data is not executable by default. – Jester Oct 07 '20 at 16:03
  • 5
    You probbaly don't have execute permission for the data segment. – Weather Vane Oct 07 '20 at 16:03
  • 3
    You can try `gcc -z execstack`. – Jester Oct 07 '20 at 16:05
  • 4
    This is operating system specific. For Linux, see [syscalls(2)](https://man7.org/linux/man-pages/man2/syscalls.2.html), notably [mmap(2)](https://man7.org/linux/man-pages/man2/mmap.2.html), [mprotect(2)](https://man7.org/linux/man-pages/man2/mprotect.2.html), [execve(2)](https://man7.org/linux/man-pages/man2/execve.2.html) also see [pmap(1)](https://man7.org/linux/man-pages/man1/pmap.1.html) and [proc(5)](https://man7.org/linux/man-pages/man5/proc.5.html) and of course read [*Advanced Linux Programming*](https://mentorembedded.github.io/advancedlinuxprogramming/). – Basile Starynkevitch Oct 07 '20 at 16:05
  • thank you all , the ``gcc -z execstack`` solved the problem for me – herzallah aymen Oct 07 '20 at 16:08
  • 1
    Don't forget to read the documentation of [GCC](http://gcc.gnu.org/) and of [binutils](https://www.gnu.org/software/binutils/) – Basile Starynkevitch Oct 07 '20 at 16:08

1 Answers1

6

As pointed out by @WeatherVane, you need permission to execute a data segment, mprotect can help:

#include <stdio.h>
#include <sys/mman.h>
#include <stdint.h>

static char code[] = "\x52\x56\x57\x50\xB8\x41\x00\x00\x00\x50\xB8\x01\x00\x00"
                     "\x00\xBF\x01\x00\x00\x00\x48\x89\xE6\xBA\x01\x00\x00\x00"
                     "\x0F\x05\x58\x58\x5F\x5E\x5A\xC3";
                                 
int main(void)
{
    uintptr_t page = (uintptr_t)code & -4095ULL;

    mprotect((void *)page, 4096, PROT_READ | PROT_EXEC | PROT_WRITE);

    void (*func)(void) = (void (*)(void))code;

    func();
    return 0;
}

You can see the result (A) in godbolt

David Ranieri
  • 39,972
  • 7
  • 52
  • 94