March 12, 2019

Записки реверсера #1 Часть 2. Работа с ресурсами

Telegram: @VolfsChannel

Четвертое правило Android-реверсера гласит:

  • После декомпиляции исходного кода, сразу же удаляй папку /res/

Я объясню почему, но для начала, держите немного информации для понимания.

Не кодом единым...

Мы вроде бы разобрались, из чего состоит APK, как формируется DEX, и чем отличается процесс декомпиляции джарников и dex-ов. Но код - ничто, без правильно расшифрованных ресурсов.

Ресурсы хранятся в специальных папках и файлах (вспомните, каких?). Но есть одна небольшая загвоздка - они представлены в бинарном виде. Для использования в реверсе нам необходимо их расшифровать. Поможет нам в этом ApkTool.

Вы можете использовать любую имплементацию ApkTool, какую захотите. Можно использовать "чистый" ApkTool, а можно - комбайны типа BatchApkTool. Главное - чтобы версия apktool.jar была самой последней (на март 2019 - 2.4.0). Ссылки на скачивание ApkTool я оставлю на канале.

Можно вообще не париться, и декомпилировать ресурсы даже на смартфоне (ApkTool for Android/APK Editor/etc). Было бы желание.

После того, как приложение успешно декомпилировано (собирается и разбирается без ошибок), мы можем приступить к очистке ресурсов.

Telegram: @VolfsChannel

Какая ещё очистка ресурсов?

Во время разработки ПО, у разработчика есть 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.

Telegram: @VolfsChannel

Через игольное ушко и обратно

Ты, да, ты! Ещё не уснул? Что там было в предыдущем разделе? Какая-то главная задача... Что-то про мух, тьфу, ресурсы... Рекомендую перечитать если забыл:

Наша задача - "отделить мух от котлет", оставив только ресурсы приложения, добавив библиотеки с помощью системы автоматизации сборки (тот же Gradle)

Чтож, задача ясна, но как определить ресурсы библиотек? На этот ответ нет 100% верного алгоритма. Я использую, как я думаю, лучший вариант из возможных:

  1. Тап по файлу layout/drawable
  2. Control + F7 (Find Usages)
  3. Если всплывает уведомление "No usages found in project files", то можете смело удалять
  4. См п #1

Но файлов layout много, а время не резиновое. Поэтому я дам маленький список:

  1. /res/layout/ и /res/drawable/
  • abc_*.xml (support-library)
  • design_*.xml (support-library)
  • md_*.xml (material-dialogs)
  1. /res/values/strings.xml
  2. /res/values-XX/strings.xml
  • Все строки, идентификаторы которых начинаются с abc_
  1. Также следует удалить файл /res/values/public.xml
  2. /res/values/styles.xml
  3. /res/values-vXX/styles.xml
  • Все темы, имя которых начинается с Theme.AppCompat.** / Base.** / TextAppearance.AppCompat.**

Как восстановить id-шники разметки, как правильно модифицировать манифест, какие подводные камни скрывает декомпиляция с помощью ApkTool

Всё это будет в следующих постах.

Подписывайтесь!