Содержание статьи

Исследование исходного кода Android-приложений начинается с понимания формата файлов APK. Каждый APK представляет собой архив, содержащий скомпилированные классы в формате DEX, ресурсы и манифест приложения. Для анализа кода чаще всего используют инструменты декомпиляции, такие как JADX или Bytecode Viewer, которые преобразуют DEX в читаемый Java-код или Smali-ассемблер.
Перед началом работы важно иметь базовую структуру приложения. Основные элементы – AndroidManifest.xml, каталоги res и assets, а также папка с классами. Изучение манифеста позволяет выявить используемые разрешения, активити и сервисы, а ресурсы дают понимание интерфейса и мультимедийных компонентов. Практика показывает, что последовательный просмотр этих элементов ускоряет анализ и снижает риск пропуска критически важных частей кода.
Для эффективного анализа рекомендуется сохранять оригинальный APK и работать с его копией. Инструменты декомпиляции часто создают структуру проекта, приближенную к исходному коду, но могут пропускать оптимизации компилятора. Использование JADX GUI позволяет просматривать методы, классы и структуру пакетов, а Smali – анализировать низкоуровневую логику и вызовы системных API. Рекомендуется вести заметки о подозрительных методах и зависимостях между классами, чтобы ускорить дальнейший аудит безопасности или модификацию функционала.
Дополнительно, для детального изучения сетевого взаимодействия и работы с базами данных приложения полезно подключать эмулятор Android или физическое устройство с инструментами мониторинга трафика и файловой системы. Это позволяет сопоставлять декомпилированный код с фактическим поведением приложения. В совокупности структурированный просмотр исходного кода и динамический анализ дают наиболее полное понимание внутренней логики Android-приложений.
Выбор инструментов для декомпиляции APK

Подбор инструмента для декомпиляции APK определяется типом анализа: изучение логики Java/Kotlin-кода, исследование ресурсов, аудит безопасности или модификация приложения. APK представляет собой ZIP-архив с DEX-файлами, ресурсами (resources.arsc), манифестом и нативными библиотеками (*.so). Поэтому полноценный разбор требует набора утилит, а не одного универсального решения.
Для восстановления исходного кода из DEX-файлов применяются декомпиляторы, преобразующие байткод Dalvik/ART в Java-подобный код. На практике используются:
- JADX – корректно обрабатывает многомодульные APK, поддерживает Kotlin-конструкции, аннотации и inline-функции;
- CFR – полезен при дополнительной обработке class-файлов после конвертации через dex2jar;
- FernFlower – показывает стабильный результат при анализе лямбда-выражений и обфусцированного кода.
JADX предпочтителен при статическом анализе: он открывает проект целиком, строит дерево пакетов и позволяет искать по строкам и сигнатурам методов. При выборе версии следует учитывать поддержку актуального формата DEX (версии 035–041). Для крупных приложений (более 50 МБ) рекомендуется запуск в режиме CLI с увеличенным heap size (например, 2–4 ГБ), чтобы избежать потери классов при декомпиляции.
Если задача – точная реконструкция структуры ресурсов и манифеста, необходим Apktool. Он декодирует resources.arsc, восстанавливает XML в читаемом виде и сохраняет smali-код. Это критично при анализе разрешений, intent-фильтров и скрытых компонентов. Apktool корректно работает с разными версиями Android API, но требует соответствующего framework-файла при разборе системных приложений.
Для низкоуровневого анализа используется smali/baksmali. Инструмент не пытается преобразовать байткод в Java, а предоставляет точное представление инструкций Dalvik. Это важно при исследовании защиты от реверс-инжиниринга, внедрённых проверок подписи и антиотладочных механизмов. Smali даёт контроль над инструкциями invoke-virtual, iget, move-result и другими операциями, что недоступно при работе только с декомпилятором высокого уровня.
При наличии нативных библиотек (*.so) стандартные декомпиляторы бесполезны. Для анализа ARM/ARM64-кода выбирают:
- Ghidra – бесплатная платформа с поддержкой ELF и автоматическим анализом символов;
- IDA Free – удобна для быстрого просмотра дизассемблированных участков;
- Radare2 – подходит для скриптового анализа и автоматизации.
Если приложение обфусцировано с помощью ProGuard или R8, следует учитывать потерю имён классов и методов. В таких случаях важна поддержка deobfuscation mapping-файлов (если они доступны) и корректная работа с synthetic-методами. JADX отображает сигнатуры и строки, что облегчает поиск точек входа даже при агрессивной минимизации кода.
Выбор набора инструментов должен учитывать версию Android (minSdk/targetSdk), размер APK, наличие split-архитектуры (base.apk + config-сплиты) и использование multidex. Оптимальная стратегия: Apktool для структуры и ресурсов, JADX для логики, smali для точечных проверок, Ghidra для нативных библиотек. Комбинированный подход даёт полный контроль над анализом и минимизирует искажения, возникающие при использовании одного инструмента.
Как извлечь DEX-файлы из APK

