What is the real signature of a C++ constructor after compilation
What is the real signature of a constructor in C++?
Background: I try to hook internal functions of a dll. I have the pdb-Debug Files and were able to get the exact location of the function, including it's undecorated name. The function looks like:
protected: __cdecl ClassName::ClassName(bool * __ptr64) __ptr64
So it is obviously a constructor. I tried void function(void * pThisPointer, bool * pBoolPointer), but as the program crashes after simply forwarding the call (other functions work fine this way), I assume that my signature is wrong.
Do you know what signature to use for a constructor (which is most likely not virtual)? Or do you have any other ideas what may go wrong?
EDIT: I use x64 and the visual stu开发者_JS百科dio 2010 compiler, the target compiler should be something like the visual studio compiler, as it is a microsoft dll.
You cannot call a constructor directly. As far as C++ is concerned, constructors do not have a name. In other words, you cannot call constructors. Many compilers create two or even three different functions. Which one should you call?
The answer is none of them. You cannot and must not try to call a constructor directly from your code.
The easiest way is to look at the disassembly of the actual constructor and see what it accesses. The usual convention with MSVC (and other compilers) is to pass this
as a hidden first parameter. Usually it's done with __thiscall
convention (i.e. in ecx
on x86), but on x64 there is only one convention, so __thiscall
is the same as __cdecl
or __stdcall
.
However, the other not very well-known convention of MSVC is that constructors must return the this
pointer. I suspect that's what's causing your crash.
It's probably not very relevant here, but have a look at my article on MSVC C++ internals. It describes x86 implementation, but a lot of things will apply
Since you can't legally take a function pointer to a constructor, it doesn't really have a meaningful signature, as far as C++ itself is concerned.
Implementations do their own thing, but typically a class can have at least two constructor function bodies in the emitted code - one for normal use, and another for when it's used as a virtual base. The compiler knows how to use each one -- you need to know exactly what parts of object construction are done in this emitted code in your implementation, what's done by the caller prior to calling it, what's done by the caller after it returns, and what's done by the caller if it throws an exception, or you can't correctly call it even given that you've figured out its address from debug info.
To reverse-engineer object construction, you should look at the code emitted at a place where an object is created using this constructor.
精彩评论