Как проанализировать APK с помощью jadx и проверить обфускацию

Вы скачали APK, и вам нужно понять, что внутри: нет ли там чего-то подозрительного, насколько хорошо защищён код, или просто интересно — как устроено приложение. Или вы проверяете свою сборку перед релизом и хотите убедиться, что обфускация реально работает. В любом случае — jadx это первый инструмент, к которому стоит потянуться.

В этом материале я покажу, как с ним работать по-настоящему: не просто «открой и смотри», а разобраться в коде, оценить качество обфускации и сделать выводы. Без теории ради теории — только то, что применяется на практике.

Что такое jadx и зачем он нужен именно вам

jadx — это декомпилятор APK и DEX-файлов. Он берёт скомпилированное Android-приложение и превращает его обратно в Java- (или Kotlin-) код, который можно читать. Не идеально — но достаточно, чтобы понять логику.

В отличие от многих инструментов jadx умеет:

  • декомпилировать не только Java, но и Kotlin-код (пусть и с оговорками);
  • показывать ресурсы: layout-файлы, строки, манифест;
  • работать из терминала и из GUI — кому как удобнее;
  • искать по коду, переходить по ссылкам, декодировать строки.

Если вы проверяете стороннее приложение на безопасность — jadx покажет, какие API вызываются, куда отправляются данные, какие разрешения реально используются. Если вы разработчик и проверяете свою сборку — он честно покажет, насколько ProGuard/R8 постарался.

Установка и первый запуск

jadx распространяется в двух формах: GUI-версия (удобна для интерактивной работы) и CLI (для автоматизации и скриптов).

GUI-версия:

  1. Скачайте архив с официального GitHub-репозитория.
  2. Распакуйте в любую папку — установка не требуется.
  3. Запустите jadx-gui (на Windows — jadx-gui.bat, на Linux/Mac — jadx-gui).
  4. Откройте APK через меню или просто перетащите файл в окно.

CLI-версия:

  1. Тот же архив, но запускайте jadx из терминала.
  2. Базовая команда: jadx -d output_dir app.apk
  3. Флаг -d задаёт папку для результатов. Без неё папка создастся автоматически рядом с APK.

Если приложение большое (сотни мегабайт), приготовьтесь подождать и убедитесь, что у вас достаточно оперативной памяти. Для GUI рекомендую от 4 ГБ RAM минимум, для CLI — можно и меньше.

Что вы увидите после декомпиляции

После загрузки APK в jadx слева появится дерево проекта. Вот что там есть и на что смотреть:

  • Sources — декомпилированный исходный код. Это главное. Классы и пакеты отображаются так, как они были структурированы (если обфускация не перемешала всё).
  • Resources — ресурсы приложения: layout XML, строки, изображения, манифест.
  • AndroidManifest.xml — уже декодирован и читаем. Смотрите сюда в первую очередь, если проверяете безопасность.

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

Как оценить качество обфускации

Теперь к главному. Вы открыли APK и видите код. Как понять — обфускация работает или нет? Вот конкретные признаки, на которые я смотрю.

Признаки хорошей обфускации

  • Имена классов и методов превращены в буквы. Вместо UserProfileManager.loadFromDatabase() вы видите a.b(), n0.c.a(). Это стандартное переименование ProGuard/R8.
  • Пакетная структура разрушена. Вместо логичных пакетов com.app.network, com.app.database — всё свалено в a, b, c.
  • Строки зашифрованы или закодированы. Если в коде вместо строк — вызовы вроде Decrypt.decode("aGVsbG8="), значит, строки обфусцированы отдельно.
  • Удалён отладочный код. Нет логов, нет System.out.println, нет стектрейсов с подробными сообщениями.
  • Control flow запутан. Методы разбиты на мелкие куски с переходами между ними, добавлены бессмысленные условия, циклы перестроены.

Признаки плохой или отсутствующей обфускации

  • Читаемые имена классов и методов. PaymentProcessor.chargeCard() — это подарок для аналитика.
  • Строки в открытом виде. Все URL, ключи API, сообщения об ошибках — как на ладони.
  • Логи с подробностями. Если в логах видно внутреннее состояние приложения — это утечка информации.
  • Неиспользуемый код остался. Мёртвый код, тестовые методы, отладочные функции — всё это не удалили.

Практический чеклист проверки обфускации

