Overriding the virtual table in a C++ object

Before starting, I just want to mention that I recently joined http://www.planetalinux.org/ , is a nice group of Linux bloggers, if you read this blog and want to read some interesting posts ( mostly in spanish, but some guys post in english ) go there!

Having said that, let’s finish this post.

Yesterday I was discussing with a friend of mine about how polymorphism is implemented in C++, and that is, using a virtual table ( remember the “virtual” keyword in method definitions? ). A virtual table is, rawly speaking, just like an array of function pointers. Each created object with virtual methods needs a virtual table. So, where does the virtual table is stored?, I really don’t know, but I do know where I can find the address of the virtual table associated to an object ( at least in g++ 4.1.1 ), the first sizeof(void*) bytes of an object are used to store a pointer to the virtual table. With this knowledge, one could think that is possible to override the virtual table pointer of the object and call arbitrary functions, and yes, we can. Let’s see some fun code.


#include <iostream>

using namespace std;

class Parent
{
    public:
        virtual void VirtFunc1() { cout << "Parent::VirtFunc1" << endl; }

        virtual void VirtFunc2() { cout << "Parent::VirtFunc2" << endl; }
};

class Child : public Parent
{
    public:

        void VirtFunc1() { cout << "Child::VirtFunc1" << endl; }
        void VirtFunc2() { cout << "Child::VirtFunc2" << endl; }
};

typedef void (*virtual_function)();

struct FakeVirtualTable {
    virtual_function virtual_one;

    virtual_function virtual_two;
};

void fake_virtual_one()
{
    cout << "Faked virtual call 1" << endl;
}

void fake_virtual_two()
{
    cout << "Faked virtual call 2" << endl;
}

int main()
{
    /* declare a Child class and a base pointer to it. */
    Child child_class_obj;
    Parent* parent_class_ptr = &child_class_obj;

    /* create our fake virtual table with pointers to our fake methods */
    FakeVirtualTable custom_table;
    custom_table.virtual_one = fake_virtual_one;

    custom_table.virtual_two = fake_virtual_two;

    /* take the address of our stack virtual table and override the real object pointer to the virtual table */
    FakeVirtualTable* table_ptr = &custom_table;

    memcpy(parent_class_ptr, &table_ptr, sizeof(void*));

    /* call the methods ( but we're really calling the faked functions ) */

    parent_class_ptr->VirtFunc1();
    parent_class_ptr->VirtFunc2();

    return 0;
}

So, try to run that code and, of course, the expected result is having fake_virtual_one() and fake_virtual_two() functions called. No magic there, we just replace the first sizeof(void*) bytes of the object with our own table pointer. There is not a use I can think of right now, but it is funny ….

This entry was posted in C/C++. Bookmark the permalink.

2 Responses to Overriding the virtual table in a C++ object

  1. moy says:

    @Leonard: That sounds like a cool hack! … thanks for sharing

  2. Leonard says:

    There definitely is a use. If you want to call a virtual member function of a class with a non-compatible compiler (one that stores/handle virtual classes or its members differently) then this is just a first step. The second step is to realize that most, if not all, C++ class member functions get passed a hidden *this pointer, and depending on how it’s done for a specific compiler usually means putting in ASM code to do it before making the actual call. The third step is to make sure you’re using the correct calling convention. In MSVC++ for example, the default calling convention for class member functions is __stdcall, not __cdecl.

    I had to do this when I needed to call Winamp’s WASABI classes, which is compiled with MSVC++, from a Borland C++ Builder 5 compiled plugin, which handles classes and class member functions differently from MSVC++.

Leave a Reply

Your email address will not be published. Required fields are marked *

*