Ring3 Circus
February 6th, 2008, 04:11
I wrote about this ("http://www.ring3circus.com/gameprogramming/run-time-determination-of-vc-2005-virtual-member-function-addresses/") tricky little problem a while ago and wasn’t too happy with the desperate methods that seemed necessary. Since then, I’ve been shown a much cleaner way to do the same thing, by manipulating the vTable manually. It seems that Microsoft haven’t changed their vTable implementation since Visual Studio 6 (at least) and so with a little modification, the following piece of inline-assembly will do the trick: no muss, no fuss.
Thanks go to Vuurvlieg for this function. The beauty (or horror), here, is the use of a variadic parameter-list to overcome C++’s strong-typing that would otherwise make this operation very difficult. Obviously, this implementation will only work for objects of type IDirect3DDevice9, but the method extends to any other class by simply replacing the class name in the function declaration. Don’t be tempted to generalise this function to IUnknown or some other common base-class, as you’ll quickly run into problems with object-slicing. A final warning to those still using Visual Studio 6 (not that you deserve any help for such a crime): you’ll need to drop the ampersand from the second argument in the function call, as VS6 handles function pointers slightly differently.
http://www.ring3circus.com/gameprogramming/run-time-determination-of-vc-virtual-member-function-addresses-take-ii/
Code:
__declspec(naked) void* ResolveVirtualFunction
(IDirect3DDevice9* pDevice, ...)
{
_asm
{
mov eax, dword ptr ss:[esp+0x0C]
add eax, 0x8
cmp byte ptr ds:[eax-1], 0xA0
mov eax, dword ptr ds:[eax]
je normal_index
and eax, 0xFF
normal_index:
mov ecx, eax
mov eax, dword ptr ss:[esp+0x8]
mov eax, dword ptr ds:[eax]
mov eax, dword ptr ds:[eax+ecx]
retn
}
}
// ...
// The function should be invoked like this:
void* address_device_present = ResolveVirtualFunction(
device, &IDirect3DDevice9::Present);
http://www.ring3circus.com/gameprogramming/run-time-determination-of-vc-virtual-member-function-addresses-take-ii/