Когда я беру APK на анализ, я прохожу примерно по такому списку. Можете использовать как шпаргалку:

  1. Откройте манифест. Проверьте: все ли разрешения обоснованы? Нет ли лишних? Зарегистрированы ли подозрительные сервисы или ресиверы?
  2. Найдите точку входа. Activity, которая запускается при старте приложения (android.intent.action.MAIN). Посмотрите, что она делает.
  3. Проверьте сетевые вызовы. Поищите по коду HttpURLConnection, OkHttp, Retrofit. Куда идут запросы? Есть ли проверка сертификатов?
  4. Оцените именование. Откройте 5–10 случайных классов. Если имена читаемые — обфускация слабая или отсутствует.
  5. Проверьте строки. Откройте файл ресурсов strings.xml и поищите в коде строковые литералы. Нет ли ключей API, паролей, внутренних URL?
  6. Посмотрите на библиотеку классов. Нативные вызовы (System.loadLibrary), рефлексия — всё это может указывать на обфусцированные участки.
  7. Проверьте наличие кода защиты. Есть ли проверки root, проверки целостности APK, обфускация с помощью сторонних инструментов (DexGuard, DashO)?

Поиск и навигация — что реально ускоряет работу

Просто открыть код и листать его — медленно. Вот фишки, которые экономят время:

  • Поиск по тексту (Ctrl+Shift+F в GUI). Ищите конкретные строки: URL, названия API, ключевые слова. Это самый быстрый способ найти интересные участки.
  • Поиск по классам (Ctrl+N). Если знаете имя класса или хотя бы его часть — переходите напрямую.
  • Переход по вызовам. Клик по методу с зажатым Ctrl переводит к определению. Это работает даже для библиотечных классов.
  • Декодирование строк. jadx автоматически декодирует многие строковые операции. Если видите new String(Base64.decode("...")) — jadx часто показывает результат прямо в коде.

jadx в командной строке — для автоматизации

Если нужно проверить десятки APK или встроить анализ в пайплайн — CLI незаменим. Вот команды, которые я использую регулярно:

jadx -d output app.apk — базовая декомпиляция.

jadx --deobf app.apk — включить деобфускацию (jadx пытается сопоставить переименованные классы с исходными по контексту).

jadx --deobf-min 3 app.apk — минимальная длина имени для деобфускации. Имена короче 3 символов будут обрабатываться.

jadx -res-pass --show-bad-code app.apk — показывать «плохой код», который не удалось корректно декомпилировать. Иногда там находятся интересные артефакты.

Полезные флаги для ресурсов:

  • --no-res — не декомпилировать ресурсы (быстрее, если нужен только код).
  • --no-src — не декомпилировать исходники (только ресурсы).
  • -j 4 — количество потоков для обработки. По умолчанию 4, можно увеличить для больших APK.

Сравнение подходов к обфускации

Не все обфускации одинаковы. Вот как они выглядят глазами аналитика после декомпиляции через jadx:

Тип обфускации Что видно в jadx Насколько мешает анализу Типичный инструмент
Без обфускации Полный читаемый код, все имена, строки, логи Не мешает вообще — анализ максимально простой
Переименование (R8/ProGuard) Имена классов и методов заменены на a, b, c. Строки открыты Средне — логику понять можно, но сложнее ориентироваться R8, ProGuard
Переименование + удаление кода Как выше, но мёртвый код удалён, методы инлайнены Выше среднего — меньше шума, но структура упрощена R8 full mode, ProGuard
Обфускация строк Строки закодированы, в коде вызовы декодеров Высокое — нужно вручную декодировать или писать скрипты DexGuard, кастомные решения
Control flow обфускация Методы разбиты на блоки, добавлены ложные условия, switch-конструкции Очень высокое — читать код крайне сложно DexGuard, DashO, Allatori
Паковка (packer) Вместо кода — мусор или зашифрованные данные, реальный код загружается в рантайме Критическое — jadx не покажет основной код Qihoo360, Baidu, Tencent Protect

Что делать, если jadx не справляется

jadx — мощный инструмент, но не всесильный. Вот типичные проблемы и что с ними делать:

  • Код не декомпилируется. jadx показывает «bad code» или пустые методы. Попробуйте флаг --show-bad-code. Если не помогло — возможно, это packed APK, и код загружается динамически. Тут нужен дамп памяти в рантайме.
  • Много ошибок в консоли. Некоторые APK собираются с нестандартными опциями. Попробуйте обновить jadx до последней версии — поддержка улучшается с каждым релизом.
  • APK слишком большой и jadx падает. Увеличьте память для JVM: JADX_OPTS="-Xmx4g" jadx app.apk. Или используйте CLI без декомпиляции ресурсов.
  • Нативный код (.so файлы). jadx не умеет декомпилировать ARM/x86. Для этого нужен Ghidra или IDA. Но jadx покажет, какие нативные библиотеки загружаются и какие функции вызываются.