APK-файл представляет собой ZIP-архив, внутри которого размещаются один или несколько файлов classes.dex (в приложениях с Multidex – classes2.dex, classes3.dex и т.д.). Для извлечения достаточно переименовать расширение .apk в .zip и открыть архив любым архиватором (7-Zip, WinRAR) либо выполнить распаковку через unzip. После распаковки DEX-файлы находятся в корневом каталоге архива. Важно копировать их без перекомпрессии, чтобы сохранить исходную структуру байткода.
При работе через Android SDK целесообразно сначала получить APK напрямую с устройства командой adb shell pm path имя.пакета, затем извлечь файл через adb pull указанный_путь. Такой способ гарантирует получение именно установленной версии приложения, включая возможные модификации, внесённые системой (например, split-APK).
Если приложение использует Android App Bundle, установленный на устройстве вариант может состоять из нескольких split-APK (base.apk и конфигурационные split_config.*.apk). В этом случае необходимо выгрузить все части через adb shell pm path и объединить содержимое, извлекая DEX-файлы из каждого base- или feature-модуля. Основной байткод обычно расположен в base.apk, однако динамические модули могут содержать собственные classes.dex.
Для автоматизации извлечения применяются инструменты анализа: apktool d файл.apk создаёт директорию с декомпилированными ресурсами и извлечёнными DEX, а jadx при открытии APK автоматически обрабатывает все classes*.dex без ручной распаковки. При необходимости получить «чистый» DEX без изменений предпочтительно использовать прямую распаковку ZIP, поскольку apktool может преобразовывать структуру проекта.
В приложениях с защитой (ProGuard, R8, DexGuard) DEX-файлы могут быть дополнительно зашифрованы или загружаться динамически через ClassLoader из assets или lib. В таких случаях стандартная распаковка извлекает лишь загрузчик, а основной байткод появляется в памяти во время выполнения. Для анализа требуется дамп памяти процесса (например, через frida-dexdump), что позволяет сохранить расшифрованный DEX из runtime.
При проверке целостности извлечённых файлов рекомендуется сравнить их хэш-суммы (SHA-256) с оригиналом из архива и убедиться, что размер совпадает с указанным в центральной директории ZIP. Повреждённый DEX не будет корректно обрабатываться dex2jar или jadx, что проявляется ошибками формата или некорректной структурой классов.
Извлечённые DEX-файлы можно конвертировать в JAR через d2j-dex2jar для последующего анализа в Java-декомпиляторах либо напрямую загрузить в JADX для просмотра исходного кода. При наличии нескольких classes*.dex важно сохранять их в одной директории, поскольку инструменты анализа автоматически объединяют ссылки между методами и классами из разных DEX-файлов.
Использование JADX для чтения Java-кода

