Записки реверсера #1. Часть 3: нестандартные кейсы
Всем привет дамы и господа, с вами Юрий Хованский, и сегодня мы с вами поговорим на тему подводных камней, которые могут встретиться вам при исследовании чужого приложения. Для удобства, все это будет выполнено в формате FUCK YOU:
Что нужно для реверса Android-приложения?
- Навыки программирования на Java
- Мозги
- Руки
- Глаза
- Смекалка
- IDE (Android Studio)
- Декомпилятор (ApkTool)
- Декомпилятор исходного кода (JaDX/FernFlower/CFR/etc.)
Какие файлы нужно сразу же удалить?
- R.java
- res/values/public.xml
- Подробнее об удалении ресурсов можно почитать в предыдущей статье на канале.
Импортировал проект, но везде ошибки!
А ты как думал? Думал что будет легко?
В большинстве случаев, IDE сама укажет на ошибки компиляции. Но если что, то можно пройти все файлы поиском (ПКМ на паккейдже приложения > Find in files) с помощью следующей регулярки:
JADX WARNING|not be decompiled
IDE покажет классы, которые декомпилировались с ошибками.
После того, как найдешь, исправляй по факту.
Что делать, если метод не декомпилировался, но его код очень важен?
Такое встречается сплошь и рядом. Первое, что необходимо попробовать: разобрать APK с помощью другого декомпилятора, а лучше нескольких. Вполне возможно, что один из них таки сможет предоставить вам необходимый код.
Второй вариант:
- преобразовать DEX в JAR с помощью утилиты Dex2Jar
- удалить все
.class
файлы, кроме тех, в которых присутствуют нужные методы - закинуть получившийся JAR файл в папку
/libs/
модуляapp
- Удалить повреждённые исходники, заменив их импортами из JAR-файла
Третий (джедайский) вариант:
- декомпилировать classes.dex до smali
- найти нужный класс и метод в smali файлах
- переписать его на Java, строчка за строчкой смотря в smali-файл
После декомпиляции ApkTool-ом, все id-шники в разметке становятся каличными. ШТО ДЕЛАТЬ?
Что делать, что делать... Муравью хй приделать!
Дело в том, что ApkTool херит id-шники удаляя их объявления. Т.е. вместо android:id="@+id/test"
, мы получаем android:id="@id/test"
. Почему так происходит? Да очень просто: все идентификаторы хранятся в файле resources.arcs и в момент компиляции *AAPT (Android Asset Packaging Tool) собирает их внутри. Идентификатор @+Id нужен только во время компиляции. С помощью него AAPT понимает, какой идентификатор нужно добавить. А в скомпилированном виде ничего этого не нужно, т.к. мы просто ссылаемся на уже существующие в resources.arcs
идентификаторы, а не создаём новые.
Как решить эту проблему? Добавить @+id вместо @id где требуется (исключение, пожалуй, составит RelaiveLayout. Там придется комбинировать ссылку и объявление id).
Приложение использует нативные библиотеки (сошки). Положил их в папку /libs/
моего модуля, но при компиляции их нет. WAT?
Для нативных библиотек требуется отдельная папка /jniLibs/
. Библиотеки должны быть разбиты на архитектуры по разным папкам. Создать её нужно в том же каталоге, в котором находится папка /libs/
с JAR файлами. А устранить ошибки IDE можно с помощью специальной аннотации lint.
Собрал приложение, но оно крашится при старте.
Проверьте, все ли activity вы указали в файле AndroidManifest.xml. Если все activity/сервисы перенесены верно, то ищите проблему в логе. По моему личному опыту, подопытный кролик заведется только с 5-й - 6-й попытки. Ничто не бывает с первого раза. Всегда что-нибудь да забудешь.
О том, как работают обфускаторы, как понять такой код, и как реанимировать кусман говна мамонта будет написано в следующих постах.