20120701

Чуть-чуть в догонку про vTable.

В видео я рассказывал про таблицу виртуальных функций (VTable). Что это такое, по сути?

Создаётся некий объект MyObj, который умеет две функции - Init() и Destroy():

class MyObj
{
   virtual void Init() {}
   virtual void Destroy() {}
}


var myObj = new MyObj();

Как только создаётся такой объект, с ним в памяти ассоциируется таблица функций, в дизассемблированном виде выглядящая как:

...
jmp init
...
...
jmp destroy
...

Если смотреть на это с точки зрения Direct3D, то все реализации (код) функций лежат в dll с именем d3d.dll, а когда создаётся новый объект d3d - получается вот такая картина:

Игровой код:
call [d3d+0x123]


vTable:
0x123: jmp init


d3d.dll:
0x456: init

Т.е. созданный объект стучится в присвоенную ему vTable, находит там (по смещению от начала) нужную функцию, а уже она указывает на конкретную реализацию в библиотеке.

Помните смещение из видео? [ECX+0AC]? 0xAC = 172 в десятичной системе счисления. 172/4 = 43. Почему делим на 4? Потому что все указатели (а vTable - это таблица указателей) занимают ровно 4 байта. Отнимаем ещё 4 байта (первые 4 - указатель на саму таблицу) - получаем, что Clear() находится на 42-й позиции в vTable. И это всегда так (для данной версии DirectX). Приятность тут в том, что это не зависит от игры. Никак. Если 20 игр используют эту версию библиотеки - во всех играх эта функция будет находиться по этому смещению в vTable.

Нам остаётся только как-то найти всё это дело, не вмешиваясь особо в код игры.

Комментариев нет:

Отправить комментарий

Не люблю мат и низкий уровень грамотности. Чем конкретнее поставите свой вопрос и чем лучше он будет выглядеть - тем большая вероятность на мой ответ. :)