简体   繁体   English

更改VTable条目不会重定向功能吗?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM