![]() |
Часть 1- логин сервер
Как-то раз в далеком 2017 году понадобилось мне разобрать одну популярную мобильную игру того времени- Зитву Бамков. Я уверен, многим из вас приходилось играть в нее, когда она была на пике популярности. На данный момент игра стала умирать. Разработчики отдают внутриигровые ресурсы за копеечный донат. По просьбе знакомого, и из-за обесценивания этой информации, публикую обзор полного взлома игры: от реверса, до создания альтернативного сервера и накрутки валюты гильдии, на которую даже сделали обзор некоторые ютуберы (да-да, Князь, привет). За это время у меня сохранились не все материалы, которые стоило бы использовать в статье. Поэтому в части скриншотов будет показана старая версия игры, а в части- новая. Однако мой сервер все еще работает с новой версией игры. Значит, можно надеяться, что обновления обратно совместимы Изначально разбор игры я прототипировал на питоне, итоговая версия написана на котлине. Примеры кода буду брать из итоговой версии, благо, котлин очень интуитивный, и наглядный. Интересующиеся могут самостоятельно перенести код на свой любимый яп. 0. Анализ стека технологий, и устройства игры Базовый этап, дающий представление о том, с чем придется иметь дело дальше Легко заметить, что приложение написано на cocos2dx. Например, если посмотреть smali код CastleClashActivity, можно заметить Код: Код:
.method public constructor ()VCocos2dx это c++ форк игрового движка cocos2d, написанного на питоне Если еще немного посмотреть smali код, то можно заметить, что он исключительно определяет не очень интересные функции-хелперы, и через JNI передает управление библиотеке libgame.so. Из чего можно сделать вывод, что самое интересное происходит в нативе 1. Анализ структуры траффика Самый очевидный ход перед погружением в реверс натива. Может дать представление об устройстве механизма работы с сервером. Для этой цели буду использовать андроид приложение packet capture. Оно удобно тем, что позволяет записывать трафик только нужного приложения. https://forum.antichat.xyz/attachmen...8454242742.png https://forum.antichat.xyz/attachmen...8454293032.png https://forum.antichat.xyz/attachmen...8515533097.png Что мы видим:
2. Реверс Нужен для анализа игровой логики Первым делом определим, как устроено взаимодействие с сервером на самом деле, и каким образом шифруются данные на клиенте За взаимодействие с сервером тут отвечает класс NetMessage. Вот его методы слева направо: https://forum.antichat.xyz/attachmen...8440295163.png За шифрование пакетов, очевидно, отвечают методы EncryptMsg, и DecryptMsg. Посмотрим на EncryptMessage https://forum.antichat.xyz/attachmen...8443657033.png Он использует метод ELangh класса Langh- набора криптографических утилит, который используется как синглтон. Всё приложение работает с одним его экземпляром Внутри творится криптографическая магия. Однако прогуглив интересные методы Langh, я нашел библиотеку, которая, похоже, была перепилина в этот класс- http://read.pudn.com/downloads190/sourcecode/crypt/891222/DES Tool/yxyDES2.cpp__.htm . Вот метод EncryptData из этой библиотеки, и кусок ELangh из игры. Почти одно и то же https://forum.antichat.xyz/attachmen...8446074734.png https://forum.antichat.xyz/attachmen...8444435111.png Значит, игра использует des для шифрования. Но, как мы знаем, des- блочный шифр. Какой паддинг используется для данных, размер которых не кратен 8 байтам? Как оказалось, никакого паддинга там и нет. Китайцы используют гениальное решение- шифруют packet_data[acket_data_size // 8] (в терминах питона), и дописывают в конце packet_data[packet_data_size // 8:] в исходном виде. По-моему это очень странно. Оставим это дело на их совести Для создания декодера пакетов осталась всего одна деталь- ключ des. Поискав по xref'ам метода Langh::InitializeK, я быстро нашел установку ключа https://forum.antichat.xyz/attachmen...8446891114.png Им оказалась строка "L*#)@!&8". У нас есть все для создания прокси-сервера, который будет декодировать, и логировать пакеты 3. Пишем прокси-сервер Для начала нам понадобится менеджер шифрования, который мы будем использовать для дешифрования тел пакетов от клиента. На котлине он выглядит так https://forum.antichat.xyz/attachmen...8449898472.png Описываем интерфейс пакета https://forum.antichat.xyz/attachmen...8450087330.png И три сущности: ClientPacket, EncryptedClientPacket, ServerPacket, Packet(для унификации механизма чтения и отправки пакетов. Кастится к EnctyptedClientPacket, и ServerPacket) Делаем чтение, и отправку https://forum.antichat.xyz/attachmen...8493154475.png Прокси логин-сервер будет состоять из двух корутин Первая получает пакет у клиента, дешифрует (превращает EncryptedClientPacket в ClientPacket), печатает нам его содержимое и отправляет на сервер Вторая получает пакет у сервера, печатает содержимое, и отправляет клиенту Итоговый код прокси логин-сервера у меня выглядит так: Код: Код:
class LoginServer(serverIp: String = "0.0.0.0", val loginServerIp: String) :Деплоим свой конфиг, скопировав содержимое оригинального, c нужным адресом в секции LoginServer. Меняем адрес конфига в assets/config.xml на наш. Пересобираем приложение В расшифрованных телах пакетов клиента в первых четырех байтах идет инкрементирующееся чисто- порядковый id отправленного пакета. К сожалению, архитектура у меня не позволяет выводить полное содержимое пакета, ибо при инжекте пакета старый порядковый id будет все ломать. Поэтому я не смог показать полные данные пакета с ним. Вот вывод моего реверс прокси. Как видите, у меня организована авторазметка пакетов https://forum.antichat.xyz/attachmen...8453839358.png При подключении клиент сервер отправляет igg id, токен, и версию игры В ответ логин сервер отправляет данные игрового сервера, и игровой токен |
Прикольно, можно попробовать)
|
я немного потерялся, ты пишешь про exe, java, более конкретней можешь.
- исследуем такое то приложение, столько то файлов, такие и такие я исследую тем, а такие темто и т.д.... прикольно, но получилось как фильм от первого лица когда главный герой снимает камерой, а все остальное додумуй сам))))))))))) а так от меня лайк))) |
Я 0 в реверсе но статью прочел полностью очень интересно!
|
| Время: 16:47 |