Search code examples
csecurityshellcode

Executing machine code in an array in C. Is this executing an Integer?


I am trying to understand why ret(); works in the following C program:

#include<stdio.h>
#include<string.h>

unsigned char code[] = \
"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69"
"\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80";

main()
{
    printf("Shellcode Length:  %d\n", strlen(code));
    int (*ret)() = (int(*)())code;
    ret();
}

In order for this to work you must compile the above with no stack protections, allowing the stack to be executable.

What I'm wondering though is why calling ret();, which appears to be an integer assigned to the value (int(*)())code; works.

I am guessing it has something to do with function pointers really being integers, but I have not been able to mentally unpack the meaning of the expression int (*ret)() = (int(*)())code;

Thank you for your help


Solution

  • What I'm wondering though is why calling ret(), which appears to be an integer assigned to the value (int(*)())code works

    ret is not an integer, it is a pointer to a function returning an integer. The "inline" syntax, i.e. int (*ret)() is harder to "decipher" than an equivalent typedef, i.e.

    typedef int (*func_returning_int)();
    ...
    func_returning_int ret = (func_returning_int)code;
    

    Note: It goes without saying that this is undefined behavior regardless of the way you go about casting pointers.