JADX – декомпилятор, преобразующий DEX и APK в читаемый Java-код с сохранением структуры пакетов и классов. Для анализа достаточно выполнить jadx-gui app.apk или использовать CLI-версию для пакетной обработки. Инструмент корректно восстанавливает анонимные и вложенные классы, перечисления, generics и аннотации, что позволяет анализировать логику без ручного сопоставления smali-инструкций. При открытии APK автоматически извлекается AndroidManifest.xml и ресурсы, включая строки и layout-файлы, что упрощает поиск точек входа и связей между компонентами.
При работе с обфусцированными сборками (например, после ProGuard или R8) рекомендуется активировать отображение сигнатур методов и использовать поиск по строковым константам для выявления сетевых запросов, ключей API и путей к файлам. Вкладка Usage позволяет отследить вызовы конкретного метода или обращение к полю, что ускоряет реконструкцию бизнес-логики. Для глубокого анализа стоит включить опцию деобфускации имен (—deobf в CLI), которая генерирует читаемые псевдонимы классов и переменных. При наличии ошибок декомпиляции полезно сверять проблемные участки со smali-кодом, доступным во встроенном просмотрщике, чтобы исключить неточности восстановления циклов и switch-конструкций.
JADX поддерживает экспорт проекта в виде Gradle-структуры, что дает возможность открыть результат в IDE и применять статический анализ, рефакторинг и навигацию по коду. Для автоматизации ревью нескольких версий приложения целесообразно использовать CLI с параметрами —threads-count для ускорения обработки и —output-dir для структурирования результатов. Такой подход позволяет сравнивать изменения в логике между релизами, выявлять внедрение новых библиотек и отслеживать модификации в механизмах аутентификации или шифрования.
Просмотр ресурсов и макетов XML

Ресурсы и макеты в Android хранятся в папках res/layout, res/values, res/drawable. Для анализа приложения их можно извлечь из APK с помощью утилит типа APKTool. После декомпиляции файлы XML становятся читаемыми, что позволяет просматривать структуру интерфейса, используемые идентификаторы элементов и их атрибуты, такие как android:layout_width и android:layout_height.
Макеты XML разделяются на линейные (LinearLayout), относительные (RelativeLayout) и ConstraintLayout. Для понимания связей между элементами таблица атрибутов помогает определить поведение виджетов:
| Элемент | Основные атрибуты | Назначение |
|---|---|---|
| TextView | android:text, android:textSize, android:gravity | Отображение текста |
| Button | android:onClick, android:background | Обработка нажатий |
| ImageView | android:src, android:scaleType | Отображение изображений |
| RecyclerView | android:layoutManager, android:adapter | Список элементов с прокруткой |
При работе с ресурсами строк, цветов и стилей стоит использовать res/values/strings.xml, colors.xml и styles.xml. Эти файлы показывают локализацию и визуальные настройки приложения. Например, изменение colorPrimary в styles.xml напрямую влияет на цвет ActionBar и элементов интерфейса.
Для эффективного анализа рекомендуется открывать XML через редакторы с подсветкой синтаксиса, такие как Android Studio или Notepad++. Они позволяют быстро отслеживать иерархию, проверять связи ID и видеть подключенные ресурсы. Также полезно строить карту макетов: какой layout используется в Activity, а какие вложенные фрагменты подгружаются динамически.
Анализ сторонних библиотек и зависимостей

При разборе APK важно выявлять все сторонние библиотеки, включая транзитивные зависимости. Для этого используют инструменты вроде JADX или APKTool для декомпиляции, а затем анализируют файл `build.gradle` или манифест для определения версий библиотек. Особое внимание стоит уделять библиотекам с известными уязвимостями, например, старым версиям `OkHttp` или `Retrofit`, проверяя их через базы данных CVE и Snyk. Дополнительно рекомендуется проверять, нет ли скрытых модулей или встроенных SDK для аналитики и рекламы, которые могут передавать пользовательские данные без явного разрешения.
После идентификации библиотек полезно построить карту зависимостей с указанием лицензий и версий, чтобы оценить совместимость и риск обновлений. Автоматические сканеры вроде Dependency-Check или Gradle Lint помогут выявить устаревшие компоненты и конфликты версий. При обнаружении библиотек с потенциально опасным поведением, например, содержащих нативные библиотеки `.so` для обхода ограничений, стоит изучить их код или заменить безопасными альтернативами. Такой подход сокращает риск интеграции вредоносного кода и обеспечивает прозрачность внешних модулей в приложении.
Поиск уязвимостей через изучение кода

