Данная статья представлена исключительно в ознакомительных целях и не несет призыва к действию. Вся информация направлена на то, чтобы уберечь читателей от противозаконных действий.
Категорически запрещено использование разработки для совершения любых противоправных действий.
Реверсивная инженерия — изучение того, как устроено какое-то программное обеспечение, с целью понять механизм его работы. Эта информация может использоваться в будущем для создания похожего продукта или внесения изменения в уже существующий.
Я хочу рассказать о том, как с помощью реверсивной инженерии можно вносить изменения в игры на ПК. Не обязательно с целью взлома, иногда это используется для исправления багов, которые разработчики не исправили по каким-то причинам.
Как это работает
Когда мы пишем какое-то ПО, то чаще всего, мы выбираем инструментарий, подходящий лучше всего под эту задачу. В современных играх код пишется на компилируемых языках высокого уровня. Конечно, можно вспомнить Minecraft на Java, который в конечном итоге все-таки переписали на плюсах.
Здесь стоит уточнить, что часто та часть приложения, которая критична для производительности, пишется на компилируемом языке, в то время как логика может быть на чем-то скриптовом, типа Lua, который уже обращается к ядру движка.
Код на языке высокого уровня с помощью компилятора превращается в машинный код, состоящий из инструкций для процессора определенной архитектуры. При запуске, процессор последовательно выполняет инструкции, а наше приложение работает.
А как мы можем на это повлиять?
Для того, чтобы внести изменения в ход работы программы, нам необходимо отредактировать эти самые инструкции. Для этого нам потребуется определенный инструментарий, позволяющий нам внедряться в работу программы. Основным инструментом нам послужит дебаггер, я пользуюсь x64dbg.
Дебаггер — программа, которая подключается к (например) игре и позволяет ковыряться в ней во время ее работы. Она позволяет выполнять инструкции последовательно, менять содержимое регистров и стека.
Регистры — это небольшие участки памяти процессора, которые он использует при выполнении команд. У каждого регистра есть своя задача, например, один используется для возвращаемого функцией значения, другой хранит в себе аргументы, а третий — следующую инструкцию, которая будет выполнена.
Стек используется для хранения информации, которая используется программой. Он нам мало интересен, кроме его особенности в хранении информации в упорядоченном виде.
Вот так выглядит приложение под в режиме отладки (дебага) в x64dbg
Хватит нудятины, когда будем взламывать?
Уже скоро, осталось только уяснить особенности взлома игр и способы достижения результата.
Получение дополнительных ресурсов
Тут все предельно просто — находим ячейку в памяти, в которой хранится количество патронов или жизней, меняем на то, которое позволяет собственная жадность. Главное, чтобы жадность не превышала размер типа данных, иначе приложение рухнет. Этим многие из нас баловались еще во времена ArtMoney.
Хочу видеть через стены!
Это посложнее, здесь мы уже перехватываем выполнение функций графической подсистемы. (Чаще всего DirectX или OpenGL). Для этого мы создаем динамическую библиотеку DLL, которая меняет адрес нужной нам функции на нашу, которая потом вызывает и оригинальную функцию, и наш код, рисующий врагов!
это поведение у кукушек.
Хочу раздавать хэдшоты в каэсочке!
Здесь мы тоже получаем информацию о противниках из памяти игры, а разница между позицией игрока и противника и будет вектором, куда нам надо стрелять. Останется только повернуть игрока в нужном направлении, раз он сам не в состоянии.
Ну что народ, погнали?
Поскольку в реальной жизни отладка занимает просто колоссальное количество времени, мы опробуем свои силы на чем-то простом, чтобы уложиться в рамки статьи. У меня под рукой оказалась The Outer Worlds, над которой мы сегодня и будем паразитировать.
В игре есть механика заточки оружия, платим деньги — получаем улучшенное оружие.
Первым делом попробуем исправить баг с необходимостью платить за это. Для этого найдем в памяти адрес, где хранится количество украденных предварительно денег. Проще всего это делать все-таки с помощью Cheat Engine, ибо он дает возможность быстро отсортировать измененные значения и показывает адрес памяти.
Находим количество денег, тратим немного, фильтруем те значения, которые нас устраивают. В итоге остается одно значение, которое и является нашим количеством денег.
Теперь берем адрес памяти, в котором хранятся деньги, подключаем дебаггер к игре и просим его оставить выполнение программы, если она попытается изменить значение переменной в следующий раз.
Синяя линия внизу — текущая команда процессора. Именно в этом месте и меняется значение денег. Огибающие линии сверху показывают, что мы находимся в нескольких уровнях вложенности, а команды jl как раз и являются проверками каких-то условий.
Далее мы поднимаемся немного наверх, добираемся до начала функции и попеременно меняем условия, которые в дебаггере подсвечиваются желтым цветом. Опытным путем мы узнаем, что если третье условие сработает, то мы не потратим деньги. Почему? Хороший вопрос, для этого надо проследить ход выполнения программы более внимательно, но результат не хочет ждать, поэтому вместо условия jl ставим безусловный переход командой jmp и наслаждаемся бесплатными улучшениями.
Самое сложное в реверсивной инженерии то, что изначально мы как слепые котята тыкаемся и меняем условия с надеждой на достижение результата. Но если разобраться в том, что делают команды и как работают компиляторы, то со временем вы начнете находить логические последовательности, понимать, как передаются в функции аргументы и т.д.
Исправление ошибки с максимальным уровнем снаряжения
Еще в игре есть досадная ошибка разработчиков, влияющая на баланс, — оружие можно улучшать только на пять уровней выше персонажа. Что ж, исправим это!
Первым делом необходимо найти в памяти уровень персонажа. Это можно сделать предварительно накрутив себе опыта. Как только у нас есть информация об уровне персонажа, мы снова любезно просим дебаггер приостановить работу игры в момент обращения к памяти по этому адресу.
Когда нужно что-то найти в памяти, Cheat Engine приходится очень кстати. Чаще всего необходимо найти базовый адрес, это делается довольно просто, но немного выходит за рамки статьи.
Игра показывает нам сообщение о том, что нельзя улучшить снаряжение, когда мы наводим на него курсор, а чтобы убедиться в этом, ей необходимо сравнить уровень снаряжения с текущим уровнем игрока. Именно в этих местах мы вместо уровня персонажа подсунем ей число.
Редактируем команду — заменяем обращение к адресу в памяти [rax+310] константным значением 1000
После чего доверчивая игра позволяет нам ковать столько, сколько вздумается.
Обратите внимание на уровень персонажа и уровень винтовки, теперь можно отыгрывать Men In Black, у нас же все-таки рпг, не так ли?
Фиксируем прибыль
После того, как мы исправили все баги в игре, мы хотим чтобы они больше не появлялись ни у нас, ни у наших друзей. Для этого мы должны пропатчить исполняемый файл игры. Исправляем файл, кладем рядом с оригинальным и в следующий раз запускаем уже его.
Список изменений в программе, которые будут внесены в исполняемый файл
Таким образом мы с вами познакомились с чудесным миром реверсивной инженерии, разобрались, как взламывают игры и, на примере The Outer Worlds, исправили несколько багов в игре. Конечно, в реальной жизни это занимает гораздо больше времени и чаще всего взлому подвергаются онлайн-игры, которые имеют свою специфику из-за клиент-серверной архитектуры, но принципы работы остаются те же.
В этом видео покажут и расскажут о том, что такое реверс инжиниринг (обратная разработка) и для чего он нужен! (ДЛЯ НОВИЧКОВ)
Ссылка на программу для реверс инжиниринга (CrackMe):
https://github.com/CyberDen1/CrackMe