Reputation: 388
I'm working on reverse engineering a program. I'm using IDA Pro and the Hex-Rays Decompiler. I'm coming up against chunks of code where I know there is an object and there is a method call on the object but it's shown in a way I'm not able to figure out. For example:
if ( (*(*interfacePtr + 24))(interfacePtr, &v23) >= 0 )
I know here that interfacePtr is pointing to a ICLRRuntimeHost object. (C++, .NET CLR runtime) However.... I have no idea what is at *(*interfacePtr + 24). I can tell it's a method but how do I figure out what is sitting at +24?
Upvotes: 3
Views: 1485
Reputation: 2776
Have a look at the definitions of ICLRRuntimeHostVtbl
and ICLRRuntimeHostVtbl
in mscoree.h
roughly translated to something hexrays would understand, they look like this:
struct ICLRRuntimeHost {
ICLRRuntimeHostVtbl *vtbl;
};
struct ICLRRuntimeHostVtbl {
_DWORD (*QueryInterface)(ICLRRuntimeHost*, _DWORD*, void**);
_DWORD (*AddRef)(ICLRRuntimeHost*);
_DWORD (*Release)(ICLRRuntimeHost*);
_DWORD (*Start)(ICLRRuntimeHost*);
_DWORD (*Stop)(ICLRRuntimeHost*);
_DWORD (*SetHostControl)(ICLRRuntimeHost*, void*);
_DWORD (*GetCLRControl)(ICLRRuntimeHost*, void**);
};
Your variable interfacePtr should have type: ICLRRuntimeHost, then your code should decompile like this:
interfacePtr->GetCLRControl(&v23);
Upvotes: 0
Reputation: 637
The vtable of a class is just a list of pointers to functions. It contains one pointer for each virtual function, in the order: very, very top base class, next base class, subclass of that, . . . most derived class.
Example:
struct A {
virtual ~A() {}
virtual void foo() = 0;
}
struct B : public A {
virtual void foo() { // do something }
virtual void bar() { // do something else }
}
The vtable for B would contain, in this order:
(The ones for A have to come first, so that the same vtable can be used by parts of the code that have a pointer of type A to this object; that code doesn't know that the underlying object is really B.)
If you're looking at 32-bit source, pointers are 4 bytes, so 24 = 4 * 6, you're looking at the 7th virtual function (index starts at 0). If you're on 64-bit, pointers are 8 bytes, so 24 = 8 * 3, and you're looking for the 4th. Actually, I haven't used the IDA "convert to C++" functionality, so maybe 24 is actually the 24th entry in the table.
Easy way to confirm: write your own program. Declare a variable of type ICLRRuntimeHost. Call the function you suspect (based on looking at the header file and counting to 7 or 4, depending on bitness, or 24, if I misunderstood your example). Look at the generated assembly code, and confirm whether your index is right. (I'm always off by one on that kind of thing, so this will provide a check.)
Upvotes: 2