How to decompile DEX into Java source code?

Decompiling DEX to Java Source Code: A Detailed Guide

DEX (Dalvik Executable) files are Android’s compiled bytecode format. To convert them back to readable Java source code, follow this comprehensive process:

1. Key Tools Required

ToolPurpose
dex2jarConverts DEX to Java-compatible JAR
Java DecompilerConverts JAR to Java source
APK ToolExtracts DEX from APK (optional)
JADXAll-in-one decompiler (recommended)

2. Step-by-Step Process

Option 1: Using dex2jar + Java Decompiler
  1. Extract DEX from APK:
   unzip app.apk -d apk_out
   # DEX files: classes.dex, classes2.dex, etc.
  1. Convert DEX to JAR:
   d2j-dex2jar.sh apk_out/classes.dex -o classes.jar
  1. Decompile JAR to Java:
  • Use JD-GUI (GUI tool): Open classes.jar
  • Or CFR (CLI):
    bash java -jar cfr.jar classes.jar --outputdir src/
Option 2: Using JADX (Recommended)
  1. Decompile directly:
   jadx -d src app.apk  # For APK
   jadx -d src classes.dex  # For DEX file
  1. Key JADX flags:
   jadx --show-version --deobfuscate -r -d src app.apk
  • --deobfuscate: Rename obfuscated classes/vars
  • -r: Skip resources (faster decompilation)

3. Example Workflow

Input: app.apk with obfuscated code
Goal: Decompile to readable Java

  1. Use JADX:
   jadx --deobfuscation-on --output-dir src app.apk
  1. Output Structure:
   src/
   ├── com/
   │   └── example/
   │       ├── MainActivity.java
   │       └── utils/
   │           └── NetworkHelper.java
   ├── resources/
   └── AndroidManifest.xml
  1. Decompiled Java Sample:
   // Before deobfuscation
   public class a extends Activity {
       protected void onCreate(Bundle b) {
           super.onCreate(b);
           setContentView(0x7f0b001c); // R.layout.activity_main
       }
   }

   // After deobfuscation (JADX output)
   public class MainActivity extends Activity {
       protected void onCreate(Bundle savedInstanceState) {
           super.onCreate(savedInstanceState);
           setContentView(R.layout.activity_main);
       }
   }

4. Handling Common Issues

  • Multi-DEX APKs:
    JADX automatically processes all classes*.dex files.
  • Obfuscated Code:
  • Use JADX’s --deobfuscation-on
  • Enable renaming in dex2jar: d2j-dex2jar.sh --keep-bridge-syn ...
  • Incomplete Decompilation:
  • Switch tools: Try FernFlower or CFR for problematic files
  java -jar fernflower.jar classes.jar src/

5. Advanced Scenarios

Decompiling System DEX (e.g., framework.jar):

  1. Pull from device:
   adb pull /system/framework/framework.jar
  1. Extract DEX:
   unzip framework.jar classes.dex
  1. Decompile with JADX:
   jadx classes.dex -d framework_src

Dynamic Analysis:

  • Use Frida to dump runtime DEX:
  Java.perform(() => {
    const dex = Java.openClassFile('/data/local/tmp/dump.dex').load();
  });

6. Legal & Ethical Considerations

  • Legal Compliance: Decompile only apps you own or have explicit permission for.
  • Obfuscation Best Practices:
  # ProGuard rules to prevent decompilation
  -keep class com.example.** { *; }
  -useuniqueclassmembernames

7. Comparison of Java Decompilers

ToolSpeedReadabilityObfuscation Handling
JADX⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
CFR⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
FernFlower⭐⭐⭐⭐⭐⭐⭐⭐⭐
JD-GUI⭐⭐⭐⭐⭐⭐⭐⭐⭐

Final Recommendations

  1. Use JADX for 90% of cases (CLI + GUI versions available)
  2. Combine with dex2jar for edge-case files
  3. Enable deobfuscation for production apps
  4. Verify decompiled code against smali (assembly-like) when debugging

Note: Perfect decompilation isn’t always possible due to compiler optimizations. Expect to see some synthetic classes or goto statements in complex code.

Leave a Reply

Your email address will not be published. Required fields are marked *