Исходный код terraria

Обновлено: 02.07.2024

Terraria Source Code 1.2.0.3.1

Only for educational use.

Releases

No releases published

Languages

  • © 2021 GitHub, Inc.

You can’t perform that action at this time.

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.


Надеюсь, все хотя бы раз играли в такую замечательную игрушку, как Terraria, ведь сегодня речь пойдет о ней и о том, как не стоит писать игры с точки зрения безопасности. Если интересно — добро пожаловать под хабракат!

Начнем, пожалуй, с того, что такое Terraria и как она появилась.

Феноменальный успех неизменно пребывающей в разработке «песочницы» Minecraft, уже принесшей Маркусу Персону миллионы, не мог остаться незамеченным. Так и случилось, вскоре появляется на свет Terraria. Занимается разработкой один единственный человек, Эндрю Спинкс, главный дизайнер и по совместительству не менее главный программист.

При взгляде на здешние «восьмибитные» пейзажи услужливое подсознание сразу спешит навесить ярлык «Minecraft в 2D». А что? В рюкзаке — кирка и топор, вокруг — случайно сгенерированные просторы. Цель — копать, строить, убивать, добывать.

Больше вы можете узнать, почитав специальные статьи об этой игре. Ну а хабр требует технической информации.

Как оно работает?

Купив игру, поиграв в нее около двух недель со своими друзьями — она мне немножко наскучила, я решил более детально изучить её структуру. Как особенности структуры — можно использовать в своих целях.


Открываем Terraria.exe, ищем точку входа Main (Program):

Видим забавные строки:


Т.е. если обычный пользователь возьмет файлы игры из папки стима и даст их другу, у которого этого стима нет — игра выдаст ошибку и откажется запускаться.

Для того, чтобы обойти эту «безопасность», достаточно подменить steam_api.dll (откуда импортируются функции) или же можно пересобрать приложение, закоментировав соответствующие строчки. Ведь сам Steam никак не влияет на игру, кроме того, что добавляет туда свой Layout. Но мы пойдем более интересным способом и попробуем даже влиять на саму игру.

Вспомним, что игра написана с использованием — XNA, а значит, у нее должен быть главный класс игры, который наследуется от Microsoft.XNA.Framework.Game, далеко идти не пришлось, это класс Main.

Любая игра, написанная на XNA, имеет в себе, так называемые «компоненты», которые можно туда добавить. Компоненты могут быть как обычными (логика), так и графическими (Drawable).

А теперь давайте подумаем, что можно сделать?

Главный класс у нас Main и он имеет модификатор public (public class Main: Game )!
Чем это грозит? Мы можем создать новое приложение, которые будет импортировать наш Terraria.exe в качестве библиотеки и запустит её, а дальше — можно добавить свой компонент игры, и этот компонент будет иметь почти полный доступ к игре.

Пройдясь еще по всяким классам, увидим, что основная идея этих классов — это индийская версия синглтона статический доступ, который, кстати, тоже public.

Стоило бы придать главному классу модификатор доступа отличный от public, как все бы у нас провалилось.

Потом, я еще раз взглянул на класс Main, у него отсутствовал модификатор sealed, что так же доставило и упростило мне жизнь. Идея стала куда проще: просто унаследоваться от нашего Main.

Создаем новое консольное приложение, подключаем в качестве библиотек Microsoft.Xna.Framework.*, Terraria.exe.

Теперь создадим класс, который будет наследоваться от Main:


Теперь идем в точку входа и заставим запустится наш игровой класс:


Ну и нарисуем что-нибудь, добавим в наш переопределенный Draw:


Результат:

Работает, а значит, мы можем рисовать какие-то данные, например, где находится сундук с пиратскими сокровищами, ведь весь доступ к логике у нас есть.

Ну и напоследок сделаем что-нибудь эффектное, какой-нибудь хак.

У игрока террарии есть одно интересное свойство: ghost, которое превращает игрока в каспера приведение и позволяет проходить сквозь стены и летать по миру (наверняка, фишка для девелопера). Так сделаем же так, чтобы при нажатии и удержании Left Shift — игрок становился злым и коварным.

Идем в метод Update:


Запускаем игру и становимся приведением по клику на шифт:

Как вы понимаете, рисованием текста и другим преферансом — дело тут не ограничивается, на игру можно влиять почти полностью, отдельно надо сказать про кривость синхронизации мультиплеера — все эти изменения им не пресекаются и дают играть на серверах с этими хаками.

Отдельно хочется сказать про класс Player, где есть функция Save/Load, которая позволяет сохранять и загружать игроков соответственно, принимает и отдает она сам класс игрока Player. Т.е. мы можем изменить игрока чуть менее, чем полностью, сохранить его и использовать в игре. Или же, например, сохранить всех игроков на сервере в файлы, а потом закинуть их в папку Players и играть ими.

Всегда используйте модификаторы доступа как надо, а классы, которые конечны — sealed (запрещает наследование). Для таблетки от паранойи верности можно еще и обфусцировать код.

Так же, если реализуете мультиплеер — сделайте достойную синхронизацию и так, чтобы вся логика проверялась на сервере, а в случае резкого несоответствия — отключать игрока. К примеру, как игрок может моментально переместиться из одной точки карты в другую за время, которое меньше секунды? Увы, сервер террарии считает это нормальным.

Эта статья писалась исключительно в ознакомительных целях: как на примере простых модификаторов — можно написать нехилый хак.

Сначала файл с данными пользователя был скормлен WinHex'у и получен от него следующий результат:


ildasm.exe Terraria.exe /source /out:Terraria.il

Получив довольно понятный код на CIL мной были найдены методы Player::EncryptFile и Player::DecryptFile. Исследование их и контекста их использования показали, как проходит процедура загрузки/сохранения пользовательских данных.

  1. Сначала файл player1.plr расшифровывается в player1.plr.dat
  2. Далее считываются данные из player1.plr.dat и записываются в оперативную память (размер файлов <1КБ )
  3. После сих действий файл player1.plr.dat удаляется.
  1. Запись данных из оперативной памяти в player1.plr.dat
  2. Шифрование player1.plr.dat в player1.plr
  3. Удаление player1.plr.dat

Смотря на такой алгоритм, становится понятно, что все «вкусняшки» содержатся в файле player1.plr.dat. Но, к сожалению, все действия с ним происходят настолько быстро, что его даже не успеваешь заметить в «Проводнике». И тогда в исходниках была обнаружена функция, которая удаляет данный файл. Закомментировав данную функцию и пересобрав файл, цель была достигнута.
Кстати говоря, для пересборки файла была введена следующая команда в ещё запущенную консоль:

ilasm.exe Terraria.il /exe /out:Terraria.exe

Отлично, после запуска игры, файл player1.plr.dat наконец-то в моих руках.
Как и ожидалось, в нём все вкусняшки:


Использование в своих целях

Ну хорошо, файл мы получили, а теперь попробуем с ним разобраться.
Понял я там далеко не всё, но вот то, что я понял:


Так как это пользовательский файл, то он содержит данные о пользователе: сначала длина ника (красным), затем сам ник (зелёным). Далее идёт «здоровье» персонажа на момент выхода из игры (розовым) и вообще максимальное значение здоровья (коричневым).

About

No description, website, or topics provided.

Resources

License

Packages 0

No packages published

Читайте также: