C++ 更改VTable条目不会重定向功能?
我有三个班(猫,家猫:猫,狮子:猫)。 我想做的是改变家猫的习惯,让家猫吃肉而不是猫粮 我使用的类:C++ 更改VTable条目不会重定向功能?,c++,function,reverse-engineering,compiler-optimization,vmt,C++,Function,Reverse Engineering,Compiler Optimization,Vmt,我有三个班(猫,家猫:猫,狮子:猫)。 我想做的是改变家猫的习惯,让家猫吃肉而不是猫粮 我使用的类: class Cat { public: int age = 2; virtual void eat() { cout << "Meat" << this->age << endl; }; virtual void sound() { cout << "Meow!" <&l
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;
};
};
您可以看到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]
问题是函数的输出根本没有改变
---基地---
肉2
喵喵!二,
---狮子---
肉2
吼叫!二,
---家---
猫粮2
喵喵!二,
---结束---
我正在使用Visual Studio 2013。发布/调试也没有什么不同
我的代码是做错了什么,还是缺少了某种编译器的东西?我同意这是一种可怕的黑客行为。。。但是,为了让它工作,我会尝试将
lion
/base
/home
变量更改为指向对象的指针。现在,由于它们不是指针,编译器可能会在不使用vtable的情况下自动调用正确的函数(因为它确切地知道对象的类型)。为什么要进行这种可怕的攻击,而不是一开始就正确地实现行为?我的意思是,你似乎在直截了当地说“让猫吃肉,然后让家猫吃猫粮,但我想让家猫回去吃肉,所以这里有一个可怕的混乱,我希望它会无缘无故地颠覆编译器”。@下划线\d我在试着理解VTables是如何工作的?因为当试图理解编译器被认为是“可怕的黑客”时,您将试图理解一个特定实现的隐藏细节,从而学习一些不可移植的东西,作为通过正确使用继承以标准和可移植的方式完成语言已经提供的事情的一种方法。我不是要扼杀教育,但你从中获得的任何学习都几乎是无用的,也不是对所花时间的最佳利用。@下划线\d我可以利用我在这里获得的信息在虚拟类中钩住函数,当我为没有源代码的应用程序创建插件时,这些函数会很有用吗?我记得将其标记为“反向工程”。“HouseCat*house2=new HouseCat();”修复了这个问题,因此这是一个编译器优化。虽然我不明白为什么试图理解反向工程是“可怕的黑客”,谢谢你的回答;(
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
VMT.exe+11285 - E9 B6350000 - jmp VirtualMethodTable test.HouseCat::eat
[Cat Food]
->
VMT.exe+1106E - E9 ED450000 - jmp VirtualMethodTable test.Cat::eat
[Meat]