Как найти массивы объектов (сущностей, врагов) в игре, которую я реверсирую с помощью Cheat Engine?
Я делаю реверс игры с использованием Cheat Engine и OllyDBG, с помощью этого читаются и отслеживаются адреса памяти в FPS игре, эти адреса будут содержать координаты(xyz) врагов.
Моя цель - найти адрес или шаблон, который позволит мне перебрать до 32 врагов, чтобы прочитать все их координаты, для этого я пытался найти шаблон между каждым из их адресов, но безуспешно. Мне удалось собрать 3 различных адреса врагов, эта информация полезна, но поиск 32 адресов - задача, которая требует больше усилий, чем я считаю необходимым.
Как уже было сказано, у меня есть доступ к первым 3 адресам врагов, и если на основе этой информации можно проследить путь до базы либо через Cheat Engine, либо через другое программное обеспечение для обратной разработки, то я был бы признателен за этот процесс.
В конечном итоге мой вопрос заключается в том, есть ли способ обнаружить массив указателей в памяти по одному из его адресов, например, если у меня есть 3 координаты врага, могу ли я каким-то образом отследить место в памяти до адреса, который обращается ко всем 32 адресам врага, будь то с помощью Cheat Engine или другого инструмента реверсинга.
(ОП не уточнил, знает ли он, как устроены структуры. Похоже, он предполагает, что они не сложные. Я отвечу на более общий вопрос, чтобы избежать проблем локальности, предполагая, что структуры несколько сложны).
Немного способов найти другие структуры приходит на ум:
Сканирование памяти на наличие сигнатур
Когда у вас есть несколько примеров структур, возможно, самый простой способ найти экземпляры других структур - это найти совпадающие константы во всех трех структурах. Некоторые значения могут быть постоянными, представлять собой свойства, которые применяются ко всем вражеским сущностям в более высокоуровневом классе, передаваемом по наследству.
Плюсы:
Минусы:
Поиск по указателю
Возможно, где-то есть указатель на каждую сущность. Вы можете просто поискать в памяти адреса найденных структур и найти массив/структуру, в которой хранятся все сущности. Вы также можете пройтись по массивам, найденным в самих структурах, возможно, вы смотрите на связный список.
Плюсы:
Минусы:
Поиск конструктора/конструктороподобной функции
В объектно-ориентированном языке, таком как C++ или ObjC, или в процедурном языке, таком как C, должна быть функция, инициирующая структуру. обычно ее легко найти - первая функция, вызываемая после выделения объекта, довольно характерная сборка - в основном код инициализации.
Если мы говорим об ОО-коде, то поиск таблицы виртуальных функций или аналогичной конструкции позволит вам легко найти функции построения, пройтись по наследованию и найти хотя бы часть манипулирующих функций.
После получения конструкторов вы сможете легко получить все выделения и увидеть, где хранятся указатели.
Плюсы:
Минусы:
Реверсирование структуры
Этот способ требует немного больше работы по реверсированию, но позволит вам найти лучшие способы поиска сущностей. Используя Cheat Engine и IDA, вручную нанесите на карту структуру, элементы/члены, функции, которые манипулируют структурой.
Если есть какие-либо указатели, следуйте им и реверсируйте другие структуры, которые вам встретятся.
Плюсы:
Cons:
Примечание
по крайней мере для некоторых из упомянутых мною методов поиск указателей на все сущности при анализе программы может быть только первым шагом. Вы можете искать ссылки на сам список и получить лучший способ автоматического поиска сущностей при каждом перезапуске программы. Это устраняет некоторые из конс.
Сначала найдите адрес, который вы ищете. Затем выполните следующий цикл:
Пример:
Поиск параметра, находящего адрес
30000032
.Выясните, что основой этой записи является
30000000
.Проверка памяти - ничего причудливого вокруг.
Находим указатель на базу по адресу
20000004
.Выясняем, что основание записи -
20000000
.Проверяем память - по-прежнему ничего...
Находим указатель на базу по адресу
10000008
.Обнаружение базы по адресу
10000000
.Проверяю память - все указатели на искомые объекты находятся на расстоянии 12 байт друг от друга. (Очевидно, что это какая-то коллекция).
Последнее сканирование памяти для указателя, чтобы убедиться, что я не ошибся, на
0000040
.Нахожу указатель на эту коллекцию, а сразу за ним: количество объектов в коллекции.
Перезапустите игру/компьютер несколько раз, чтобы найти последовательный указатель на этот адрес.
Наградить себя пивом за хорошую работу.
Как найти базу: Мне нравится использовать "сканирование указателя", и проверять последнее смещение. Наименьшее из наиболее часто встречающихся, обычно является правильным.
Иногда я пытаюсь найти запись в начале выделенной памяти, и в этом случае я уверен, что что-то является базой.
Другой трюк - найти в памяти две записи, расположенные одна за другой, определить их "максимальный размер", и это означает, что база должна быть не дальше этого числа в памяти.
Как распознать коллекции: Большинство из них ИСКЛЮЧИТЕЛЬНО упорядочены, с определенным смещением, или имеют указатели на однотипные объекты.
Например, если у вас есть:
Это должно прозвенеть.
Имейте в виду, что такое выравнивание может случайно встречаться в источнике, поэтому попробуйте поискать: Данные игрока 3, Данные игрока 3 +/- 4, Данные игрока 3 +/- 8.
В любом случае, если вы найдете что-то подобное, скорее всего, вы действительно близки.
Это работает для меня, надеюсь, это сработает и для вас, ребята.