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

时间:2015-07-14 22:51:24

标签: c++ function reverse-engineering compiler-optimization vmt

我有3个班级(Cat,HouseCat:Cat,Lion:Cat)。 我想要做的就是改变HouseCat的VTable,让HouseCat吃肉而不是猫粮。

我使用的类:

query_hash

我正在尝试通过我创建的VTable结构来编辑这些类的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 [0] = eat(),所以我决定尝试对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);
    }
};

它结束了;

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;

}

您可以看到HomeCat [0]已从0x311285-> 0x31106E

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

问题是功能的输出完全没有改变。

  

--- ---基

     

Meat2

     

喵!2

     

--- ---狮子

     

Meat2

     

怒吼!2

     

---首页---

     

Cat Food2

     

喵!2

     

--- ---完

我正在使用Visual Studio 2013.发布/调试也没有任何区别。

我在代码中做错了什么,或者是我遗漏的某些编译器东西?

1 个答案:

答案 0 :(得分:2)

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