修改VTable表项没有重定向功能
Changing VTable entries doesnt redirect function?
我有3个班级(猫,家猫:猫,狮子:猫)。我想做的是改变家猫的VTable,让家猫吃肉而不是猫粮。
我使用的类:
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]
问题是函数的输出根本没有改变。
——基础——
Meat2
喵!2
——狮子
Meat2
咆哮!2
——回家——
猫Food2喵!2
——结束
我使用的是Visual Studio 2013。发布/调试也没有影响
我做错了什么在我的代码或它是某种编译器的东西我错过了?
我同意这是一个可怕的黑客的事情…然而,为了让它工作,我会试着改变你的lion
/base
/home
变量是指向对象的指针。现在,由于它们不是指针,编译器可能会自动调用正确的函数,而不使用虚函数表(因为它确切地知道对象的类型)。
相关文章:
- 如何将stdout重定向到stderr
- 编写时C++中的输入重定向问题
- 获取通过重定向传入的输入文件的名称?
- Windows C++重定向库
- 写入文件 a.txt,而终端重定向到文件 b.txt
- 使用 dup2() 进行输入重定向
- 将 clangd stderr 重定向到文件而不是控制台
- 如何在C++中获取重定向网页的URL
- 将标准输出重定向到ostream
- 如何撤消此代码上的 cin 重定向?
- 使用重定向标准处理子进程中的 kbhit
- 是否可以将子进程的 stdout 重定向到父进程中的另一个文件?
- 重定向输入和输出时如何处理主文件I/O?
- 如何将HTTPS流量重定向到本地主机:443上的代理?
- 使用重定向命令从 stdin 读入的字符串"<"输入文件未正确附加
- 尝试在 Windows 上重定向 stdout 和 stderr——_fileno(stdout) 返回 -2
- 可以将Boost消息队列文件重定向到用户指定的位置
- 在程序执行期间从标准输出重定向到自定义流
- Lua 5.2重定向打印功能
- 修改VTable表项没有重定向功能