cplusplus.co.il

Changing the vtable pointer

Posted on: 14/08/2009

Most compilers implement dynamic binding by using a vtable whose pointer resides at the beginning of each object’s memory footprint (something along the lines of [vtable-pointer|..members..], if we are not considering virtual inheritance).

Keeping this idea in mind, why don’t we go ahead and attempt to change that vtable pointer?

#include <iostream>
using std::cout;

struct A {
    virtual void f () { cout << "a:" << n; }
    A () : n(1) {}
    int n;
};

struct B : A {
    void f () { cout << "b:" << n; }
    B () { n = 2; }
};

int main () {
    A *a = new A();
    A *b = new B();
    // lets change a's vtable to b's
    *reinterpret_cast<int**>(a) = *reinterpret_cast<int**>(b);
    a->f(); // huray, B::f() is invoked!
}

Notice we surely did not touch the object itself, since the member did not change.

Another thing worth saying is that this trick is unlikely to work when using 64bit pointers since we’re using an (arbitrary) int* type, but that could easily be solved using a compile time #defined typedef.

One extra thing i would like to mention is that i have tried to change specific entries inside the vtable, but the compiler marks that memory area as read-only and therefore throws an exception whenever modification attempts are made. Here is the attempted piece of code:

#include <iostream>
using std::cout;

struct A {
    virtual void f () { cout << "f"; }
    virtual void g () { cout << "g"; }
};

int main () {
    A *a = new A();
 
    int **vtable = *reinterpret_cast<int***>(a);
    vtable[0] = vtable[1];

    a->f();
}

This change to the vtable would make the call to f() actually invoke g().

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: