1) Допустим, адрес базы данных ac_client.exe равен 0x4000000 - означает ли это, что начало процесса выделено по этому адресу памяти?
Да,но более конкретно, это базовый адрес PE (Portable Executable), когда-то отображенный в памяти.Таким образом, в адресной базе у вас есть PE-заголовок, а затем множество структур, затем разделы исполняемого файла и т. Д.
2) Далее идет Image Base + Offset (ac_client.exe + 0x10F4F4) - означает ли смещение, что оно приведет вас к месту или функции внутри процесса из начальной точки?
Технически это называется RVA ( Относительный виртуальный адрес ; этоотносительно базового адреса модуля): существует разница между смещением (которое применяется к плоскому файлу на диске) и RVA (которое применяется к файлу, отображенному в памяти).Как только исполняемый файл отображается в памяти (хотя это называется загрузчиком ОС), он приобретает другую «форму», чем на диске, поэтому смещение - это не то же самое, что RVA.
Чтобы ответить на вашвопрос, да, он указывает где-то в модуле с именем ac_client.exe
.
3) В Cheat Engine я загрузил Assault Cube.Я искал ценность моего здоровья.Я нашел динамический адрес здоровья.Теперь мне нужно найти статический адрес, поскольку прямого указателя на здоровье нет, я нажимаю на опцию «найти, что обращается к этому адресу» - означает ли это, что я пытаюсь найти функцию, которая использует или передает мое динамическое здоровье?переменная?
Точно.
Я не знаком с Cheat Engine, но это можно сделать различными способами:
Статически: путем разборки кода и поиска любой перекрестной ссылки, которая указывает наместо интереса.По сути, когда код обращается к искомому значению, он делает это с помощью некоторых инструкций, операнд памяти которых указывает (или не очень далеко) на интересующее место.
Сканирование памяти: механизм поиска непосредственно в адресном пространстве процесса для всего, что указывает (или не очень далеко) на интересующее место.Если это происходит в разделе кода, у вас есть совпадение.В противном случае (например, где-то еще в разделе данных или в куче) попытайтесь найти любое местоположение кода, которое указывает на это новое местоположение.Принц и повторяйте, пока не найдете что-нибудь.
Смесь вышеперечисленного.
4) После нахождения статического адреса для здоровьястоимость.Я нашел смещение 0xF8.Также ac_client.exe + 0x10F4F4 -> 0x50F4F4 - люди говорят, что 0x50F4F4 - это базовый класс локального игрока, но как мне узнать это, если мне не сказали этого?Означает ли это также, что все игровые переменные находятся в классах?
Если игра с закрытым исходным кодом, вы должны перепроектировать ее, чтобы понять все тонкости игры, чтобы иметь возможность сказать это.Это занимает много времени, сложно, и у вас никогда не будет тех же «имен», которые предполагали оригинальные программисты.«Имена» (имена классов, имена функций, имена переменных и т. Д.) Не попадают в окончательный двоичный файл: вы теряете возможность видеть имена классов и их расположение.
Есть еще несколько случаев, когдавы можете восстановить эти имена, по крайней мере, в C ++ (например, когда у вас есть что-то под названием RTTI ) или если доступна символическая информация (разработчики игр никогда не отправляют отладочную информацию, за исключением нескольких случаев).
В вашем случае (насколько я вижу игра с открытым исходным кодом и на C ++) вы можете скомпилировать игру для себя с поддержкой отладки (технически для Windows это означает символическую поддержку, создавая PDB , когдасвязывание исполняемого файла).Затем поместите игру в символический отладчик (например, Windbg) или дизассемблер, затем спросите инструмент, что за функция / класс лежат в этом точном смещении / RVA.Это действительно просто, когда у вас есть символическая информация.
Некоторые языки (например, C #, Java) можно декомпилировать (! = Дизассемблировать), и вы можете напрямую получать все имена (классы, функции, переменные и т. Д.), Если только конечный двоичный файл не защищен от декомпиляции.
Означает ли это, что все игровые переменные все находятся в классах?
Это довольно сложный вопрос с множеством различий: во-первых, это зависит от используемого языка.Если это язык OO , то , вероятно, да, за исключением глобальных, статических и локальных переменных.Некоторые языки не имеют понятия классов, поэтому расположение объектов в памяти, которыми манипулирует игра, может быть совершенно разным в играх на Си и С ++.
Еще один важный момент: у вас также может не бытьсодержимое непосредственно в классе, на которое указывает член класса.
Допустим, у вас есть игра, в которой у игрока есть инвентарь (так что класс 'Player')имеет переменный элемент с именем «инвентарь»), который, вероятно, будет управляться какой-то сложной структурой (например, ассоциативный контейнер или даже чем-то более сложным).Поскольку эти сложные структуры динамически распределяются игрой (например, new в c ++ ), все объекты в инвентаре попадают в heap , но не непосредственно в самом классе.Распределение указывается (не обязательно напрямую) членом «инвентаря», но объекты в инвентаре находятся в другом месте в памяти.