Частые ошибки при анализе APK

Вот на что я регулярно натыкаюсь — у себя и у коллег:

  • Слепая вера в обфускацию. Если имена переименованы, многие думают — «всё, код защищён». Нет. Логику можно восстановить и из переименованного кода, просто это дольше. Обфускация — это не стена, а забор. Замедляет, но не останавливает.
  • Игнорирование манифеста. Все смотрят на код, а забывают про манифест. А там — все разрешения, все компоненты, все фильтры интентов. Это карта приложения.
  • Поиск только по строкам. Если строки обфусцированы, поиск по тексту ничего не даст. Нужно смотреть на вызовы API, на структурные паттерны, на граф вызовов.
  • Забывают про ресурсы. В layout-файлах могут быть жёстко заданные URL, ключи, адреса серверов. В strings.xml — токены. Проверяйте ресурсы так же внимательно, как и код.
  • Не проверяют сертификат подписи. apksigner verify --print-certs app.apk покажет, кто подписал APK. Это важно для верификации источника.

Сценарии: что делать в зависимости от вашей задачи

Сценарий 1: Вы проверяете стороннее приложение на безопасность.

Откройте манифест, проверьте разрешения. Поищите сетевые вызовы — куда отправляются данные. Проверьте, есть ли отслеживание пользователя (аналитика, трекеры). Ищите подозрительные сервисы, которые запускаются в фоне. Если нашли что-то странное — углубляйтесь в конкретный класс.

Сценарий 2: Вы разработчик и проверяете свою сборку.

Соберите APK в release-конфигурации с включённой обфускацией. Откройте в jadx и проверьте: нет ли читаемых имён, нет ли строк с ключами API, удалился ли отладочный код. Если всё чисто — хорошо. Если видите свои классы с оригинальными именами — проверьте конфигурацию ProGuard/R8, добавьте правила для проблемных классов.

Сценарий 3: Вы проверяете APK на модификации (для пентеста).

Сравните подпись с оригиналом. Проверьте, не добавлены ли новые Activity или сервисы. Посмотрите, не изменён ли манифест. Если APK модифицирован — часто видны следы: новые пакеты, нестандартные вызовы, вставки кода, которые выбиваются из общего стиля.

Дополнительные инструменты, которые стоит иметь под рукой

jadx хорош, но в связке с другими инструментами он ещё лучше:

  • apktool — декомпилирует APK в smali-код (ассемблер Dalvik). Полезен, когда jadx не справляется или нужна точная модификация.
  • Ghidra / IDA — для анализа нативных .so файлов. Если основная логика в native-коде, без них не обойтись.
  • Frida — для динамического анализа. Позволяет перехватывать вызовы функций в рантайме, видеть аргументы и возвращаемые значения.
  • Bytecode Viewer — комбинирует несколько декомпиляторов в одном интерфейсе. Иногда показывает код лучше, чем jadx.
  • dex2jar + JD-GUI — старый, но рабочий подход. Конвертирует DEX в JAR и открывает в Java-декомпиляторе.

Итог: как работать с jadx эффективно

jadx — это ваш первый шаг в анализе APK. Он даёт быстрый доступ к коду и ресурсам, позволяет оценить качество обфускации и найти потенциальные проблемы. Но помните: обфускация — это не защита, а замедление. Если кто-то мотивирован разобрать ваше приложение, он это сделает. Ваша задача — сделать этот процесс максимально неудобным.

Практические рекомендации:

  1. Всегда проверяйте release-сборку через jadx перед публикацией. То, что вы видите в debug-версии, может отличаться.
  2. Не полагайтесь только на R8/ProGuard. Добавьте обфускацию строк и control flow для критичных участков кода.
  3. Удаляйте отладочный код и логи. Каждая строка в открытом виде — подсказка для аналитика.
  4. Проверяйте не только код, но и ресурсы, манифест, нативные библиотеки.
  5. Используйте jadx в связке с другими инструментами — один инструмент не даст полной картины.

Начните с простого: возьмите свой APK, откройте в jadx, пройдитесь по чеклисту выше. Вы удивитесь, сколько можно увидеть, если посмотреть внимательно.

Оцените статью
PEFile — Безопасность и технологии простым языком