Здесь будет показан способ полной декомпиляции apk файла. Основная ценность этой статьи в описании и сравнении полезных утилит.
0. Зачем?
1) Чтобы посмотреть как другие приложения работают. Для учебных целей, для копирования функционала и т.д.
2) Чтобы разобрать приложение популярное, "пропатчить" его малварём и собрать обратно (об этом возможно в другой статье или никогда)
1. Список утилит.
Они использоваться будут не все, но знать о них полезно. Ссылки на исходники будут в конце описания конкретной утилиты. Если модераторы посчитают пост полезным - сделают нормальные ссылки.
1) apktool - базовая утилита для декомпайла ресурсов приложения и байткода .dex в .smali Формат плохочитабелен для людей, говорят похож на ассемблер.
Полезно, если надо посмотреть статические ресурсы, вроде строк, layout, drawable и т.д.
Ссылка - github.com/iBotPeaches/Apktool
2) dex2jar - Конвертирует .dex в .jar. Т.е. в промежуточной java байткод .class. Утилита безнадёжно устарела, давно не . На больших апк крашится в тихую. Не советую использовать.
Ссылка - github.com/pxb1988/dex2jar
3) enjarify - Делает тоже самое, что и dex2jar только лучше. Разрабатывается google, написана на питон. Её мы будем использовать.
Ссылка - github.com/google/enjarify
4) fernflower - Конвертирует .class .jar в java код. Основная утилита, что я использую. Поддерживается компанией jetbrains. Есть такая плюшка, как переименование коротких названий в более осмысленные (деобфуксация). Его можно собрать из исходников в репозитории по ссылке.
А можно скачать собранную мною версию - yiy4ksveqrax675y.onion/files/ce0b22393dd2c1d7063d20a21289482b.txt (расширение поменять на jar)
Ссылка - github.com/JetBrains/intellij-community/tree/master/plugins/java-decompiler/engine
Некоторые методы он просто не разбирает, вроде такого. Причина мне неизвестна.
protected void onActivityResult(int param1, int param2, Intent param3) {
// $FF: Couldn't be decompiled
}
Деобфуксация тоже работает негладко - воздействует только на имена <= 3 символов. В большом проекте много и по 4 символа. Но, если очень надо, то можно в исходниках это поправить. Ещё деобфуксация не работает с названиями классов.
5) Procyon - Конвертирует .class .jar в java код. Я использую в качестве вспомогательной утилиты, там где fernflower не справился.
Ссылка - bitbucket.org/mstrobel/procyon/wiki/Java%20Decompiler
Иногда procyon выдаёт такую вот хуету (compile error). Но это норм, безгрешных декомпиляторов нет. Намного лучше, чем jadx и jd:
try {
this.getContentResolver().takePersistableUriPermission(intent.getData(), 3);
}
finally {
final Throwable t;
Log.e("BaseActivity", "data=" + intent, t);
}
6) CFR - Конвертирует .class .jar в java код. Утилита тоже неплохая, но похуже, чем fernflower и procyon. Можно использовать в качестве вспомогательной утилиты.
Ссылка - benf.org/other/cfr/
Вот какие траблы иногда бывают - бесконечные циклы и goto, там где они вообще не должны быть
try {
super.onBackPressed();
do {
return;
break;
} while (true);
}
catch (IllegalStateException var1_1) {
String string2 = "SomeAnonymousString";
String string3 = "";
Log.e((String)string2, (String)string3, (Throwable)var1_1);
return;
}
7) jadx-gui. Deprecated. Оконный интерфейс. Конвертирует .apk .jar .class в java код. Со своей задачей справляется, но не всегда хорошо. Не поддерживает фичи >= java7.
Ссылка - github.com/skylot/jadx
Раньше, на windows, пользовался им и норм. Сейчас почему-то на моём ноуте с достаточно мощными характеристиками i7 16gb memory он не может открыть апк, идёт декомпиляция, комп шумит как негр на плантации и фриз. Не хочу в нём копаться ради примера плохого кода, просто поверьте, что качество декомпиляции хуже вышеупомянутых.
8) jd-gui. Deprecated. Оконный интерфейс. Конвертирует .class .jar в .java код. В принципе работает, но не поддерживает фичи java7 java8. Хуже вышеупомянутых.
Иногда выдаёт такую вот хуету (какие-то ебанутые бесконечноые циклы и переменная bool, которая объявляется после присвоения - compile error):
try{
bool = super.dispatchTouchEvent(paramMotionEvent);
}
catch (IllegalArgumentException localIllegalArgumentException){
for (;;)
{
String str1 = "BaseActivity";
String str2 = "";
Log.e(str1, str2, localIllegalArgumentException);
boolean bool = false;
Object localObject = null;
}
}
return bool;
fernflower Этот же метод отлично раскомпилировал.
9) Невошедшие в список, потому что мне в лом сейчас их тестить. Потом займусь. Второй выглядит мутно, так что можете не тратить время. Первый же можно проверить, говорят норм.
Ссылка - github.com/Storyyeller/Krakatau
Ссылка - github.com/bradsdavis/candle-decompiler
2. Полная декомпиляция приложения до исходного вида.
1) Воспользуемся apktool. java -jar ~/apktool/apktool_2.1.1.jar d -f ~/apktool/apk/somefile.apk
Получим декомпилированные ресурсы: картинки, строки, атрибуты и манифест и т.д. Все как на блюдечке, кроме кода. Папку smali можно сразу удалять.
2) Воспользуемся enjarify, чтобы получить промежуточный байткод .class запакованный в .jar . cd ~/Android/apktool/enjarify ~/apktool/enjarify/enjarify.sh ~/apktool/apk/somefile.apk
mv ~/apktool/enjarify/somefile-enjarify.jar ~/apktool/sources
Для работы необходим python3 или лучше pypy3.
3) Воспользуемся fernflower, чтобы из jar с .class получить .jar с человечески читабельной .java -jar ~/apktool/fernflower.jar -ren=1 -dgs=1 ~/apktool/sources/somefile-enjarify.jar ~/apktool/sources/fernflower/
Tip* Папка, в которой находится jar для декомпайла, и папка для output должны отличатся, иначе будут очень странные ошибки
Tip** -ren=1 для деобфуксации. -dgs=1 для декампайла дженериков<Integer>
Из получившегося архива .jar копируем java файлы в наш проект
4) Необязательный пункт. Если какие-то методы/классы не декомпилировались, такое бывает. То советую воспользоваться утилитой procyon, возможно у неё получится. java -jar ~/apktool/procyon-decompiler-0.5.30.jar -jar ~/apktool/sources/somefile-enjarify.jar -o ~/apktool/sources/procyon
*Tip Не советую использовать систему windows, потому что, если обфуксация была без флага -dontusemixedcaseclassnames (Disable: obfuscated class names can contain a mix of upper-case characters and lower-case characters), то на windows будут ошибки, т.к. она case insensetive. Да и вообще windows гавно.
5) Профит! У нас получился близкий к исходному android проект. Конечно, будет куча синтаксических ошибок, в зависимости от сложности жертвы, но их можно будет просто исправить в ручную.