Avatar ·

Как декомпилировать DEX-файл обратно в исходный код Java?

Привет, коллеги! Я новичок в Android-разработке и reverse engineering. Столкнулся с такой задачей: у меня есть APK-файл (обычное Android-приложение), и я хочу посмотреть, как внутри устроена какая-то логика. Я знаю, что байт-код Java (JVM) компилируется в DEX (Dalvik Executable) для Android. Но как из этого DEX получить обратно читаемый Java-код? Я пытался просто открыть APK как ZIP-архив и найти classes.dex, но это бинарник, его не прочитать. Пробовал конвертировать DEX в JAR с помощью утилиты dex2jar, а потом открыть JAR в декомпиляторе (например, JD-GUI). В некоторых случаях это работает, но часто код получается обфусцированным (a, b, c вместо имён переменных) или вообще ломается. Вот пример того, что я вижу после декомпиляции: ```java public class a { public static String a(String str) { int i = 0; for (int i2 = 0; i2 < str.length(); i2++) { i = (i + str.charAt(i2)) * 17; } return Integer.toHexString(i); } } ``` Как это превратить в нормальный код с понятными именами? Может, есть инструменты, которые делают это лучше, чем связка dex2jar + JD-GUI? Или может быть, можно обойтись без JAR и декомпилировать DEX напрямую? Заранее спасибо за советы! <<>>

Почему dex2jar + JD-GUI — не лучший выбор

Связка dex2jar и JD-GUI устарела и часто даёт плохие результаты из-за обфускации, потери информации о типах и неполной поддержки новых версий DEX (Android API 26+). Для качественной декомпиляции DEX в Java-код лучше использовать специализированные инструменты, работающие напрямую с DEX-форматом.

Лучший инструмент: JADX

JADX (GitHub: skylot/jadx) — это декомпилятор, который напрямую читает DEX (или APK/AAR) и выдаёт читаемый Java-код. Он поддерживает:

  • Декомпиляцию в Java-код с восстановлением имён (если не обфусцировано).
  • Декомпиляцию ресурсов (AndroidManifest.xml, layouts).
  • Экспорт в Gradle-проект.
  • Графический интерфейс (GUI) и консольный режим.

Пошаговая инструкция

  1. Скачайте JADX с GitHub (последний релиз) и распакуйте.
  2. Запустите GUI (jadx-gui.bat на Windows, jadx-gui на Linux/Mac).
  3. Откройте APK или DEX-файл через меню File → Open.
  4. Просмотрите код — JADX покажет структуру пакетов и классов.
  5. Экспортируйте в Java-файлы: File → Save as Gradle project.

Пример декомпиляции с JADX

Исходный DEX (обфусцированный):

public class a {
    public static String a(String str) {
        int i = 0;
        for (int i2 = 0; i2 < str.length(); i2++) {
            i = (i + str.charAt(i2)) * 17;
        }
        return Integer.toHexString(i);
    }
}

JADX может восстановить это как:

public class HashUtils {
    public static String computeHash(String input) {
        int hash = 0;
        for (int i = 0; i < input.length(); i++) {
            hash = (hash + input.charAt(i)) * 17;
        }
        return Integer.toHexString(hash);
    }
}

Если код сильно обфусцирован (например, ProGuard/R8), JADX не сможет восстановить исходные имена, но он правильно восстановит логику и структуру.

Альтернативы JADX

  • CFR — мощный декомпилятор Java bytecode (работает с JAR). Используйте его, если сначала конвертировали DEX → JAR через d2j-dex2jar.sh.
  • Procyon — ещё один декомпилятор для JAR, часто даёт более чистый код, чем JD-GUI.
  • Bytecode Viewer — универсальный инструмент с поддержкой нескольких декомпиляторов (CFR, Procyon, Fernflower).

Как бороться с обфускацией

Если код выглядит как a.b.c(d.e), попробуйте:

  • Использовать deobfuscator (например, Simplify для Android).
  • Вручную переименовать классы/методы, анализируя их вызовы.
  • Запустить приложение в эмуляторе и посмотреть логи (Logcat) — часто строки и имена не обфусцированы.

Итог

Для быстрой и качественной декомпиляции DEX в Java используйте JADX. Он лучше всего подходит для Android reverse engineering. Если нужно декомпилировать JAR — берите CFR или Procyon. Избегайте JD-GUI для серьёзной работы.

<<>>

Консольный подход: JADX в командной строке

Если вам не нужен GUI (например, для автоматизации или работы на сервере), используйте консольную версию JADX:

jadx -d output_dir app.apk

Это создаст папку output_dir с исходниками Java и ресурсами. Флаги:

  • -r — декомпилировать только ресурсы (без кода).
  • -e — экспортировать как Android-проект.
  • --deobf — попытаться восстановить имена (слабо помогает).

Альтернатива: Enjarify — лучшая замена dex2jar

Enjarify (Google) — это утилита для конвертации DEX в JAR, которая работает лучше, чем dex2jar, особенно с новыми версиями Android. Используйте так:

python3 -m enjarify classes.dex

После этого вы получите JAR, который можно открыть любым декомпилятором (например, CFR).

Сравнение подходов

  • JADX (прямая декомпиляция DEX) — лучший результат, меньше шагов, но требует Java 8+.
  • Enjarify + CFR — если JADX не справляется (редко), даёт больше контроля над процессом.
  • APKTool — не декомпилирует в Java, а только в smali (ассемблер DEX). Используйте, если нужно редактировать код и пересобрать APK.

Совет

Для сложных случаев (обфускация, шифрование) комбинируйте JADX с отладчиком (например, Frida) — это поможет понять логику, которую декомпилятор не может восстановить.