gpt4 book ai didi

c++ - 更改表条目没有重定向功能?

转载 作者:行者123 更新时间:2023-11-30 03:51:12 24 4
gpt4 key购买 nike

我有 3 个类(Cat、HouseCat:Cat、Lion:Cat)。我想做的是更改 HouseCat 的 VTable,让 HouseCat 吃肉而不是猫食。

我使用的类:

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;
};
};

我正在尝试通过我创建的 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);
}
};

我确认 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;

}

它输出了;

-------------- BEFORE EDIT ----------------
Base:
0031106E
0031121C
HomeCat:
00311285
0031121C
Lion:
0031106E
003113F2
-------------- AFTER EDIT -----------------
Base:
0031106E
0031121C
HomeCat:
0031106E
0031121C
Lion:
0031106E
003113F2

可以看到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]

问题是函数的输出根本没有改变。

---Base---

Meat2

Meow!2

---Lion---

Meat2

ROAR!2

---Home---

Cat Food2

Meow!2

---End---

我使用的是 Visual Studio 2013。发布/调试也没有什么不同。

我是不是在我的代码中做错了什么,还是我缺少某种编译器的东西?

最佳答案

我同意这是一个可怕的 hacky 事情......但是,为了让它工作我会尝试改变你的 lion/base/ home 变量是指向对象的指针。现在,由于它们不是指针,编译器可能会在不使用 vtable 的情况下自动调用正确的函数(因为它确切地知道对象是什么类型)。

关于c++ - 更改表条目没有重定向功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31418755/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com