A virtual function is essentially a function in a class, that allows inherited classes to overwrite that function. On assembly level, this means that the compiler generates a table of pointers to functions, which are then called instead of calling the function directly. This allows inherited classes to easily overwrite the virtual function in the class instance. ex:
2521a783 2521a825 25220052 25228252As you can see, it consists merely pointers, that point to the functions themselves.
(I am working on my paint skills):
With this information, we can actually easily replace the address that exists within the vmt with a pointer to our own function, while preserving the original function pointer for later use.
I've coded a little example code here just for the sake of consistency;
class VirtualTable
{
public:
virtual void VirtualFunction01( void );
};
void VirtualTable::VirtualFunction01( void )
{
cout << "VirtualFunction01 called" << endl;
}
//we use this to store and call the original function inside our custom one
typedef void ( __thiscall* VirtualFunction01_t )( void* thisptr );
VirtualFunction01_t g_org_VirtualFunction01;
//our custom function
void __fastcall hk_VirtualFunction01( void* thisptr, int edx )
{
cout << "Custom function called" << endl;
//call the original function
g_org_VirtualFunction01(thisptr);
}
int _tmain(int argc, _TCHAR* argv[])
{
VirtualTable* myTable = new VirtualTable();
//get the pointer to the actual virtual method table from our pointer to our class instance
void** base = *(void***)myTable;
DWORD oldProtection;
//one way to remove page protection(not the best but this is an example only)
VirtualProtect( &base[0], 4, PAGE_EXECUTE_READWRITE, &oldProtection );
//save the original function
g_org_VirtualFunction01 = (VirtualFunction01_t)base[0];
//overwrite
base[0] = &hk_VirtualFunction01;
//restore page protection
VirtualProtect( &base[0], 4, oldProtection, 0 );
//call the virtual function (now hooked) from our class instance
myTable->VirtualFunction01();
system("pause");
return 0;
}
Output:
Custom function calledVirtualFunction01 called
