Skip to content

Instantly share code, notes, and snippets.

@evanlong
Created February 24, 2011 06:15
Show Gist options
  • Save evanlong/841846 to your computer and use it in GitHub Desktop.
Save evanlong/841846 to your computer and use it in GitHub Desktop.
Showing off vtables for stackoverflow answer.
#include <iostream>
using namespace std;
class A
{
public:
int a1;
int a2;
virtual void A1() { cout << "A->A1" << endl; }
virtual void DoSomething() { cout << "DoSomething" << endl; };
};
class B : public A
{
public:
int b1;
int b2;
virtual void A1() { cout << "B->A1" << endl; }
virtual void B1() { cout << "B->B1" << endl; }
};
class C : public A
{
public:
int c1;
int c2;
virtual void A1() { cout << "C->A1" << endl; }
virtual void C1() { cout << "C->C1" << endl; }
};
void somefunc(void* thiz)
{
cout << "somefunc" << endl;
}
int main(int argc, char** argv)
{
A* a = new A();
B* b = new B();
C* c = new C();
//first lets show the size of the types
cout << sizeof(A) << ", " << sizeof(B) << ", " << sizeof(C) << endl;
//from wikipedia we know the class layout for B and C will consist of four
//integers and a vtable pointer so a total of 20 bytes (assuming 32bit machine)
c->A1(); //Will print C->A1()
//Lets lets move the vtable pointer of B and put it on C
int* cVtablePtr = (int*)((int*)c)[0];
((int*)c)[0] = ((int*)b)[0];
c->A1();
//and restore
((int*)c)[0] = (int)cVtablePtr;
c->A1();
c->DoSomething();
//So that was the whole vtable what if you wanted to change just one function in the vtable
//cVtablePtr[0] is C->A1() and cVtablePtr[1] is A->DoSomething()
void* doSomethingPtr = (void*)cVtablePtr[1];
cout << &cVtablePtr[1] << endl;
int k;
cin >> k;
cVtablePtr[1] = (int)somefunc;
c->DoSomething();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment