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
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.