Вы используете устаревший браузер. Этот и другие сайты могут отображаться в нём некорректно. Вам необходимо обновить браузер или попробовать использовать другой.
насколько я знаю vmt это не метод хука
метод хука это vmt hooking
я же спрашиваю что такое vmt просто напросто и всё
я не могу просто начать хукать через него мне просто нужно понять что это такое
Это результат использования virtual в C++, такой префикс ставится перед функциями, когда ты хочешь указать что они виртуальные.
Применение очень простое, обычно чтобы вызвать какой-то метод класса, тебе точно нужно знать какого типа этот объект на этапе компиляции, но виртуальные функции позволяют тебе реализовать абстрактный интерфейс, т.е. есть базовый класс который описывает что есть некие функции, но как они будут реализованы зависит от конечного класса, который может их переопределять.
При этом ты можешь работать с объектом как с абстрактным классом, не зная деталей его реализации, а вызываться будут именно методы конечных классов.
Теперь о том что такое VMT, это то, как этот механизм реализован в бинарном виде.
Попросту для каждого класса с виртуальными методами содержится таблица их адресов в секции константных данных.
Затем при создании объекта в самое начало данных записывается указатель на эту таблицу.
При вызове виртуального метода, компилятор именно подставит чтение адреса из вирт. таблицы, а не конкретный адрес в бинаре.
Это часто используется в играх, в CS GO в том числе.
Некоторое время хук вирт. таблиц был неплохим сложно обнаруживаемым методом хука, т.е. ты просто меняешь адрес вирт таблицы на свою модифицированную копию, и т.к. данные объекта находятся в динамической памяти обнаружить такое невозможно, без знания семантики объекта.
Пример:
Код:
class Base
{
public:
virtual void func1() { printf("base1\n"); }
virtual void func2() { printf("base2\n"); }
};
class First : public Base // наследует
{
public:
void func1() override { printf("first1\n"); } // переопределяет
float val = 0;
};
class Second : public Base // наследует
{
public:
void func2() override { printf("second2\n"); } // переопределяет
bool val = false;
};
void Test(Base* obj)
{
obj->func1();
obj->func2();
}
Base base;
First first
Second second;
Test(&base);
Послав в Test base напечатается base1 и base2, если first то first1 и base2, а с second уже base1 и second2.
Без virtual методов, всегда бы печаталось base1 и base2, независимо от типа, потому что в параметре выставлен Base* и вызывались бы его методы.
Примерно так это выглядит в бинарном виде:
Код:
// вирт таблица Base::vftable
void* Base::func1 // 0000
void* Base::func2 // 0004
// вирт таблица First::vftable
void* First::func1 // 0000
void* Base::func2 // 0004
// вирт таблица Second::vftable
void* Base::func1 // 0000
void* Second::func2 // 0004
// содержимое base
void* vftable; // 0000 указывает на Base::vftable
// содержимое first
void* vftable; // 0000 указывает на First::vftable
float val; // 0004
// содержимое second
void* vftable; // 0000 указывает на Second::vftable
bool val; // 0004
Т.е. при вызове в Test компилятор просто читает vftable + нужное смещение, а без виртуальных методов просто бы подставлял конкретные адреса.