pxb1988/dex2jar · error · BadOpException

zero-width instruction op=0x%02x

Error message

zero-width instruction op=0x%02x

What it means

BadOpException thrown while traversing method instructions: the opcode byte maps to no known Op or the Op has no instruction format, i.e. a zero-width (undecodable) instruction at u1offset. The traversal cannot make progress, so it aborts.

Solutions

  1. Upgrade to a d2j/dex-translator version whose Op table covers the dex's opcode version
  2. Check the op=0x%02x value against the dalvik opcode table to identify the missing opcode
  3. Disassemble the method with baksmali to confirm the bytecode is valid
  4. Rebuild/reobfuscate the app disabling the transformation that injects junk opcodes

Example fix

// before
// d2j 2.x Op table lacking newer opcodes
// after
// upgrade dependency:
// <artifactId>dex-reader</artifactId> <version>latest</version>
Defensive patterns

Strategy: validation

Validate before calling

// Check opcode support before accepting
int opcodeByte = 0xFF & insns[offset];
if (opcodeByte > maxSupportedOpcode) throw new IllegalArgumentException("unsupported op 0x" + Integer.toHexString(opcodeByte));

Try / catch

try {
    reader.accept(dmv);
} catch (DexException e) {
    if (e.getCause() instanceof BadOpException) { /* skip method */ }
}

Prevention

When it happens

Trigger: acceptCode's opcode walker reads insns[u1offset] and Op.ops[opcode] is null or op.format == null — an unknown/invalid opcode byte where an instruction is expected.

Common situations: Dex compiled for a newer ART/dalvik version with opcodes this d2j doesn't know, obfuscated dexes with junk bytes, or a bad offset landing mid-instruction.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of pxb1988/dex2jar@b5bda4fb49 (2026-09-08). Data as JSON: /api/errors/f0a94e8ffbd6ec34. Report an issue: GitHub.

Appendix: source

Thrown at dex-reader/src/main/java/com/googlecode/d2j/reader/DexFileReader.java:1154

            } catch (IndexOutOfBoundsException indexOutOfRange){
                badOps.set(offset);
                WARN("GLITCH: %04x %s | not enough space for reading instruction", offset, method.toString());
            } catch (BadOpException badOp){
                badOps.set(offset);
                WARN("GLITCH: %04x %s | %s", offset, method.toString(), badOp.getMessage());
            }
        }
    }

    private void travelInsn(Map<Integer, DexLabel> labelsMap, Queue<Integer> q, byte[] insns, int offset) {
        int u1offset = offset * 2;
        if (u1offset >= insns.length) {
            throw new IndexOutOfBoundsException();
        }
        int opcode = 0xFF & insns[u1offset];
        Op op = Op.ops[opcode];
        if (op == null || op.format == null) {
            throw new BadOpException("zero-width instruction op=0x%02x", opcode);
        }
        int target;
        boolean canContinue = true;
        if (op.canBranch()) {
            switch (op.format) {
            case kFmt10t:
                target = offset + insns[u1offset + 1];
                if (target < 0 || target * 2 > insns.length ) {
                    throw new BadOpException("jump out of insns %s -> %04x", op, target);
                }
                q.add(target);
                order(labelsMap, target);
                break;
            case kFmt20t:
            case kFmt21t:
                target = offset + sshort(insns, u1offset + 2);
                if (target < 0 || target * 2 > insns.length ) {
                    throw new BadOpException("jump out of insns %s -> %04x", op, target);

View on GitHub (pinned to b5bda4fb49)