Fun with C / ASM

Hacking around with C and ASM is fun! Here are two blobs of C code useful for future reference:

Use function return to actually call another function via the stored IP:

#include <stdio.h>

register void ** base_pointer  __asm("%rbp");
register void ** stack_pointer __asm("%rsp");

int mycode(void * old_ip) {
    printf("Mycode\n");
    *(base_pointer + 1) = old_ip;
    return 10;
}

int fun() {
    void * old_ip = *(base_pointer + 1);
    *(base_pointer + 1) = mycode;
    stack_pointer = base_pointer;
    __asm("movq %0, %%rdi"::"r"(old_ip));
    return 4;
}

int main() {
    printf("%i\n", fun());
    return 0;
}

Dynamically generate code and execute it:

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

int seven() {
    char * space = mmap(NULL,
                        7,
                        PROT_WRITE | PROT_READ,
                        MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
    // mov 7, %rax; leave; ret
    space[0] = 0xB8;
    space[1] = 0x07;
    space[2] = 0x00;
    space[3] = 0x00;
    space[4] = 0x00;
    space[5] = 0xC9;
    space[6] = 0xC3;
    mprotect(space, 7, PROT_EXEC | PROT_READ);
    goto *space;
}

int main() {
    printf("%i\n", seven());
    return 0;
}

And the buffer overflow version:

#include <stdio.h>

register void ** base_pointer  __asm("%rbp");
register void ** stack_pointer __asm("%rsp");

int mycode(void * old_ip) {
    printf("Mycode\n");
    *(base_pointer + 1) = old_ip;
    return 10;
}

int fun() {
    void * old_ip = *(base_pointer + 1);
    void * buffer[0];
    buffer[1] = mycode;
    stack_pointer       = base_pointer;
    __asm("movq %0, %%rdi"::"r"(old_ip));
    return 4;
}

int main() {
    printf("%i\n", fun());
    return 0;
}

About admin

I am a PhD student at the Software Composition Group, University of Bern.
This entry was posted in C, hacking, virtual machine. Bookmark the permalink.

2 Responses to Fun with C / ASM

  1. Niko Schwarz says:

    I think you need to escape the less than signs with &lt:

  2. admin says:

    Thanks. Fixed ;)

    Also, obviously the binary code that I inlined is X86… I added a comment saying what it does.