import java.io.File; import com.android.tools.smali.baksmali.Baksmali; import com.android.tools.smali.baksmali.BaksmaliOptions; import com.android.tools.smali.dexlib2.DexFileFactory; import com.android.tools.smali.dexlib2.Opcodes; import com.android.tools.smali.dexlib2.iface.DexFile; import com.android.tools.smali.dexlib2.iface.MultiDexContainer; /** * Disassembles d8's classes.dex to smali with the baksmali bundled in apktool.jar, so that * apktool re-assembles it with dexlib2 (clean dex 035, correct checksums). * usage: java -cp apktool.jar:. Disassemble classes.dex out-dir api-level */ public class Disassemble { public static void main(String[] a) throws Exception { int api = Integer.parseInt(a[2]); MultiDexContainer c = DexFileFactory.loadDexContainer(new File(a[0]), Opcodes.forApi(api)); if (c.getDexEntryNames().size() != 1) throw new IllegalStateException("expected one dex, got " + c.getDexEntryNames()); DexFile dex = c.getEntry(c.getDexEntryNames().get(0)).getDexFile(); BaksmaliOptions o = new BaksmaliOptions(); o.apiLevel = api; o.debugInfo = true; // keep line numbers for readable stack traces o.localsDirective = true; o.sequentialLabels = true; if (!Baksmali.disassembleDexFile(dex, new File(a[1]), 1, o)) { throw new IllegalStateException("baksmali reported errors"); } System.out.println("disassembled " + dex.getClasses().size() + " classes"); } }