Pull to refresh

Comments 31

Самая свежия версия Unity Assets Explorer лежит на дропбоксе. На Nexus'е версия немного устарела.
Начал делать ее еще в январе 2013го для русификации игр на Unity. Первой ласточкой стала One Late Night.
За перевод статьи спасибо.
Обновил ссылку в статье. Спасибо.
Для декомпиляции и просмотра managed-кода .NET библиотек (коими и являются наши жертвы) существуют довольно удобные и при этом бесплатные утилиты: IlSpy и dotPeek.

Еще удобная программа .NET Reflector с плагином Reflexil. Помимо просмотра позволяет еще и править код. Что может использоваться как для взлома игр, так и активации всяческих чит-режимов или исправления багов.
Рефлектор платный, плюс ко всему его делали те же ребята, что пилят сейчас ILSpy, так что полагаю там этот режим тоже введут.
Я бы для декомпиляции IL рекомендовал использовать dnSpy, форк ILSpy от известного 0xd4d (автор Confuser, de4dot и многих других полезных продуктов).
Там много полезных вещей для реверсера — отладка, редактирование без пересборки, более устойчивая к обфускации dnLib (вместо Mono.Cecil) и т.д.
4 года назад после вашего комментария начал юзать dnSpy, и по сей день пользуюсь. Удобная классная штука. Спасибо вам =)
Есть еще такой вариант, как проверить, играет ли пользователь со взломанной .apk-шки (т.е. используя патченную Assembly-CSharp.dll) — хранить хеш сборки на сервере для каждой версии. При старте игры вычисляется хеш локальной сборки, затем отправляется серверу. Сервер ее проверяет, и, если она неверная, запоминает это. Затем через определенное время включается банхаммер, и всем юзерам, от которых был прислан неверный хеш, присваивается бан, показывается окно «поди прочь» (или еще что-то, зависит от реализации). Конечно, вычисление и отправку хеша нет смысла класть в Assembly-CSharp — если в ней поломали уже что-то, то могут поломать и это, а значит нужно как можно меньше зависимости от c# и java. Вариант — сделать либу на JNI, которая этим занимается. Тогда ее использование сводится к строке System.loadLibrary(«you_native_library_name») (при использовании JNI_OnLoad), которую найти посложнее. Но и это не гарантирует полной защиты, конечно. Тем не менее планка взлома слегка повышается. Так же, отложенный банхаммер не дает сразу понять читеру, на основании чего он произошел.
Ничего не мешает изменить dll и отправлять корректный хэш.

Недавно как раз отучал от защиты Битву чемпионов от kabam.

1. На данные, отправляемые на сервер, вычисляется hmac и добавляется в сообщение.
Соль зашита в игре.

2. При логине происходит следующие действия
Вычисляется sha1 для dll файлов в папке managed и отправляется на сервер
Если хэш верен, то в ответ приходит соль, с некоторой модернизацией которой вычисляется hmac все тех же dll

Все вычисления и логика встроены в so библиотеку.
Расковыряв алгоритм, в классе защиты заменил вызовы внешней библиотеки на реализующий его код.

Профит. Теперь можно менять тем же рефлектором все что нам нужно
Я не писал, что что-то этому мешает, вопрос лишь в сложности. C# сборку легче расковырять чем найти .so и расковырять ее. Соответственно, из .so не должны торчать концы (кроме как loadLibrary), и уж точно она не должна общаться или обмениваться данными с managed-кодом (в идеале). Опять же, расковырять все что угодно можно, конечно. Но иногда достаточно увеличить сложность взлома, и энтузиастов это сделать может уже не найтись. А могут и найтись :)
Если бы логику отправки хеша встроили в .so причем зашифровав содержимое каким AES-ом с ключем, забитым там же в native — врядли бы вы что-то с этим сделали.
Пффф, это только немного усложнит задачу
Напишите, как бы вы взломали? А то вы привели слишком много аргументов.
Я так понял вы имели ввиду зашифровать код, который отправляет хеш. Т.к. ключ зашит в саму либу, то просто ищем место когда расшифровывается код, оттуда берем ключ и адреса по каким идет расшифровка. Расшифровываем сами код, патчим, шифруем обратно, заменяем либу, профит. Ну это вариант для симметричного шифрования. А если взять например RSA с ключом более 1024 бит, то такой трюк не прокатит. Тогда делаем немного по другому. Мы можем расшифровать код и посмотреть что и как там делается, узнаем адрес по которому нужно пропатчить. Далее в либе после кода расшифровки втыкаем переход на свой код, который патчит в памяти уже расшифровываний код, и переходит к дальнейшему выполнению оригинального кода. Это самые простые решения в лоб, но их может быть намного больше.
Как бы вы не старались защитить целостность файлов на клиенте это невозможно. И взлом защит не занимает много времени.
К примеру на ПК Eve Online считает хеши файлов и сравнивает их с образцом. Алгоритм зашит внутри своей библиотеки. Обходится довольно просто:

