pxb1988/dex2jar · error · BadOpException
index-out-of-range for
Error message
index-out-of-range for %s index: %d
What it means
DexFileReader throws BadOpException when an instruction references a method/proto/field/type/string index that is out of range of the corresponding ids table (e.g. idx >= method_ids_size or idx2 >= proto_ids_size for invoke-type ops). The library validates indexability before continuing so downstream lookups cannot read past the tables. It indicates a corrupt or deliberately malformed dex.
Solutions
- Verify the dex with an official verifier before conversion.
- Rebuild or re-extract the dex from a known-good APK.
- Use a tool that repairs dex headers/id tables before running d2j.
- Catch BadOpException per method/class and skip the invalid one.
Example fix
// before
dexReader.accept(visitor, 0);
// after
try {
dexReader.accept(visitor, 0);
} catch (BadOpException e) {
LOG.warn("out-of-range index: " + e.getMessage());
} Defensive patterns
Strategy: try-catch
Validate before calling
// parse header and ensure id tables look sane before decoding
int methodIdsSize = ByteBuffer.wrap(data, 88, 4).order(ByteOrder.LITTLE_ENDIAN).getInt();
if (methodIdsSize < 0 || methodIdsSize > data.length / 8) throw new IllegalArgumentException("implausible method_ids_size"); Try / catch
try {
dexReader.accept(visitor, 0);
} catch (BadOpException e) {
LOG.warn("index out of range: " + e.getMessage());
} Prevention
- Validate dex header (checksum, file_size, ids sizes) before decoding
- Use dex repair tooling for packed/protected APKs
- Skip-and-log offending methods in batch conversion pipelines
When it happens
Trigger: Decoding a dex whose instructions contain index operands equal to or larger than method_ids_size/proto_ids_size/etc., detected in the op.indexType switch that sets canContinue = false.
Common situations: Analyzing obfuscated or packed APKs that corrupt index tables to break static tools; fuzzed dex inputs; dex files spliced between versions.
Related errors
- bad payload for
- bad payload offset for
- while accept code in method
- zero-width instruction op=0x%02x
- jump out of insns -> %04x
AI-assisted analysis of pxb1988/dex2jar@b5bda4fb49 (2026-09-08).
Data as JSON: /api/errors/3bc7e4d0469d53e4.
Report an issue: GitHub.
Appendix: source
Thrown at dex-reader/src/main/java/com/googlecode/d2j/reader/DexFileReader.java:1299
canContinue = idx < method_ids_size;
break;
case kIndexFieldRef:
idx = ushort(insns, u1offset + 2);
canContinue = idx < field_ids_size;
break;
case kIndexCallSiteRef:
idx = ushort(insns, u1offset + 2);
canContinue = idx < call_site_ids_size;
break;
case kIndexMethodAndProtoRef:
idx = ushort(insns, u1offset + 2);
int idx2 = ushort(insns, u1offset + 6);
canContinue = idx < method_ids_size && idx2 < proto_ids_size;
break;
default:
}
if (!canContinue) {
throw new BadOpException("index-out-of-range for %s index: %d", op, idx);
}
}
if (canContinue && op.canContinue()) {
if (op == Op.NOP) {
switch (insns[u1offset + 1]) {
case 0x00:
q.add(offset + Op.NOP.format.size);
break;
case 0x01: {
int size = ushort(insns, u1offset + 2);
q.add(offset + (size * 2) + 4);
break;
}
case 0x02: {
int size = ushort(insns, u1offset + 2);
q.add(offset + (size * 4) + 2);
break;
View on GitHub (pinned to b5bda4fb49)