Изменение записей VTable не перенаправляет функцию?

У меня есть 3 класса (Cat, HouseCat:Cat, Lion:Cat). Я пытаюсь изменить VTable HouseCat так, чтобы 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]

Проблема в том, что вывод функций вообще не изменился.

---База---

Meat2

Мяу! 2

--- --- Лев

Meat2

ROAR! 2

---Главная---

Кошачья еда2

Мяу! 2

---Конец---

Я использую Visual Studio 2013. Релиз / Отладка также не имеет значения.

Я сделал что-то не так в своем коде или это что-то из того, что я пропустил?

1 ответ

Решение

Я согласен, что это ужасная хакерская вещь... однако, чтобы заставить ее работать, я бы попробовал изменить вашу lion/base/home переменные, которые будут указателями на объекты. Прямо сейчас, поскольку они не являются указателями, компилятор может автоматически вызывать правильную функцию, не используя vtable (поскольку он точно знает, какой тип объекта).

Другие вопросы по тегам