как залезть в приложение на андроиде
Открываем и редактируем файлы Apk на устройствах Андроид
Привет всем. Здесь вы узнаете, как открыть файл apk на Андроид и даже поковырять его код. Не будем останавливаться на общих понятиях расширения apk, сразу перейдем к делу. Для этих целей создано приложение “APK Editor Pro”. Этот инструмент поможет открыть, а также редактировать apk файлы. Ссылки для скачивания приложены в конце статьи.
При помощи его я редактировал созданное в конструкторе приложение, так как некоторые ссылки и изображения (по умолчанию встраиваемые конструктором) не устраивали. Нет, я не программист и понимаю в кодах не больше вашего, но инструмент APK Editor позволяет работать с ним пользователям любого уровня от новичка до профессионала, так как оно имеет подсказки.
Как открыть Apk файл на Андроид
Содержание
Интерфейс APK Editor Pro
Главная страница содержит четыре кнопки:
Для редактирования используются первые две.
1. Первая кнопка открывает непосредственно файлик apk, сохраненный в памяти устройства. То есть, открывается встроенный менеджер, находите нужное место расположения редактируемого объекта.
Клик по нужному элементу вызовет окно, где нужно выбрать, что вы хотите делать.
Функция редактирования ресурсов позволяет изменять строки, файлики, манифест. Через эту функцию доступно практически все содержимое редактируемого файла.
Замена, подразумевает полную подмену одного файла на другой. Как правило, её используют для замены изображений, аудио и других элементов.
Общее редактирование поможет изменить название приложения, пакета, место установки, код версии, название версии.
2. Вторую кнопку используют в случае отсутствия файла apk, но при наличии установленного приложения. Выбираете из списка и приступаете к редактированию.
Клик на кнопку вызовет список всех установленных приложений. Здесь же можно переключиться между пользовательскими и системными.
Выбрав объект, открывается окно для выбора редактирования, но добавляется дополнительно “Редактирование данных”.
По-большому счету эта функция ничего интересного не даст, разве что только профи найдет в нем смысл.
3. Раздел “Помощь” – это одна большая подсказка по работе с некоторыми функциями: замена названия приложения, подмена фонового рисунка, ликвидация рекламы, перемещение данных на карту, удаление подозрительных разрешений.
В принципе инструкция написана неплохо, но при изучении советую внимательно изучить от начала и до конца.
4. Последняя кнопка “Выход” говорит сама за себя. Нажав её, приложение закроется.
Теперь на примерах рассмотрим использование приложения.
Как заменить картинку в приложении
1. Выбираем вторую кнопку “Выберете … из приложений”
2. Находим объект, который подвергнем испытанию, клик по нему.
з. Переход по “Замена файлов”
4. Выбрать “Изображения”
5. Долгое нажатие откроет окно:
Нам нужна замена. Заранее необходимо подготовить другой файл и закинуть его в устройство. Для этих целей я использую папку “Others”. По умолчанию она имеется в каждом устройстве.
6. Клик по готовому изображению произведет подмену.
7. Жмем “Сохранить” и ждем готового результата. Это может занять некоторое время, все зависит от размера приложения.
8. По окончании будет указан путь, куда сохраняется модифицированный файл. Прежде чем запустить новый apk, старый необходимо удалить.
Как удалить рекламу из приложения
Рекламный код может быть прописан где угодно, все зависит от её назначения. Мы рассмотрим стандартный способ. Этот способ описан в разделе помощь, но пришлось немного потратить время на разбор, так как названия папок и файлов немного не соответствовало. Видимо, информация устаревает.
Начнем сразу с пункта №3. Первый и второй выполняем как в первом примере.
Удаляем старый apk и устанавливаем новый.
В этом случае убрали рекламу только с главной страницы.
Работать с редактированием элементов лучше всего через программу AirDroid. Оно выводит экран смартфона на монитор компьютера. Приятней работать с нормальной клавиатурой, а не тыкать в малюсенькие кнопочки устройства.
Ссылки
С вопросом “как открыть apk файл на андроид” разобрались. Плюс ко всему мы можем его полноценно редактировать под свои интересы.
Где взять приложение выбирать вам, ссылки ниже.
Установить APK Editor
с Плэй Маркет (платно)
с 4PDA (со скидкой и …)
Декомпиляция и отладка Android-приложений
В статье будет рассказано о том, как подключить отладчик к Android-приложению и пошагово пройти через вызываемые методы, используя информацию, полученную после декомпиляции приложения.
В статье будет рассказано о том, как подключить отладчик к Android-приложению и пошагово пройти через вызываемые методы, используя информацию, полученную после декомпиляции приложения. Хорошая новость в том, что для отладки не требуются привилегии суперпользователя. Описанные техники могут быть очень кстати во время пентестов мобильных приложений, поскольку мы можем «проникнуть» в код во время работы программы, получить и записать информацию, к которой обычно у нас нет доступа. Например, можно перехватить трафик перед шифрованием и на лету получить ключи, пароли и любую другую ценную информацию. Статья будет полезна пентестерам и разработчикам мобильных приложений, желающих получить более глубокие знания о возможных атаках на платформе Android.
Требования к тестовой среде:
В статье будет использоваться следующая конфигурация: Windows 8, Android Studio и IntelliJ IDEA. Устройство: Nexus 4 с Android версии 4.4.4. Рекомендую все утилиты добавить в переменную окружения PATH, чтобы облегчить и ускорить доступ к этим инструментам.
Android application package (APK), используемый в статье, можно скачать отсюда: com.netspi.egruber.test.apk.
Инструкция ниже поможет вам подготовить устройство для экспериментов.
Активация раздела Developer Options
Для начала на Android-устройстве должна быть разрешена отладка через USB (опция USB debugging), что позволит «общаться» с девайсом при помощи инструментов из набора Android SDK. Однако перед этим необходимо активировать раздел Developer options. На устройстве зайдите в раздел Settings > About Phone и кликните несколько раз на пункт Build Number, после чего должно появиться сообщение о том, что раздел Developer options активирован.
Рисунок 1: Для того чтобы активировать раздел Developer options, необходимо несколько раз кликнуть на Build number
Разрешение отладки через USB
Чтобы разрешить отладку через USB-порт, зайдите в раздел Settings > Developer options и отметьте флажок напротив USB debugging.
Рисунок 2: Включение опции USB debugging
Подключение устройства и запуск ADB
После подключение устройства к компьютеру через USB-порт, должно появиться сообщение «USB debugging connected on the device». Также следует проверить, можно ли подключиться к устройству при помощи приложения Android Debug Bridge (ADB), входящего в состав Android SDK (пакет Android SDK Platform-tools). В командной строке введите следующую команду:
Устройство должно отобразиться в списке.
Рисунок 3: Список подключенных устройств
Если устройство не отобразилось в списке, то наиболее вероятная причина в некорректно установленных драйверах (в Windows). В зависимости от устройства драйвер можно найти либо в Android SDK, либо на сайте производителя.
Проверка приложения на возможность отладки
Перед отладкой Android-приложений вначале необходимо проверить, есть ли такая возможность. Проверку можно выполнить несколькими способами.
Первый способ – запустить Android Device Monitor, входящий в состав Android SDK (в папке tools). В Windows файл называется monitor.bat. При открытии Android Device Monitor устройство отобразится в разделе Devices.
Рисунок 4: Приложение Android Device Monitor
Если какое-либо приложение на устройстве можно отлаживать, это приложение также отобразится в списке. Я создал тестовую программу, но список пуст, поскольку программу отлаживать нельзя.
Второй способ проверить приложение на возможность отладки – исследовать файл AndroidManifest.xml из пакета приложения (APK, Android application package). APK представляет собой zip-архив, содержащий всю информацию, необходимую для запуска приложения на Android-устройстве.
Всякий раз, когда приложения загружается из Google Play Store, также загружается и пакет приложения. Все загруженные APK-файлы обычно хранятся на устройстве в папке /data/app. Если у вас нет прав суперпользователя, вы не сможете получить список файлов из директории /data/app. Хотя, если вы знаете имя APK-файла, можете скопировать его при помощи утилиты adb. Чтобы узнать имя APK-файла, введите следующую команду:
Появится командная строка устройства. Затем введите следующую команду:
Отобразится список всех пакетов на устройстве.
Рисунок 5: Перечень пакетов на устройстве
Глядя на список, находим тестовое приложение.
Рисунок 6: Пакет созданного тестового приложения (выделено белым)
Теперь необходимо скопировать файл пакета. Открываем шелл и вводим следующую команду:
adb pull /data/app/[.apk file] [location]
Рисунок 7: Копируем APK-файл с устройства в систему
Теперь нужно открыть файл пакета и исследовать содержимое AndroidManifest.xml. К сожалению, мы не можем просто так распаковать архив, поскольку APK-файл закодирован в бинарном формате. Для раскодировки чаще всего используется утилита apktool, хотя я использую APK Studio, поскольку у этого приложения дружелюбный графический интерфейс. Далее в статье будет рассказываться об APK Studio.
В APK Studio кликните на маленькую зеленую иконку, задайте имя проекту и укажите путь к APK файлу. Затем укажите пусть для сохранения проекта.
Рисунок 8: Создание нового проекта в APK Studio
После открытия APK выберите файл AndroidManifest.xml и посмотрите параметры тега application. Если флаг android:debuggable отсутствует (или присутствует, но установлено значение false), значит, приложение отлаживать нельзя.
Рисунок 9: Содержимое файла AndroidManifest.xml
Модификация файла AndroidManifest.xml
При помощи утилиты apktool или APK Studio мы можем модифицировать файлы и упаковывать содержимое обратно в пакет. Сейчас мы изменим файл AndroidManifest.xml так, чтобы приложение можно было отлаживать. Добавляем внутрь тега application строчку android:debuggable=»true».
Рисунок 10: Изменяем содержимое тега application
После добавления флага кликаем на иконку «молоток» и заново собираем пакет. Пересобранный пакет будет находиться в директории build/apk.
Рисунок 11: Повторная сборка пакета завершилась успешно
После пересборки пакет подписывается и его можно заново установить на устройстве (все Android-приложения должны быть подписаны). Большинство приложений не проверяет сертификат, при помощи которого происходит подпись. В противном случае необходимо изменить код, выполняющий эту проверку.
Теперь нужно установить пересобранный пакет. Вначале удаляем старое приложение при помощи следующей команды:
adb pm uninstall[package name]
Затем устанавливаем новый пакет:
adb install [.apk file]
Также можно удалить и установить пакет одной командой:
Рисунок 12: Установка пересобранного пакета
Проверьте, чтобы переустановленное приложение корректно запускалось на устройстве. Если все работает, переходим обратно в Android Device Monitor, где должно появиться тестовое приложение.
Рисунок 13: Теперь пересобранное приложение можно отлаживать
Настройка среды разработки (IDE)
Теперь к пересобранному приложению можно подцепить отладчик, но вначале нужно создать проект в среде разработки (в статье используется IntelliJ IDEA). Создаем новый проект. В поле Application name указываем произвольное имя. В поле Package name указываем имя, в точности совпадающее с иерархией папок пересобранного пакета.
Рисунок 14: Создание нового проекта в IntelliJ IDEA
Обычно имя APK-файла совпадает со структурой папок, хотя, если вы не уверены, в APK Studio проверьте иерархию директорий до папки, где находятся файлы приложений. В моем случае имя и структура папок полностью совпадают (com.netspi.egruber.test).
Рисунок 15: Иерархия директорий тестового приложения
Снимите флажок «Create Hello World Activity» и завершите создание проекта (все остальные параметры остаются по умолчанию). Новый проект должен выглядеть примерно так:
Рисунок 16: Иерархия папок и файлов нового проекта
После создания проекта нужно добавить исходный код из APK-файла для того, чтобы отладчик «знал» имена символов, методов, переменных и т. д. Хорошая новость в том, что Android-приложения можно декомпилировать практически без потери качества (исходный код будет совпадать с оригиналом). После декомпиляции исходный текст импортируется в среду разработки (IDE).
Получение исходных текстов из пакета приложения
Для начала необходимо преобразовать APK в jar-файл. Затем мы при помощи java-декомпилятора получим исходный текст приложения. Преобразование в jar будем делать при помощи утилиты dex2jar. У dex2jar есть файл d2j-dex2jar.bat, используемый для конвертирования APK в jar. Синтаксис команды довольно прост:
d2j-dex2jar.bat [.apk file]
Рисунок 17: Преобразование APK в jar
Затем открываем или перетаскиваем полученный файл в JD-GUI (это java-декомпилятор).
Рисунок 18: Структура jar-файла
Jar-файл должен отобразиться в виде иерархической структуры, внутри которой находятся java-файлы с читабельным исходным кодом. Заходим в File > Save All Sources, чтобы упаковать все исходные тексты в zip-архив.
Рисунок 19: Сохранение исходных текстов декомпилированного файла
После сохранения исходных текстов распаковываем архив в отдельную директорию.
Рисунок 20: Распакованный архив
Теперь нужно импортировать обе директории в созданный ранее проект в IDE. В IntelliJ заходим в папку src и копируем туда содержимое распакованного архива (две директории).
Рисунок 21: Обе папки скопированы в директорию src
Возвращаясь в Intellij, видим обновленный проект.
Рисунок 22: В проекте появились исходные тексты
Если мы кликнем на какой-нибудь элемент из списка, то увидим исходный текст. Как видно на скриншоте ниже (исходный текст класса LoginActivity), исходный код обфусцирован при помощи ProGuard.
Рисунок 23: Обфусцированный исходный текст класса LoginActivity
Теперь, когда в проекте появились исходные тексты, мы можем начать устанавливать точки останова на методах и переменных. По достижению точек останова приложение будет останавливаться. В качестве примера я установил точку останова на методе (прямо в обфусцированном коде), отвечающим за обработку информации, введенной в текстовом поле.
Рисунок 24: Поставлена точка останова на обфусцированный метод
Как только появилась точка останова, подключаем отладчик к процессу на устройстве, кликнув на иконку с экраном в правом верхнем углу (на вашей IDE иконка может отличаться).
Рисунок 25: Подключаем отладчик к процессу
Далее вам будет предложено выбрать процесс, к которому нужно подключиться. Будут отображены только процессы с флагом android:debuggable=»true».
Рисунок 26: Перечень процессов для подключения отладчика
После выбора процесса отладчик подсоединится к устройству.
Рисунок 27: Отладчик подключен к процессу, запущенному на устройстве
В текстовое поле я буду вводить число 42 (если помните, на соответствующем методе стоит точка останова).
Рисунок 28: В текстовое поле вводим число 42
После нажатия на кнопку «Enter Code» выполнение приложения прервется на точке останова, поскольку отладчик «осведомлен», какой метод вызывается на устройстве. Скомпилированное Android-приложение содержит отладочную информацию (например, имена переменных), доступную любому отладчику, совместимому с Java Debug Wire Protocol (JDWP). Если в приложении разрешена отладка, отладчик, совместимый с JDWP (в эту категорию попадает большинство отладчиков идущих в составе сред разработки для Java), сможет подсоединиться к виртуальной машине Android-приложения, а затем считывать и выполнять отладочные команды.
Рисунок 29: Сработала точка останова
На скриншоте ниже видно число, которое ранее мы ввели в текстовом поле.
Рисунок 30: Перечень переменных текущего экземпляра класса
Мы можем не только считывать данные в приложении, но и вставлять свои собственные. Это может быть полезно, если мы, например, захотим прервать поток выполнения кода и обойти некоторые участки алгоритма. При помощи отладчика мы можем лучше понять логику работы приложения и проанализировать то, что недоступно обычному пользователю. Например, может оказаться очень полезным просмотр используемых функций шифрования и динамические ключи. Кроме того, иногда при отладке полезно знать, как функции взаимодействуют с файловой системой или базой данных, чтобы понять какая информация сохраняется приложением. Подобные манипуляции доступны на любом Android-устройстве без привилегий суперпользователя.
Как посмотреть исходный код приложения Android
С каждым днем приложений для Android становится все больше и больше. Миллионы интересных игр и полезных программ можно найти в Play Market. Все они имеют удобный интерфейс и справляются с поставленной задачей. Без них сложно представить современный мир информационных технологий. Эта статья ориентирована на людей, которые не только ценят функционал и внешний вид приложений, а еще и интересуются их внутренним устройством.
Если Вам когда-либо было интересно, что находится «под капотом» любимого приложения, и вы немного смыслите в программировании — эта статья для Вас. Мы расскажем, как посмотреть исходный код приложения Android прямо на вашем гаджете. Поехали!
Общие сведения
Большинство программ для ОС Android, как и большая часть самой операционной системы, написаны на языке программирования Java. А это значит, что посмотрев в исходный код программ Android, мы, скорее всего, увидим Java код с использованием Android SDK (которая включает в себя инструменты платформы Android). Повторюсь: чтобы понимать исходный код приложений, нужно иметь базовые знания Java и принципы работы Android.
Как узнать исходный код приложений Android?
Для начала скачайте приложение, исходный код которого Вас заинтересовал. Затем зайдите в Play Market и скачайте утилиту под названием Show Java. Именно она будет заниматься декомпилированием. Установили? Отлично, а теперь перейдем к самому интересному — извлечению исходного кода Android программы. Запускаем Show Java.
Выберите нужное приложение из установленных, или найдите его на SD карте. Теперь нужно выбрать декомпилятор. Я обычно выбираю CRF. Если возникнут проблемы — пробуйте JaDX.
Начнется декомпиляция программы. Это может занять некоторое время. Чем больше приложение — тем дольше декомпилятор будет доставать исходные коды. Пока вы ждете результата, почитайте о перспективных языках программирования.
По завершению процесса вы получите список пакетов с исходниками Android приложения. Конечно, это не 100% копия кода, которую писали разработчики этого приложения. Но основная логика сохраняется, разобрать не сложно. Что делать с исходниками? Что угодно. Смотрите, разбирайте, возможно Вам будут интересны некоторые «фичи» или особенности реализации функционала программы.
Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.
Взломать мобильную онлайн игру? Легко!.
Под катом трафик на
800кб, 293 из которых – скриншоты кода (!)
Эта статья написана исключительно в ознакомительных целях. Автор не несёт никакой ответственности за любые действия пользователей, прочитавших статью. Любые совпадения в статье случайны.
Однажды, дождливым летним вечером мы с моей девушкой искали чем себя занять. Фильм смотреть не хотелось, но и вылезать из постели желания не было. Выбор пал на мобильную игрушку. Основных требований к игре было не слишком много:
Таким образом, мы нашли игру из топа Google Play. Чтобы не раскрывать имен, назовем ее игрой N. Правда, как оказалось позже, третий пункт из списка выше там реализован чуть более, чем никак.
Ниже я спрятал под спойлер краткое описание игры, читать его необязательно, но для полноты картины будет полезно.
Игра основывается на монстрах. Вы их призываете, качаете их и их спеллы, надеваете им руны, которые апают различные статы. У монстров, помимо привычных уровней (levels), существует еще и градация по звездам:
1 star – max level 15
2 star – max level 20
3 start – max level 25
и так далее до 6 звезд и максимального уровня 40. Достигнув максимального уровня, вы можете поднять монстру количество звезд, при этом его уровень сбросится до первого. Этот процесс в игре называется «Evolve». Чтобы это сделать, вам придется «съесть» других определенных монстров, например:
Призываться монстры могут множеством способов, но в конечном итоге сводится все к трем:
90-95%, что вы получите 3s, 4s падают редко, 5s монстры мне никогда не падали с этих свитков. Свитки можно в неограниченных количествах покупать за красные кристаллы. Падают очень редко)
Теперь о валюте игры:
Энергия – нужна для походов в PvE локации и данжи. Расход – от 3 до 8 в зависимости от локации. Копится по одной в 5 минут, часто падает прямо с убитых мобов. Существует потолок энергии, который увеличивается с уровнем игрока (не путать с уровнем монстров) и с помощью специального здания.
Арена энергия – используется для походов на арену, «PvP». О том, почему PvP в кавычках, вы узнаете чуть ниже. 1 поход на арену тратит 1 единицу арена энергии, максимум – 10, накапливается по одной раз в полчаса.
Синие кристаллы – основная валюта игры. На нее покупаются вещи из магазина, большинство зданий. Накапливается различными зданиями, падает с убитых мобов, дают в качестве награды за задания.
Красные кристаллы – второстепенная валюта, которую можно купить за реальные деньги. Их можно тратить на те самые свитки 3-5, на обновление энергии и арена энергии и покупать за них синие кристаллы. Очень редко они падают с убитых мобов или на арене. В день их можно заработать около 30-40, к слову, один свиток 3-5 стоит 75.
Очки славы – валюта, которую дают за победу на арене. За нее покупается очень много интересных зданий и предметов. Эту валюту нельзя приобрести за какую-либо другую или за донат.
Донатом в игре не давят. Все хорошо и спокойно проходится/покупается без вливания денег. Донат, по сути, дает вам только больше свитков, шансы получить бесполезных монстров с них те же. Приобрести конкретного монстра за донат нельзя (да и вообще никак нельзя).
Система боя напоминает Final Fantasy 7-10 или, если хотите, HoMM – пошаговый бой, на выбор 2-4 спелла. В подземельях от 3 до 10 уровней (чаще всего 3 или 5), на каждом уровне стоит пачка мобов, убиваете – проходите дальше, не убиваете – получаете все то, что успели заработать (кристаллы, энергия, опыт).
По поводу «PvP» и «совместной игры». Как оказалось, возможности играть вместе с человеком или против человека у вас нет. Играешь либо сам, либо на «автоатаке» и всегда против компьютера. Поэтому PvP тут довольно скучное. Заключается оно в следующем: каждый игрок выставляет на деф 4 монстра и покупает башни для защиты. Попадая на арену, вы деретесь против ИИ, который довольно глуп. Чтобы уравновесить это, через некоторое время по вам начинают палить те самые башни, с каждым разом все чаще и чаще.
Я – программист-удаленщик, поэтому работаю дома. А дома всегда хороший wi-fi, и я особо не задумывался, как и когда игра взаимодействует с сервером.
До тех пор, пока я не решил зайти в игру с мобильного интернета. Пробежав все уровни в очередном подземелье, я получил сообщение «Network connection is delayed. Resend Battle Results? (If Battle Results are not sent, the battle will count as loss.)». После того как я нажал на кнопку «Yes», результаты все же ушли на сервер.
Если вы прочитали описание игры, то и для вас многое встало на свои места: почему нет нормального PvP или игры вдвоем – игра связывается с сервером редко, скорее всего по HTTP, никаких сокетов. И самое главное — судя по всему, в этой игре клиент высчитывает результаты боя, а сервер их только получает.
Сразу же поэкспериментировав с отключением интернета в различные моменты игры, я выяснил следующее:
Идея 1. Подделываем запрос
Самая логичная идея, которая может прийти после описанного выше.
Для того, чтобы подделать запрос, нам нужен оригинал. Вариантов мониторинга трафика много, я выбрал самый простой для себя – пустить трафик через ноут и смотреть на все это с помощью WireShark.
Инструкции для превращения компьютера в точку доступа можно найти вот тут.
Чтобы было меньше лишнего «шума» в логах, закрываем все приложения и отключаем синхронизацию.
Во время загрузки игра подгружает информацию об акциях, партнерах, друзьях из фейсбука – в общем, трафика много, и он идет на разные сервера, поэтому нам не интересен. Заходим в локацию:
С первого взгляда видно, что это Base64. Но вбив текст в первый попавшийся декодер, я получил полную бессмыслицу, хотя ожидал JSON (шучу, это было бы слишком наивно – у приложения 10кк+ загрузок).
We need to go deeper ©
Скачиваем apk игры (вариантов много, я воспользовался этим). APK-файл – это обычный ZIP-архив, в нем находится много всего, но в первую очередь нас интересует файл classes.dex. Это формат Dalvik executable. По сути – скомпилированные Java-классы. Чтобы открыть их, нам понадобятся dex2jar и jd-gui. Первый преобразовывает dex в jar, второй пытается восстановить из jar исходный код.
То, что восстановит jd-gui, выглядит довольно кошмарно и read-only. Вам не стоит пытаться это скомпилировать. Исходники из jd-gui можно сохранить и открыть в вашем любимом редакторе. Я скачал 30-дневный триал IDEA от JetBrains, потому что очень люблю то, как в их продуктах сделан поиск (сам пользуюсь купленными PyCharm и PHPStorm).
Предупреждение для тех, кто предпочтет этот редактор – не выставляйте SDK, вас завалит ошибками.
Из программирования для андроид я знал только азы и не имел особого понятия, с чего мне начать свои поиски. Поэтому я запустил поиск «base64» по проекту, и нашел класс, реализующий Base64 decode и encode. Этому я очень удивился, потому что эти методы не были просто оберткой для библиотечных, а, судя по коду, действительно реализовывали кодирование и декодирование Base64.
Первая мысль, которая мне пришла – создатели написали что-то свое, что похоже на Base64, но кодируется по-другому. Так как код выглядит кошмарно (методы по тысячи строк, goto’s, инструкции в методах сразу после return и прочие радости жизни), то переписать это я бы не смог. Потом я вспомнил, что сервер написан на PHP, и решил не отчаиваться, потому что содержать две собственных реализации Base64 на двух очень разных платформах довольно накладно для разработки. Чуть позже я загуглил Base64 на Java и понял, что в стандартных Java библиотеках (6 и 7 версии) base64 кодирования нет, что окончательно отогнало мои страхи по поводу альтернативной реализации.
Поискав использование этого класса, я вышел на другой – StringEncrypter, который реализовывал несколько методов, но основные – decrypt и encrypt. Бегло просмотрев метод decrypt я понял, что это то, что мне нужно. Данные расшифровывались из base64, прогонялись через AES/CBC/PKCS7Padding и возвращались. Оставалось только найти ключ, который использовался для Cipher и начальный вектор (Initialization vector).
Для этого я начал искать использование этих методов. И обнаружил, что класс StringEncrypter нигде не используется. Это сильно меня удивило, но я подумал, что это огрехи jd-gui.
Я начал поиск по проекту заново, в этот раз я сразу искал Cipher. Результатов было много, и, бродя по ним, я наткнулся на файл, исходный код которого, видимо, восстановить не получилось. Вместо кода висело «INTERNAL ERROR». Запустив поиск этой самой «INTERNAL ERROR» по проекту, я получил 55 результатов. Стало понятно, почему я не мог найти использование некоторых классов. Среди этих файлов нашелся один с интересным названием ActiveUserNetwork.
We need to go deeper ©
Я догадывался, что дальше – только ассемблер. Так и получилось.
У Dalvik VM есть множество оп-кодов, и, на самом деле, smali код довольно user-friendly для чтения, особенно, если вы ковырялись в ассемблере.
В этот раз нам понадобятся smali и baksmali. Backsmali преобразовывает файл classes.dex в папку с исходным кодом, при этом сохраняя иерархию и имена папок и файлов. На первых порах будет гораздо проще разбираться в smali коде, открыв этот же файл java (если, конечно, jd-gui смог его декомпилировать). В интернете хватает ресурсов, где можно найти примеры кода, вот тут, например, показывается, как выглядят массивы в smali и инструкции for/switch.
Но вернемся к нашей игре, а конкретно к заинтересовавшему меня файлу ActiveUserNetwork. Тут нашлось всё – Cipher, методы encrypt и decrypt, Base64, (кстати, тут он использовался из библиотеки android.utils) и даже константа «http://***.com/gateway.php». Да, это не /api/gateway.php, но хоть что-то. Кстати, поиск «api/gateway.php» даже по smali коду не давал ничего, но я не особо расстраивался, потому что видел, что частенько используется StringBuilder.
Подсветки smali кода на хабре нет (будем откровенны, она вообще мало где есть), поэтому большие куски этого кода я буду выкладывать скриншотами.
Итак, метод decrypt :
Заглядывая в таблицу оп-кодов и помня, что в invoke-virtual первым параметром всегда передается сам объект, в отличие от invoke-static, «дословно» переписываем метод на Java:
Здесь spec – статическая переменная класса ActiveUserNetwork, она инициализируется в конструкторе класса
Это преобразованный код из конструктора. Дело было уже ночью, и число 0x10 мой мозг перевел в десятичную систему как «10». Хорошо, что я решил перепроверить в калькуляторе, а то дальше ждало бы сплошь разочарование 🙂
Метод createSecretKey (тут, кстати, опечатка в названии, ее мы тоже поправим)
Метод совсем простой, преобразовывается в
Этот метод уже потяжелее для восприятия: тут есть и цикл, и исключения, и условия. А ошибаться в криптографических методах нельзя. Одна эта конструкция чего стоит:
А превращается она в банальное Byte v9 = mdByte[i];
В качестве подсказки: почти всегда, когда вы видите инкремент ( add-int/lit8 v1, v1, 0x1 ) перед goto – это цикл for. Финальный код Java:
Собираем все воедино. Я создал новое приложение и закинул все в MainActivity:
Теперь вернемся к тому, зачем мы все это делаем. Внимательный читатель мог заметить, что в ни в ответе, ни в запросе, которые были приведены выше, не было хедера REQ-TIMESTAMP. Однако, там и запрос идет к /gateway, а не к /api/gateway. Запросы к /gateway идут во время инициализации приложения. Их всего два, расшифровав их, я получил… ничего. Нет, там были данные об устройстве, MAC-адресе и даже о том, рутован ли планшет. Но ничего стоящего я не получил. Запросы к /api/gateway шли откуда-то еще и никак не были связаны с /gateway.
Пока я разбирался со smali кодом, я сделал еще несколько попыток в разных направлениях, прежде чем пришел к решению разобраться со всеми методами и переписать их на Java.
Попытка 1: не искать то, как генерируется ключ, а просто сделать запрос с ним на свой сервер. Smali код можно изменить и скомпилировать обратно, так что идея была проста – перед методом decrypt делаем запрос на свой сервер, передав ключ как GET параметр, а потом смотрим логи веб-сервера.
В поисках как скомпилировать smali код я нашел apktool. Этот инструмент умеет разбирать apk файл сразу же на smali код, а также собирать все это обратно в apk.
Но когда вы попытаетесь установить новое приложение, вы получите ошибку:
На stackoverflow советуют удалить приложение вручную, а потом еще раз установить, но и это меня не спасло. Делаем новый ключ, для этого нам понадобятся keytool и jarsigner (входят в пакет openjdk)
Важное замечание – jarsigner ведет себя по-разному в 6 и 7 версии jdk, и на 7 версии команда ругнется на alias. Я не нашел решения этой проблемы и установил себе дополнительно 6 версию.
После этого установка приложения пройдет. Но, к сожалению, приложение (даже если его не изменять, а просто декомпилировать-компилировать-подсписать-установить) сразу же вылетало. Догадываюсь, что сервер как-то проверяет подписи, но буду рад, если кто-то в комментариях уточнит. Эту идею пришлось оставить.
Попытка 2: если нет желания ковыряться в smali коде (а у меня его не было, я думал, что это задачка на
5 часов), то можно поступить проще. В своем приложении создаете пустой метод с таким же интерфейсом, что и у того, который хотите скопировать, создаете apk, декомипилируете, копируете тело метода, собираете обратно. Каждая такая итерация отнимает довольно много времени. Поэтому быстрее будет изучить оп-коды. При этом понятно, что открыть исходный код собранного приложения вы уже не сможете.
Эта статья писалась не за один день, и это замечание я пишу через неделю после абзаца выше. Способ описания интерфейса и копирования smali кода в тело метода очень мне помог, когда я так и не смог восстановить исходный код метода генерации ключа. Чтобы упростить себе жизнь и сократить время итерации можно объединить все в одну команду
Идея 2. Делаем супермонстра.
Привет, ассемблер!
We need to go deeper ©
Надеюсь, вы еще не устали 🙂 Потому что мы начинаем практически с самого начала.
Скажу честно, на этой стадии я потратил около 20-30 часов своего времени. Если вы не знакомы с оп-кодами процессора, регистрами и памятью – вы тоже тут встрянете надолго. Меня спасло только мое упорство и желание доказать, что человек круче какого-то там приложения.
Очень много времени ушло на подбор инструментов и методики. И если оставшаяся статья кому-то сэкономит в дальнейшем несколько часов – это будет замечательно.
Инструментарий.
Ida Pro 6.1+ – основной инструмент для отладки. С версии 6.1 идет в комплекте с файлом android_server и возможностью удаленной отладки андроид приложений.
gdbserver – еще один инструмент для удаленной отладки.
На этом этапе root доступ к устройству обязателен.
Закачиваем оба сервера на устройство:
Настраиваем проброс портов на локалхост:
Выставляем нужные права:
Еще один важный момент:
Если приложение упадет – вам (с некоторой вероятностью) придется проделать все шаги с первого. Все дело в технологии ASLR. Чтобы отключить ее, выполните в шелле:
Внимание! Это сильно влияет на безопасность вашего устройства. Не забудьте запомнить значение этого параметра и вернуть его на место после ваших экспериментов.
Теперь, если все сделано правильно, код библиотеки, который проанализировала Ida, встанет на нужное место.
как я говорил в описании, с мобов падают не только синие кристаллы. Довольно часто падает энергия и изредка красные кристаллы, причем вы видите, что и сколько упало при убийстве моба. И вот тут возникает мысль: неужели клиент решает, сколько и чего упадет, а потом отправляет на сервер? Если так, то отправив «правильный» запрос, мы не только сможем «выиграть» подземелье, которое нам не по зубам, но еще и забрать с него пару-тройку сотен красных кристаллов и энергии.
По идее, все то, что мы делаем с помощью дебаггера, для игры выглядит вполне законно – победа, все монстры мертвы. Банить нас вроде бы не за что. Однако, чуть позже я выяснил один неприятный момент. Как я говорил, локации делятся на уровни – три или больше. На каждом уровне стоят свои мобы. Для примера представим такую ситуацию:
Stage 1 – 3 монстра (мы их убили, прошли дальше)
Stage 2 – 4 монстра (тут мы убили одного и погибли)
Stage 3 – 3 монстра (в этот уровень мы не зашли, так как погибли раньше)
Теперь, если мы перехватим JSON перед шифрованием, мы получим примерно такие результаты:
Как видите, из-за того, что мы не дошли до третьего уровня, мы не загрузили данные о монстрах на нем. Даже если мы изменим запрос на «win» и статусы существующих монстров на «dead», мы все равно не сможем добраться до трех оставшихся мобах на третьем уровне. И для сервера они живы, хоть в ответе и приходит, что мы одержали победу. Теоретически на этом могут поймать и забанить. Но я пока жив 🙂
В то же время, на арене только один уровень, и запрос с нее выглядит правдивым на 100%.
Теперь все стало ясно. Хоть и получить неограниченное количество красных кристаллов мы не сможем, зато по-прежнему мы можем выигрывать любое сражение, какое пожелаем. Правда, для этого приходится держать устройство подключенным к компьютеру, постоянно переключать брейкпоинты и вручную переделывать запрос перед шифрованием. Это не очень удобно. По идее, нам надо не слишком много: всегда записывать в «win» единицу, а в «result» двойку для всех мобов.
Ищем код, который добавляет «win» в JSON. Немного повозившись с брейкпоинтами, я нашел этот кусок.
Судя по всему, в R6 находится то, что нам нужно – значение победы. Теперь нам надо изменить эту инструкцию на автоматическое присваивание победы.
Тут стоит отметить, что в игре есть возможность в любой момент выйти из боя, при этом засчитывается поражение. То есть у нас всегда есть возможность получить поражение, и мы можем рассчитывать, что в R6 всегда 2. Но мне было не очень понятно, будет ли там просто 2 (0x2) или «2» (0x32 ASCII).
Дело за малым – изменить инструкцию. К сожалению, Ida не дает изменять ASM код, поэтому придется менять биты инструкций.
Вы хотели научиться программировать на нулях и единицах? Их есть у меня!
ADDS – эта часть постоянна для этой инструкции
Imm – immediate value. Непосредственное значение, которое мы хотим прибавить.
Rn – регистр, к которому мы будем прибавлять.
Rd – destination register. Регистр, который будет хранить сумму после исполнения инструкции.
На всякий случай проверяем с помощью брейкпоинта регистры на входе в функцию AESConvertEncode и убеждаемся, что все верно.
Осталось заменить только инструкцию, отвечающую за присвоение статуса монстрам.
Она находится тут же, чуть ниже.
Здесь идет обход массива в цикле for.
В R11 хранится длина массива, цикл узнается по трем строкам:
Profit! Самое главное не забывать, что выходить из боя надо всегда. Если случайно одержите победу — на сервер отправится поражение. Теперь можно даже отключить устройство от компьютера. До тех пор, пока приложение не перезапустится, в его памяти будет висеть измененная библиотека.
Вместо заключения
Взлом этого приложения стал возможен во многом из-за того, что авторы фактически сами раскрыли, что результат боя они считают на клиенте. В то же время, в мобильной онлайн игре надо соблюсти грань между безопасностью и удобством для пользователя. Если игра будет требовать постоянного подключения, ее аудитория убавится. Разработчики постарались усложнить жизнь потенциальным взломщикам: сделали шифрование данных и вынесли основной код игры в shared object. Но меня смущает одно — почему не обфусцированы имена функций? Я не программировал на C/C++ и не знаю, есть ли такая опция в компиляторе. Но если бы все функции назывались » sub_xxxxxxxx «, то время, потраченное на взлом приложения, выросло бы в разы. Рад буду услышать ответ в коментариях.
Спасибо тем, кто дочитал до конца.
О грамматических или орфографических ошибках просьба писать в личку.
О логических или грубых технических — лучше в комментарии.