Анализ декомпилированного APK (через JADX или CFR) следует начинать с манифеста и точек входа:
- экспортированные activity, service, receiver, provider без проверки разрешений;
- наличие android:exported=»true» в сочетании с отсутствием permission;
- использование taskAffinity и launchMode, создающих условия для task hijacking;
- deep link-интенты без валидации параметров.
Далее проверяются обработчики входящих данных: методы onCreate(), onStartCommand(), onReceive(), где параметры Intent используются без строгой проверки типов и диапазонов. Любое прямое извлечение getStringExtra(), getSerializableExtra() или getParcelableExtra() без null-check и whitelist-логики рассматривается как потенциальная точка инъекции.
Особое внимание уделяется работе с сетью и криптографией. В коде выявляются:
- жёстко прописанные URL и IP-адреса;
- отключённая проверка SSL (кастомный TrustManager с пустой реализацией checkServerTrusted());
- использование устаревших алгоритмов (MD5, SHA-1, DES);
- симметричные ключи и токены, встроенные в строки.
Поиск строковых литералов через grep по декомпилированным файлам позволяет быстро обнаружить API-ключи, секреты Firebase, JWT-подписи. Если применяется Retrofit или OkHttp, анализируются interceptors и логирование запросов – наличие HttpLoggingInterceptor.Level.BODY в релизной сборке указывает на утечку чувствительных данных.
Хранилище данных проверяется на предмет небезопасных практик: использование SharedPreferences без режима MODE_PRIVATE, хранение паролей в открытом виде, отсутствие шифрования в SQLite. При анализе ContentProvider оцениваются методы query(), insert(), update(), delete() – отсутствие проверки caller UID или permission ведёт к утечке данных. В WebView ищутся включённые флаги setJavaScriptEnabled(true) и addJavascriptInterface() без аннотации @JavascriptInterface, а также загрузка контента через loadUrl(«http://»), что создаёт риск MITM-атаки.
Дополнительно анализируются механизмы аутентификации и защиты от реверс-инжиниринга:
- проверка наличия root через примитивные строки («su», «/system/bin») легко обходится;
- логика лицензирования, реализованная только на стороне клиента;
- отсутствие обфускации или некорректная конфигурация R8/ProGuard, оставляющая читаемые имена классов;
- debug-флаги и включённый android:debuggable=»true» в релизе.
Каждая найденная точка сопоставляется с возможным сценарием эксплуатации: подмена Intent, перехват трафика, извлечение ключей, выполнение произвольного JavaScript. Итогом анализа становится карта поверхностей атаки с приоритетами по критичности.
Вопрос-ответ:
Можно ли просматривать исходный код любого приложения для Android?
Нет, не все приложения позволяют получить доступ к своему коду. Большинство приложений распространяются в скомпилированном виде (APK), и исходный код не предоставляется. Для анализа используют инструменты декомпиляции, но это может нарушать лицензионные соглашения.
Какие инструменты подходят для изучения структуры Android-приложений?
Существуют разные утилиты для декомпиляции APK-файлов и изучения ресурсов приложения. Среди популярных — JADX, который позволяет преобразовать байт-код в читаемый Java-код, и APKTool, дающий возможность исследовать ресурсы и манифест приложения. Выбор зависит от того, какую информацию нужно получить: код, ресурсы или общую структуру.
Нужно ли иметь опыт программирования, чтобы просматривать исходный код Android-приложений?
Базовые знания помогают понять структуру и назначение компонентов, но для полной интерпретации кода требуется опыт в Java или Kotlin. Без него можно увидеть лишь общие элементы и ресурсы, но понять логику работы приложения будет сложно.
Можно ли изменить приложение после просмотра его исходного кода?
Технически это возможно: декомпилированный код можно редактировать, затем собрать приложение обратно в APK. Однако это часто нарушает авторские права и лицензионные соглашения, поэтому такие действия допустимы только для личного изучения или с открытым исходным кодом.
Какие риски связаны с декомпиляцией Android-приложений?
Декомпиляция может привести к юридическим последствиям, если нарушаются права разработчика. Также существует риск повреждения приложения при попытке изменить код и собрать его заново. Вредоносные модификации могут привести к заражению устройства. Поэтому рекомендуется работать только с приложениями, на которые есть разрешение или открытый исходный код.
