Reputation:
When I decompiled a function I got the following code
((void(__thiscall**)(int))(*v4 + 4))(v4);
*v4 in this context is a virtual table. I can't really break it down (who is resolved first and the exact meaning of it).
I'd kindly ask you to help me resolving this step by step so I can understand how this works.
Upvotes: 0
Views: 338
Reputation: 26656
(
( // these parens around the type declaration are a cast
void (__thiscall**)(int) // this type declaration:
// a pointer to pointer to function taking int parameter
)
(*v4 + 4) // this is a pointer expression
// this pointer is being cast to a function
) // this is a function pointer
( // these paren's invoke the function
v4 // this is the parameter being passed to the function
);
The only thing that is strange is that v4
, passed as parameter, is not an int as the cast says — it is a pointer.
It looks like v4
is an object, and the vtable is the first member of the object, so *v4
refers to the vtable. *v4+4
refers to the 5th vtable entry.
Upvotes: 2
Reputation: 206
This statement use some weird calling convention specification from Microsoft, but what it basically is, is just a cast, followed by a call.
(void(**)(int))
this type is a pointer to a pointer to a function taking int as parameter, and returning void.
__thiscall
is a calling convention specifier only supported by Microsoft compiler as you can see here
(*v4 + 4)
This part is just dereferencing v4, then adding 4, so I'd guess that *v4 is a pointer, and the type of v4 is something like void **
Wrapping all up, this statement de-reference v4, add 4 to this value, cast this new pointer as a pointer to a pointer to function, then invoke this by passing v4.
As pointed out by others, it's weird that v4 is passed as an int. However, as the architecture seems to be x86, this should not break anything, as int and pointer should have the same size of 32bits.
Upvotes: 0
Reputation: 58888
((void(__thiscall**)(int))(*v4 + 4))(v4);
^^ pointer
^^^ dereference it
^^^^^^^ add 4
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cast to void (__thiscall**)(int)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Call with v4 as the parameter
void (__thiscall**)(int)
is a pointer to a pointer to a function, which has an int
parameter.
Presumably:
v4
is the address of an object.*v4
reads the vtable pointer from the object.*v4 + 4
is the slot in the vtable where the function pointer we want to call is. It's a pointer to that function pointer.this
Note that we're calling a pointer to a function pointer. Function pointers are automatically dereferenced in C(++), but I wasn't aware that that also applied to pointers to function pointers. Evidently, it does.
Upvotes: 2