The outcome of the following macro is clear:
#define CRASH() do {\
*(int *)(uintptr_t)0xbbadbeef = 0;\
((void(*)())0)();\
} while (false)
My question is, what does the line
((void(*)())0)();
break down to, in English? For example, "this is a function that returns a pointer to a...."
It looks like it casts 0 as a function pointer (with the signature that it takes not parameters and has void return type) and then invokes it.
( ( void(*)() ) 0 ) ();
/* cast..*/ /* fn pointer signature */ /*..cast 0 */ /* invocation */
Which is another way to say that it's trying to invoke (call) a function that's expected to be located in memory at address 0x00000000 - which is guaranteed to be an invalid address.
Cast 0 to a pointer to a void function that takes can be called with no parameters (the (void(*)())0 part of the expression)
Call that function through a pointer with an empty parameter list (the () part after it).
EDIT 1: Edited in response to Cristoph's comment.
It casts a NULL pointer to a method taking no parameters and returning void, and attempts to call this method.
Needless to say, it crashes, so the name CRASH suits it very well.
It casts 0 to a function pointer, where the function takes no argument and returns void, then tries to call this function. It basically dereferences a null pointer.
It casts 0 to a pointer to a function, then attempts to call that function. Which will cause a segfault and crash.
Edit: way too much competition for these questions. Upvotes all round, and I'm going to bed :)
It means “treating NULL pointer as pointer to void function(), call function()”.
It takes the value zero, and casts it to a function pointer that doesn't return anything (void).
Presumably, the purpose is that when you call this "function", it calls address zero, which should indeed crash the application.
For me it is simpler to translate to a different C++, rather than directly to english:
typedef void (void_func_t)(); // type of a function taking no arguments
// and returning void
typedef void_fnct_t* void_func_ptr; // pointer to such a function
static_cast<void_func_ptr>(0)(); // call that function
// ((void_func_ptr)0)(); // pure C equivalent cast
if fp is a pointer to a function, *fp is the function itself, so(fp)()is the way to invoke it. ANSI C permits this to be abbreviated as fp(), bu keep in mind that it is only an abbreviation. -------C traps an pitfalls.
( ( void()() )0 ) () is the avvreviation of ( ( void()() )0 )()
Related
So in "the c++ programming language, 4th edition", there's a paragraph I don't understand about conversion of pointer-to-function types. Here is some of the code sample.
using P1 = int(*)(int*);
using P2 = void(*)(void);
void f(P1 pf) {
P2 pf2 = reinterpret_cast<P2>(pf);
pf2(); // likely serious problem
// other codes
}
When I run this it crashed.
I'm not sure if I am right, but I initially think the "likely serious problem" comment is when pf got casted to P2 in pf2, I think pf2 is not pointing to anything? Because when I created a function that matches P2's type and point pf2 to it, it didn't crash and runs normally.
After the code, I read this:
We need the nastiest of casts, reinterpret_cast, to do conversion of pointer-to-function types. The reason is that the result of using a pointer to function of the wrong type is so unpredictable and system-dependent. For example, in the example above, the called function may write to the object pointed to by its argument, but the call pf2() didn’t supply any argument!
Now I'm completely lost starting from "For example, in the example above" part:
"may write to the object pointed to by its argument" //what object is it exactly?
"but the call pf2() didn’t supply any argument!" //"using P2 = void(*)(void);" doesn't really need an arguement does it?
I think I'm missing something here. Can someone explain this?
For example, in the example above, the called function may write to the object pointed to by its argument (...)
pf is a pointer to a function like this:
int foo(int* intPtr)
{
// ...
}
So it could be implemented to write to its argument:
int foo(int* intPtr)
{
*intPtr = 42; // writing to the address given as argument
return 0;
}
(...) but the call pf2() didn’t supply any argument!
When you call foo through its cast to type P2, it will be called without arguments, so it is unclear what intPtr will be:
P2 pf2 = reinterpret_cast<P2>(pf);
pf2(); // no argument given here, although pf2 really is foo() and expects one!
Writing to it will most likely corrupt something.
Moreover, compilers usually implement calls to functions that return something by reserving space for the return value first, that will then be filled by the function call. When you call a P1 using the signature of P2, the call to P2 won't reserve space (as the return value is void) and the actual call will write an int somewhere it should not, which is another source for corruption.
Now I'm completely lost starting from "For example, in the example
above" part:
"may write to the object pointed to by its argument" //what object is
it exactly?
P1 is a function expecting a non-const pointer-to-int argument. That means it very well may write to the int referenced in its argument.
"but the call pf2() didn’t supply any argument!" //"using P2 =
void(*)(void);" doesn't really need an arguement does it?
When you call the function through another function pointer type passing no argument, the expectations of the called function aren't met. It may try to interpret whatever is on the stack as an int pointer and write to it, causing undefined behavior.
This does fail, but not necessarily in the way one might expect.
The implementation of a function pointer is left up to the compiler (undefined). Even the size of a function pointer can be bigger than a void*.
What is guaranteed about the size of a function pointer?
There is no guarentees about anything in the value of the function pointer. In fact, the only even guarentee that the comparison operators will work between function pointers of the same type.
Comparing function pointers
The standard does provide that function pointers can store the values of other function types.
Casting the function pointer to another type undefined behavior, meaning the compiler can do whatever it wants. Whether or not you supply the argument really doesn't matter, and how that would fail depends on the calling convention of the system. As far as your concerned, it could allow "demons to fly out of your nose".
Casting a function pointer to another type
So that brings us back to the statement by the author:
We need the nastiest of casts, reinterpret_cast, to do conversion of pointer-to-function types. The reason is that the result of using a pointer to function of the wrong type is so unpredictable and system-dependent. For example, in the example above, the called function may write to the object pointed to by its argument, but the call pf2() didn’t supply any argument!
That is trying to make the point that with no argument specified, if the function writes the output, it will write to some uninitialized state. Basically, if you look at the function as
int foo(int* arg) {*arg=10;}
if you didn't initialize arg, the author says you could be writing anywhere. But again, there is no guarentee that this even matters. The system could store functions with the footprint int (*)(int*) and void(*)(void) in completely different memory space, in which case instead of the above problem you'd have a jump into a random location in the program. Undefined behavior is just that: undefined.
Just don't do it man.
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;
}
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.
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
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.
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 (*)( ).
If we were to cast this type to a constant shellcode, then we use ( void (*)() ) shellcode.
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
Can someone explain what does this statement do?
#define CONST_SIG (void (*) () ) 1
This statement defines CONST_SIG to be 1 cast into a pointer to a function that gets no parameters and returns void. This may be useful if you have a pointer to a function and you perhaps test it for truthness, then CONST_SIG will be true.
You can try the cdecl program, which is available in many linux distributions, for "English translation" of C declarations. Example output in this instance:
cdecl> explain (void (*) () )
cast unknown_name into pointer to function returning void
Side-note: The reason it says "unknown_name" is because our pointer has no name. To name it, for example, "p", would look like this: (void (*p) () ).
You can pass CONST_SIG to a function which expects a function pointer and treats a value of 1 as a special value for this function pointer.
I am trying to understand what this means, the code I am looking at has
in .h
typedef void (*MCB)();
static MCB m_process;
in .C
MCB Modes::m_process = NULL;
And sometimes when I do
m_process();
I get segmentations fault, it's probably because the memory was freed, how can I debug when it gets freed?
It defines a pointer-to-function type. The functions return void, and the argument list is unspecified because the question is (currently, but possibly erroneously) tagged C; if it were tagged C++, then the function would take no arguments at all. To make it a function that takes no arguments (in C), you'd use:
typedef void (*MCB)(void);
This is one of the areas where there is a significant difference between C, which does not - yet - require all functions to be prototyped before being defined or used, and C++, which does.
It introduces a function pointer type, pointing to a function returning nothing (void), not taking any parameters and naming the new type MCB.
Let's take an example
typedef void (*pt2fn)(int);
Here, we are defining a type pt2fn. Variables of this type point to functions, that take an integer as argument and does not return any value.
pt2fn kk;
Here, kk is a variable of type pt2fn, which can point to any function that takes in an integer as input and does not return any value.
Reference:https://cs.nyu.edu/courses/spring12/CSCI-GA.3033-014/Assignment1/function_pointers.html
The typedef defines MCB as the type of a pointer to a function that takes no arguments, and returns void.
Note that MCB Modes::m_process = NULL; is C++, not C. Also, in C, the typedef should really be typedef void (*MCB)(void);.
I'm not sure what you mean by "the memory was freed". You have a static pointer to a function; a function cannot be freed. At most, your pointer has been reset somewhere. Just debug with a memory watch on m_process.
It's a function pointer. You get a SEGMENTATION FAULT because you are trying to make a call to a function which address is invalid (NULL).
According to your specific sample, the function should return no value (void) and should receive no parameters ().
This should work:
void a()
{
printf("Hello!");
}
int main(int arcg, char** argv)
{
m_process = a;
m_process(); /* indirect call to "a" function, */
// Hello!
}
Function pointers are commonly used for some form of event handling in C. It's not its only use though...
CUnknown* (*)( LPUNKNOWN pUnk, HRESULT* phr );
Seems I've always been in trouble reading such complicated pointers..
How do you read it? what if the expression even longer?
Everyone has said what it is, but you asked how to read it.
Function pointer syntax is as follows:
RETURN_VALUE (*POINTER_NAME) (ARGUMENT LIST)
So
foo (*bar) (baz)
is a pointer to a function taking baz and returning foo, and the pointer is called bar.
In the case that you only want to write the type of a function pointer, rather than declare one, you just leave out the name, e.g.
RETURN_VALUE (*) (ARGUMENT_LIST)
as you see here.
For parsing hard-to-understand C declarations, there's a nice program called cdecl available on most Linux and Unix-like systems, as well as available as a web app: http://cdecl.org/
What I learned from books and Uni was to start at the middle and proceed outwards back and forth. The trick is only to do it slowly, and know where the middle actually is.
You have a
CUnknown* (*)( LPUNKNOWN pUnk, HRESULT* phr );
that's a pointer (*)
Now we go right: it's a pointer to a function because the next thing is a (
The arguments of the function are a LPUNKNOWN and a pointer to HRESULT, and that's it.
Now we go left: the function returns a pointer to CUnknown.
So, as stated by everyone, it's a pointer to a function that takes two arguments -a LPUNKNOWN and a pointer to a HRESULT- and returns a pointer to CUnknown.
Link beauties: this and this.
The Clockwise Spiral Rule helps me understand things like this. From the site:
Starting with the unknown element, move in a spiral/clockwise direction; when ecountering the following elements replace them with the corresponding english statements:
Keep doing this in a spiral/clockwise direction until all tokens have been covered.
Always resolve anything in parenthesis first!
[X] or []
=> Array X size of... or Array undefined size of...
(type1, type2)
=> function passing type1 and type2 returning...
*
=> pointer(s) to...
It's a pointer to a function taking the arguments 'LPUNKNOWN pUnk, HRESULT* phr' and it returns a pointer to a CUnknown.
it's a function pointer with two arguments that returns a CUnknown*
I think this is pointer to a function taking LPUNKNOWN and pointer to HRESULT, returning pointer to CUnknown
For some function:
int f(int a, int& b, int* c);
The type of the expression:
&f
Or, equivalently:
f
Is:
int(*)(int, int&, int*)
And an easy way to remember this is that a function pointer type specifier is just like a function declaration, except with the name replaced with (*). You can also perform a typedef:
typedef int(*ftype)(int, int&, int*);
And now you can write:
ftype func = f;
Rather than:
int(*func)(int, int&, int*) = f;