iBotPeaches/Apktool · error · AndrolibException

Cannot disassemble an odex file without deodexing it: {dexNa

Error message

Cannot disassemble an odex file without deodexing it: {dexName}

What it means

During baksmali decoding, a dex file in the container reports supportsOptimizedOpcodes(), i.e. it is an optimized dex (odex/oat artifact from a device's dalvik-art cache), not plain dex. Baksmali cannot disassemble optimized opcodes without a deodexing context, so apktool refuses.

Source

Thrown at brut.apktool/apktool-lib/src/main/java/brut/androlib/smali/SmaliDecoder.java:103

                int dexNum;
                try {
                    dexNum = Integer.parseInt(dexEntryName.substring(prefix.length()));
                } catch (NumberFormatException ignored) {
                    continue;
                }
                if (dexNum > 1) {
                    dexFiles.put(dexNum, mDexContainer.getEntry(dexEntryName).getDexFile());
                }
            }

            // Decode the dex files into separate folders.
            for (Map.Entry<Integer, DexBackedDexFile> entry : dexFiles.entrySet()) {
                int dexNum = entry.getKey();
                DexBackedDexFile dexFile = entry.getValue();

                if (dexFile.supportsOptimizedOpcodes()) {
                    throw new AndrolibException("Cannot disassemble an odex file without deodexing it: " + dexName);
                }

                String dirName = "smali";
                if (dexNum > 1 || !dexName.equals("classes.dex")) {
                    dirName += "_" + dexName.substring(0, dexName.lastIndexOf('.')).replace('/', '@');
                    if (dexNum > 1) {
                        dirName += dexNum;
                    }
                }

                decodeFile(dexFile, new File(outDir, dirName));
            }

            mDexFiles.add(dexName);
        } catch (IOException ex) {
            throw new AndrolibException("Could not baksmali file: " + dexName, ex);
        }
    }

View on GitHub (pinned to 79b63384d7)

Solutions

  1. Decode the original APK (base.apk from the device/Play store) rather than dalvik-cache artifacts
  2. For real odex files, deodex first using baksmali with a matching boot.oat/boot.art (`baksmali deodex -b boot.oat file.odex`), then work with the plain dex
  3. Ensure the odex's boot image comes from the exact same ROM build as the odex, otherwise deodex fails
  4. Alternatively skip the odex entry: decode only known plain-dex entries by name

Example fix

# before
# pulled /data/dalvik-cache/arm64/data@app@@com.example*==/base.apk@classes.dex
apktool d cached.apk   # Cannot disassemble an odex file without deodexing it

# after
# get the original, non-optimized artifact and deodex properly
baksmali deodex -b boot.oat app.odex -o out
apktool d original-base.apk
Defensive patterns

Strategy: validation

Validate before calling

// Detect optimized dex before decode
// DexBackedDexFile.supportsOptimizedOpcodes() is the check apktool uses;
// from outside, screen inputs by origin: reject files pulled from dalvik-cache
if (path.contains("dalvik-cache") || path.endsWith(".odex")) {
    throw new IllegalArgumentException("Optimized dex requires deodexing first: " + path);
}

Try / catch

try {
    decoder.decode(dexName, outDir);
} catch (AndrolibException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Cannot disassemble an odex")) {
        // deodex with matching boot.oat via baksmali, or decode the original APK instead
    } else { throw e; }
}

Prevention

When it happens

Trigger: Calling SmaliDecoder.decode on an APK or container that contains an odex entry (e.g. classes pulled from /data/dalvik-cache, or an .odex file), where the dex uses quickened/optimized opcodes.

Common situations: Pulling optimized dex from a rooted device's ART cache instead of the original APK; handling OEM .odex files; trying to decode with a tool version whose deodex path is not enabled.

Related errors


AI-assisted analysis of iBotPeaches/Apktool@79b63384d7 (2026-08-14). Data as JSON: /api/errors/783c714edc0c6f2d. Report an issue: GitHub.