Domanda

I saw this code today in some fb profile, and was not able to understand what is and how this is working:-

(*(void(*)()) shellcode)()

Can someone please explain me, what does above code mean ?

Full Code Snippet Below :-

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

char *shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69"
          "\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80";

int main(void)
{
fprintf(stdout,"Length: %d\n",strlen(shellcode));
(*(void(*)()) shellcode)();
return 0;
}
È stato utile?

Soluzione

It is a cast to a function pointer (with no returned result and no arguments). I prefer using typedef to define signature of such functions:

 typedef void plainsig_t(void);

then simply code

 (*(plainsig_t*)shellcode) ();

For function pointers, you don't need to dereference them, so it is shorter to just code:

 ((plainsig_t*) shellcode) ();

which basically calls the function whose machine code is located inside shellcode memory zone.

BTW, this is not strictly portable C. In principle, there is no guarantee that you can cast a data pointer to a function pointer. (On some weird processors -e.g. embedded microcontrollers, DSP, 1970s era computers-, code and data sit in different address spaces, or have different pointer sizes, etc....). But most common processors and ABI (x86-64/Linux, ARM/Android, ....) have the same address space for code and for data and accept casting function pointers to data pointers and vice versa.

Altri suggerimenti

This is one place that C and C++ differ.

In C it means a pointer to a function returning void and taking an unspecified number of arguments of unspecified types.

In C++ it means a pointer to a function returning void and taking no argument.

The expression as a whole takes the address of shellcode, casts it to a pointer to function type, then invokes the function -- i.e., executes the op-codes in that string.

void(*)() means "a pointer to a void function that takes no arguments." The line

(*(void(*)()) shellcode)();

is casting shellcode to such a function pointer, dereferencing the pointer (not actually necessary), and then calling the function.

It's a function pointer. Type specifiers match declarations; so a function void f() has type void(); and a pointer to a function void (*pf)() has type void(*)().

Note that, as with function declarations, it has slightly different meanings in C and C++. In C, the empty parentheses mean it has an unspecified number of parameters, while in C++ it means it has no parameters. However, that doesn't affect the meaning of the code.

This code reinterprets an array as a function and attempts to call it. Presumably, the array contains machine code to print a message, or format your hard drive, or something. On most modern platforms, this will cause a protection fault since the static data is (hopefully) not executable by default.

In C a variable is declared as int foo; , to declare a function we use int foo( ); It means that the return type of the function is int. To declare a pointer we use *foo.

In the expression (*(void(*)())0)() we can see that

  1. Assuming that the variable fp is a function pointer, we can use (*fp)( ); to call the function, because fp is a function pointer, and *fp is the function pointed to by the pointer, so (*fp)( ); can call the function.

  2. Suppose fp is a pointer to a non-return value type, then the way to call it is void (*fp)( ), then the type of the fp variable is void (*)( ).

  3. If we were to cast this type to a constant shellcode, then we use ( void (*)() ) shellcode.

  4. Now that the shellcode is cast to the type, in order to call the shellcode we use

    ( ( void (*)() ) shellcode )();


Note: We can use typedef to replace the type name of the above expression

For example: typedef void (*ff)( ); Therefore, the way to call a function can be written as:

(*(ff) shellcode ) ( );

from : https://www.codetd.com/en/article/14043929

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top