[英]Changing VTable entries doesnt redirect function?
I have 3 classes (Cat, HouseCat:Cat, Lion:Cat). 我有3个班级(Cat,HouseCat:Cat,Lion:Cat)。 What I'm trying to do is change HouseCat's VTable to make HouseCat eat Meat instead of cat food.
我要做的是更改HouseCat的VTable,使HouseCat吃肉而不是猫食。
Classes I 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 to edit those classes' VTable entries by a VTable struct I created. 我试图通过我创建的VTable结构来编辑这些类的VTable条目。
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;
for (int i = 0; i < size; i++)dest[i] = src[i];
VirtualProtect(set, size, old, &old);
}
struct VTable{
static VTable read(void * object){
VTable vt = *(VTable*)(object);
int i = 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 that VTable[0] = eat(), so i decided to try making a change on the Vtable like this : 我确认VTable [0] = eat(),所以我决定尝试对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 that HomeCat[0] changed from 0x311285->0x31106E 您可以看到HomeCat [0]从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 is the output of the functions didnt change at all. 问题在于函数的输出完全没有改变。
---Base---
- -基础 - -
Meat2
Meat2
Meow!2
喵!2
---Lion---
- -狮子 - -
Meat2
Meat2
ROAR!2
怒吼!2
---Home---
- -家 - -
Cat Food2
猫粮2
Meow!2
喵!2
---End---
- -结束 - -
I'm using Visual Studio 2013. Release/Debug didnt make a difference either. 我使用的是Visual Studio2013。发布/调试也没有任何区别。
Did i do something wrong in my code or is it somekind of compiler stuff I'm missing? 我在代码中做错了什么吗?还是我缺少某种编译器?
I agree that this is a horrible hacky thing to do... however, to get it working I'd try changing your lion
/ base
/ home
variables to be pointers to objects. 我同意这是一件骇人听闻的事情……但是,要使其正常工作,我将尝试将您的
lion
/ base
/ home
变量更改为指向对象的指针。 Right now since they are not pointers, the compiler may be automatically calling the correct function without using the vtable (since it knows exactly what type the object is). 现在,由于它们不是指针,因此编译器可能会在不使用vtable的情况下自动调用正确的函数(因为它确切知道对象的类型)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.