1) Берется EasyHooks
2) Вешается хук на fopen
3) При первом(2,3,4) срабатывании, когда считается хеш, подсовывается оригинал, во всех остальных модифицированный файл

Если файл считывается с диска один раз, то ищется функция хеширования и вешается на неё хук, туда идет оригинальный файл, во все остальные места уже модифицированный.
Разве я писал, что это возможно? Наоборот в конце подчеркнул, что вовсе нет
Вы не подчеркнули что это «принципиально невозможно», а все попытки только делают желания взломать тверже :)
«Расковырять можно все, что угодно» равно по смыслу «принципиально невозможно защитить», как по мне :) Я писал про то, что можно усложнить это по максимуму. Выводя проверку хешей в нативку, а баны и контрольные чеки различной логики на сервер. Если брать не сферический проект в вакууме, а реальный, этого часто бывает достаточно. Конечно, есть много факторов, которые на это влияют, в частности объем аудитории и тип проекта (оффлайн — онлайн — частично онлайн)
Нормально, спасибо за пост, еще бы «CHECKSUM» в реестре переименовать в популярный параметр который якобы используется в игре, и без реверса не будет понятно что hash вообще используется.

Трюк — заводим switch case конструкцию, определяем первые 2-3 варианта (которые по хорошему стилю кодирования должны быть наиболее часто встречаемыми) с похожими на правду параметрами, а настоящая работа будет проходить в других ветках или вообще в default. Потом самому не запутаться, но это чуть сложнее обфускации на которую будет антиобфускация :)
Как раз начал изучать вопросы анти-читов для своей игры; статья очень в тему, спасибо! Кстати, не пробовали ли использовать AntiCheat Toolkit из Asset Store? Какие есть о нём отзывы?

И ещё, интересно, как бы вы стали защищать взаимодействие с внешними сервисами? Вроде покупки каких-нибудь внутриигровых ништячков или выгрузки статистики из игры.
Клиент должен только совершать транзакцию и отправляет данные о ней на сервер для проверки.
Логику, различные проверки и данные пользователя хранить там же. Ключевая статистика только от сервера.
И всегда старайтесь выбирать для хранения типы данных, которые не позволяют параметрам применять отличные от задуманных значения. Опять же проверки, проверки и еще раз проверки. Все что приходит от клиента должно подвергаться сомнению.

В этом случае даже при изменении значений на клиенте на сервере это легко отслеживается и выписывается бан.

Опишу один из многочисленный фэйлов того же kabam в игре Герои камелота.

В игре есть «хранилище» с различными итемами (в том числе картами героев). Для всех итемов хранится их количество, но используют для этого не целое число, а с точкой. При этом при использовании на сервер уходит количество итемов. Отсутствие проверки на сервере дает два замечательных чита. Первый — это использование количества в виде 0.0000001. Что есть по сути бесконечный итем. Второе — использование отрицательных значений, т.е. возможность клонирования.

