I would like to know how to change the address of Test
which is in the virtual table with that of HackedVTable
.
void HackedVtable()
{
Under Mac OS X 10.10.3 + gcc 4.8.3, following code works well.
void HackedVtable()
{
cout << "Hacked V-Table" << endl;
}
class Base
{
public:
virtual void Test() { cout << "base" << endl; }
virtual void Test1() { cout << "Test 1" << endl; }
void *prt;
Base(){}
};
class Derived : public Base
{
public:
void Test()
{
cout << "derived" << endl;
}
};
int main()
{
Base b1;
Base* pb1 = &b1;
*(*(void***)pb1) = (void*) HackedVtable;
pb1->Test();
//It works for all the Base instance
Base b2;
Base* pb2 = &b2;
pb2->Test();
//But Derived's virtual function table is separated from Base's
Derived d1;
Derived* pd1 = &d1;
pd1->Test();
*(*(void***)pd1) = (void*) HackedVtable;
pd1->Test();
return 0;
}
Its output:
$ g++ h.cpp; ./a.out
Hacked V-Table
Hacked V-Table
derived
Hacked V-Table
I test the same code under Ubuntu 12.04 + g++ 4.9.0. However, it does not work and arises segmentation fault. It seems Linux assigns the virtual function table in a read only area (e.g. rodata) to forbid hacking.