Записки реверсера #1 Часть 2. Работа с ресурсами
Четвертое правило Android-реверсера гласит:
- После декомпиляции исходного кода, сразу же удаляй папку
/res/
Я объясню почему, но для начала, держите немного информации для понимания.
Не кодом единым...
Мы вроде бы разобрались, из чего состоит APK, как формируется DEX, и чем отличается процесс декомпиляции джарников и dex-ов. Но код - ничто, без правильно расшифрованных ресурсов.
Ресурсы хранятся в специальных папках и файлах (вспомните, каких?). Но есть одна небольшая загвоздка - они представлены в бинарном виде. Для использования в реверсе нам необходимо их расшифровать. Поможет нам в этом ApkTool.
Вы можете использовать любую имплементацию ApkTool, какую захотите. Можно использовать "чистый" ApkTool, а можно - комбайны типа BatchApkTool. Главное - чтобы версия apktool.jar была самой последней (на март 2019 - 2.4.0
). Ссылки на скачивание ApkTool я оставлю на канале.
Можно вообще не париться, и декомпилировать ресурсы даже на смартфоне (ApkTool for Android/APK Editor/etc). Было бы желание.
После того, как приложение успешно декомпилировано (собирается и разбирается без ошибок), мы можем приступить к очистке ресурсов.
Какая ещё очистка ресурсов?
Во время разработки ПО, у разработчика есть 2 стула пути:
- Создавать приложение без библиотек, полагаясь только на встроенные в SDK возможности
- Использовать библиотеки, разрабатывая приложение быстро, и так же быстро получая profit
И, скажу честно, абсолютное большинство выбирает второй путь. В сегодняшних реалиях, когда стоимость времени программиста оценивается дороже времени пользователя, все чихать хотели на размер APK. В современных приложениях используются десятки, библиотек и фреймворков. Скачайте первое попавшееся приложение с маркета, и с вероятностью 99% там будет хотя бы одна библиотека семейства android.support.*
или androidx.*
.
Помимо фактического кода в DEX, зачастую библиотека добавляет в приложение свои ресурсы (иконки/xml/разметка), которые нужны ей для корректной работы. На этапе компиляции эти ресурсы смешиваются с ресурсами самого приложения.
Наша задача - "отделить мух от котлет", оставив только ресурсы приложения, добавив библиотеки с помощью системы автоматизации сборки (тот же Gradle)
Зачем я удаляю ресурсы декомпилятора?
Ответ до безобразия прост: потому что они неправильные.
Папка /res/, которую создаёт почти любой декомпилятор, содержит всё дерево ресурсов оригинального приложения, и вроде даже все файлы на месте, и в них даже что-то содержится, но это представление имеет один ФАТАЛЬНЫЙ НЕДОСТАТОК- эти ресурсы забракует любая нормальная IDE!
Просто пример кода для понимания.
JaDX:
<TextView android:textAppearance="{2:16842817}" android:id="false" android:layout_width="-1" android:layout_height="-2" />
ApkTool:
<TextView android:textAppearance="?android:textAppearanceMedium" android:id="@id/path" android:layout_width="fill_parent" android:layout_height="wrap_content"/>
ApkTool декодирует все атрибуты и ID, в то время как JaDX показывает какую-то китайскую грамоту.
Справедливости ради, стоит заметить, что ApkTool не является истиной в последней инстанции. Что первый, что второй вариант придется править для успешной сборки, но второй вариант значительно легче для понимания, чем первый.
Для меньшей головной боли я удаляю ресурсы сгенерированные декомилятором (папку /res/
целиком) и заменяю ее аналогичной папкой /res/
, которую мне предоставил ApkTool.
Через игольное ушко и обратно
Ты, да, ты! Ещё не уснул? Что там было в предыдущем разделе? Какая-то главная задача... Что-то про мух, тьфу, ресурсы... Рекомендую перечитать если забыл:
Наша задача - "отделить мух от котлет", оставив только ресурсы приложения, добавив библиотеки с помощью системы автоматизации сборки (тот же Gradle)
Чтож, задача ясна, но как определить ресурсы библиотек? На этот ответ нет 100% верного алгоритма. Я использую, как я думаю, лучший вариант из возможных:
- Тап по файлу layout/drawable
- Control + F7 (Find Usages)
- Если всплывает уведомление "No usages found in project files", то можете смело удалять
- См п #1
Но файлов layout много, а время не резиновое. Поэтому я дам маленький список:
- /res/layout/ и /res/drawable/
abc_*.xml
(support-library)design_*.xml
(support-library)md_*.xml
(material-dialogs)
- /res/values/strings.xml
- /res/values-XX/strings.xml
- Все строки, идентификаторы которых начинаются с
abc_
- Также следует удалить файл
/res/values/public.xml
- /res/values/styles.xml
- /res/values-vXX/styles.xml
- Все темы, имя которых начинается с
Theme.AppCompat.**
/Base.**
/TextAppearance.AppCompat.**
Как восстановить id-шники разметки, как правильно модифицировать манифест, какие подводные камни скрывает декомпиляция с помощью ApkTool
Всё это будет в следующих постах.