Возможно уже неактуально, но вы упомянули Anti-Cheat Toolkit.
Я был бы рад помочь, если у вас ещё есть по нему вопросы.
Эфемерная защита. Берем метод для дешифровки из приложения и получаем нормальный ассет
Автор статьи много полезных деталей опустил =(

Стоило бы упомянуть, что уже сейчас вполне можно применять IL2CPP как отличное средство защиты от просмотра и редактирования вашего кода.
Копаться в в коде, который хоть и предназначен для VM, но уже всё-таки нативный — то ещё «удовольствие» по сравнению с простым и доступным ковырянием IL.
IL2CPP пока доступен не на всех платформах, но развитие и добавление поддержки новых платформ не стоит на месте.

Кроме того, читеры ещё много чем увлекаются, применяют Speed Hack'и, Wall Hack'и, инжектят свои managed сборки прямо в Unity приложения и добавляют в вашу игру свои OnGUI менюшки, и это лишь малая часть.
в данный момент IL2CPP доступен только на Ios, на Android еще бета версия. а на остальных платформах вообще нету.
Вы забыли про WebGL, и я написал выше:
IL2CPP пока доступен не на всех платформах, но развитие и добавление поддержки новых платформ не стоит на месте.

Бэта под Андроид уже весьма стабильна (если сравнивать с первой публичной бэтой), что лишь прибавляет уверенности в том, что вскоре мы увидим IL2CPP и на других платформах.
гдеж это стабильно, когда при билде на андройд 5.2.2p2 ошибки летают?

p.s скрин IL2CPP под webGL (ей богу не нашел)
Стабильно, если сравнивать с первой публичной бэтой.
Я и не говорил, что он работает идеально и его можно смело использовать в продакшене. Но если сравнить то, что было в первой бэтке и то что есть сейчас — разница очень существенная.

Да и 5.2.2 может не содержать последнюю версию IL2CPP под дроид, её надо в 5.3 тестировать для объективных результатов.

p.s скрин IL2CPP под webGL (ей богу не нашел)

WebGL билдится только через IL2CPP, что вы не нашли — не понятно.
5.3 сама по себе еще бетка, действительно будете компилировать под Android IL2CPP свои рабочие проекты? может 5.4 альфу тогда лучше юзать? (уже есть). Покуда IL2CPP выйдет под все платформы, уж больно очень много времени пройдет, а вскрыть как консервную банку билд под Windows не составит труда. Так что статья пока что более чем актуальна, тем более статья публиковалась 2 месяца назад, или тогда IL2CPP под android тоже был нормальным по вашему?
p.s и в правду по умолчанию IL2CPP под WebGL используется. но Официальный релиз стабильной версии WebGL обещают к 5.4 версии.
Я знаю, что 5.3 ещё бэтка, но я также знаю, что вовсю готовится 5.3.0f1, т.е. не долго 5.3 в бэте оставаться осталось.
И я ещё раз повторю, что не призываю собирать рабочие проекты под IL2CPP Android, я лишь отмечаю, что работа по IL2CPP постоянно идёт, появляется поддержка новых платформ, фиксятся тонны багов и т.д.
Потому не упомянуть IL2CPP в статье в контексте защиты кода как-то неправильно.

вскрыть как консервную банку билд под Windows не составит труда…
статья пока что более чем актуальна

Я и не говорил, что статья неактуальна. Я отмечал, что она неполноценна и автор много полезных моментов в ней не отметил.

Кстати, всё описанное в статье никак не помешает вскрыть билд под Windows как консервную банку.
Даже раздел касательно защиты кода довольно таки скуп. Если уж использовать обфускаторы, то что-то посерьёзнее и посвежее, например Eazfuscator последних версий, или свой билд ConfuserEx.

статья публиковалась 2 месяца назад, или тогда IL2CPP под android тоже был нормальным по вашему?

2 месяца назад был IL2CPP iOS, IL2CPP WebGL, и уже был IL2CPP Android, не важно в каком состоянии, важно что к тому моменту уже было очевидно, что IL2CPP продолжает своё «наступление» и его нельзя игнорировать.

Официальный релиз стабильной версии WebGL обещают к 5.4 версии.

Ну так отлично же! Хотя как вам наверняка известно, это не мешает многим разработчикам запускать проекты под WebGL уже сейчас.
Поправка, 5.3 уже в RC стадии =)
Sign up to leave a comment.

Articles