pxb1988/dex2jar · error · BadOpException

bad payload for

Error message

bad payload for %s

What it means

DexFileReader throws BadOpException when an instruction requires a data payload (switch or fill-array-data pseudo-op) but the payload found at the computed offset is not a valid packed-switch/sparse-switch/array-data payload for that opcode. The reader cannot interpret the referenced data, indicating a malformed or tampered dex.

Solutions

  1. Re-acquire the dex from a trusted build; rebuild if it came from a custom toolchain.
  2. Validate the dex with a verifier (e.g., dx/dexdump) before running d2j.
  3. If analyzing protected apps, use a deobfuscation pass that fixes pseudo-op payloads first.
  4. Catch BadOpException per method and skip/report the offending method instead of aborting.

Example fix

// before
dexReader.accept(visitor, 0);
// after
try {
    dexReader.accept(visitor, 0);
} catch (BadOpException e) {
    LOG.warn("bad payload: " + e.getMessage());
}
Defensive patterns

Strategy: try-catch

Validate before calling

// run a structural pass with a verifier before d2j
// dexdump -d classes.dex  (or apkanalyzer dex packages) to reject malformed input

Try / catch

try {
    dexReader.accept(visitor, 0);
} catch (BadOpException e) {
    LOG.warn("bad payload for op: " + e.getMessage());
}

Prevention

When it happens

Trigger: Decoding a dex where a switch/fill-array-data instruction points at an offset whose payload opcode does not match the expected pseudo-op (e.g., a packed-switch op pointing at a payload that is not kPackedSwitchPayload).

Common situations: Analyzing dex files rewritten by obfuscators; hand-patched bytecode where offsets were edited; tools that reassemble dex with incorrect pseudo-op links.

Related errors


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

Appendix: source

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

                            }
                            break;
                        }
                        case 0x02:// sparse-switch-data
                        {
                            int size = ushort(insns, u1SwitchData + 2);
                            int b = u1SwitchData + 4 + 4 * size;// targets
                            for (int i = 0; i < size; i++) {
                                target = offset + sint(insns, b + i * 4);
                                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;
                        }
                        default:
                            throw new BadOpException("bad payload for %s", op);
                    }
            } else {
                throw new BadOpException("bad payload offset for %s", op);
            }
        }

        if (canContinue) {
            int idx = Integer.MAX_VALUE;
            switch (op.indexType) {
            case kIndexStringRef:
                if (op.format == InstructionFormat.kFmt31c) {
                    idx = uint(insns, u1offset + 2);
                } else {// other
                    idx = ushort(insns, u1offset + 2);
                }
                canContinue = idx >= 0 && idx < string_ids_size;
                break;
            case kIndexTypeRef:

View on GitHub (pinned to b5bda4fb49)