c++ - Changing VTable entries doesnt redirect function? -


i have 3 classes (cat, housecat:cat, lion:cat). i'm trying change housecat's vtable make housecat eat meat instead of cat food.

classes use:

class cat { public:     int age = 2;     virtual void eat() {         cout << "meat" << this->age << endl;     };      virtual void sound() {         cout << "meow!" << this->age << endl;     }; };   class housecat : public cat { public:     virtual void eat() {         cout << "cat food" << this->age << endl;     }; };  class lion : public cat { public:     virtual void sound() {         cout << "roar!" << this->age << endl;     }; }; 

i'm trying edit classes' vtable entries vtable struct created.

static void __memcpy(void * set, void * data, int size){     dword old;     virtualprotect(set, size, page_execute_readwrite, &old);     char*dest = (char*)set;     char*src = (char*)data;     (int = 0; < size; i++)dest[i] = src[i];     virtualprotect(set, size, old, &old); }  struct vtable{      static vtable read(void * object){         vtable  vt = *(vtable*)(object);         int = 0;         while ((dword)vt.functions[i] != 0x0)             i++;         vt.size = i;         return vt;     }     void ** functions;     int size;      void redirectfunction(int i, void * redirect){         __memcpy(&functions[i], &redirect, 4);     } }; 

i confirmed vtable[0] = eat(), decided try making change on vtable :

int main(int argc, char* argv[]) {      lion lion = lion();     cat base = cat();     housecat home = housecat();        vtable lionvtable = vtable::read(&lion);     vtable basevtable = vtable::read(&base);     vtable homevtable = vtable::read(&home);     cout << "-------------- before edit -----------------" << endl     << "base:" << endl     << (basevtable.functions[0]) << endl     << (basevtable.functions[1]) << endl     << "homecat:" << endl     << (homevtable.functions[0]) << endl     << (homevtable.functions[1]) << endl     << "lion:" << endl     << (lionvtable.functions[0]) << endl     << (lionvtable.functions[1]) << endl;      homevtable.redirectfunction(0, lionvtable.functions[0]);       cout << "-------------- after edit -----------------" << endl     << "base:" << endl     << (basevtable.functions[0]) << endl     << (basevtable.functions[1]) << endl     << "homecat:" << endl     << (homevtable.functions[0]) << endl     << (homevtable.functions[1]) << endl     << "lion:" << endl     << (lionvtable.functions[0]) << endl     << (lionvtable.functions[1]) << endl;      pause();         cout << "---base---" << endl << endl;     base.eat();     base.sound();     cout << "---lion---" << endl << endl;     lion.eat();     lion.sound();     cout << "---home---" << endl << endl;     home.eat();     home.sound();     cout << "---end---" << endl;        pause();     return 0;  } 

it outputed;

-------------- before edit ---------------- base: 0031106e 0031121c homecat: 00311285 0031121c lion: 0031106e 003113f2 -------------- after edit ----------------- base: 0031106e 0031121c homecat: 0031106e 0031121c lion: 0031106e 003113f2 

you can see homecat[0] changed 0x311285->0x31106e

vmt.exe+11285 - e9 b6350000           - jmp virtualmethodtable test.housecat::eat [cat food] -> vmt.exe+1106e - e9 ed450000           - jmp virtualmethodtable test.cat::eat [meat] 

the problem output of functions didnt change @ all.

---base---

meat2

meow!2

---lion---

meat2

roar!2

---home---

cat food2

meow!2

---end---

i'm using visual studio 2013. release/debug didnt make difference either.

did wrong in code or somekind of compiler stuff i'm missing?

i agree horrible hacky thing do... however, working i'd try changing lion/base/home variables pointers objects. right since not pointers, compiler may automatically calling correct function without using vtable (since knows type object is).


Comments