public void computeSizesFromOffsets() { int end = fileSize; for (int i = sections.length - 1; i >= 0; i--) { Section section = sections[i]; if (section.off == Section.UNDEF_OFFSET) { continue; } if (section.off > end) { throw new DexException("Map is unsorted at " + section); } section.byteCount = end - section.off; end = section.off; } dataOff = header.byteCount + stringIds.byteCount + typeIds.byteCount + protoIds.byteCount + fieldIds.byteCount + methodIds.byteCount + classDefs.byteCount; dataSize = fileSize - dataOff; }
/** * Gets the B register number, as a code unit. This will throw if the * value is out of the range of an unsigned code unit. */ public static short getBUnit(int b) { if ((b & ~0xffff) != 0) { throw new DexException("Register B out of range: " + Hex.u8(b)); } return (short) b; }
public static int getLiteralInt(long literal) { if (literal != (int) literal) { throw new DexException("Literal out of range: " + Hex.u8(literal)); } return (int) literal; }
public static int getLiteralByte(long literal) { if (literal != (byte) literal) { throw new DexException("Literal out of range: " + Hex.u8(literal)); } return (int) literal & 0xff; }
/** * Gets the A register number, as a code unit. This will throw if the * value is out of the range of an unsigned code unit. */ public static short getAUnit(int a) { if ((a & ~0xffff) != 0) { throw new DexException("Register A out of range: " + Hex.u8(a)); } return (short) a; }
public static int getLiteralNibble(long literal) { if ((literal < -8) || (literal > 7)) { throw new DexException("Literal out of range: " + Hex.u8(literal)); } return (int) literal & 0xf; }
public static short getLiteralUnit(long literal) { if (literal != (short) literal) { throw new DexException("Literal out of range: " + Hex.u8(literal)); } return (short) literal; }
/** * Reads an unsigned leb128 integer from {@code in}. */ public static int readUnsignedLeb128(ByteInput in) { int result = 0; int cur; int count = 0; do { cur = in.readByte() & 0xff; result |= (cur & 0x7f) << (count * 7); count++; } while (((cur & 0x80) == 0x80) && count < 5); if ((cur & 0x80) == 0x80) { throw new DexException("invalid LEB128 sequence"); } return result; }
public void writeTo(File dexOut) throws IOException { OutputStream out = null; try { out = new BufferedOutputStream(new FileOutputStream(dexOut)); writeTo(out); } catch (Exception e) { throw new DexException(e); } finally { if (out != null) { try { out.close(); } catch (Exception e) { // ignored. } } } }
public StringData readStringData() { int off = data.position(); try { int expectedLength = readUleb128(); String result = Mutf8.decode(this, new char[expectedLength]); if (result.length() != expectedLength) { throw new DexException("Declared length " + expectedLength + " doesn't match decoded length of " + result.length()); } return new StringData(off, result); } catch (UTFDataFormatException e) { throw new DexException(e); } }
/** * Reads an signed integer from {@code in}. */ public static int readSignedLeb128(ByteInput in) { int result = 0; int cur; int count = 0; int signBits = -1; do { cur = in.readByte() & 0xff; result |= (cur & 0x7f) << (count * 7); signBits <<= 7; count++; } while (((cur & 0x80) == 0x80) && count < 5); if ((cur & 0x80) == 0x80) { throw new DexException("invalid LEB128 sequence"); } // Sign extend if appropriate if (((signBits >> 1) & result) != 0) { result |= signBits; } return result; }
@Override public int byteCountInDex() { try { return Leb128.unsignedLeb128Size(value.length()) + (int) Mutf8.countBytes(value, true) + SizeOf.UBYTE; } catch (UTFDataFormatException e) { throw new DexException(e); } } }
public static int getTargetByte(int target, int baseAddress) { int relativeTarget = getTarget(target, baseAddress); if (relativeTarget != (byte) relativeTarget) { throw new DexException( "Target out of range: " + Hex.s4(relativeTarget) + ", perhaps you need to enable force jumbo mode." ); } return relativeTarget & 0xff; }
public static short getTargetUnit(int target, int baseAddress) { int relativeTarget = getTarget(target, baseAddress); if (relativeTarget != (short) relativeTarget) { throw new DexException( "Target out of range: " + Hex.s4(relativeTarget) + ", perhaps you need to enable force jumbo mode." ); } return (short) relativeTarget; }
throw new DexException("Expected " + DexFormat.DEX_IN_JAR_NAME + " in " + file); loadFrom(in, (int) file.length()); } catch (Exception e) { throw new DexException(e); } finally { if (in != null) { throw new DexException("unknown output extension: " + file);
@Override public void visitFillArrayDataPayloadInsn(int currentAddress, int opcode, Object data, int size, int elementWidth) { mapAddressIfNeeded(currentAddress); this.currentPromotedAddress += 2 + 2; switch (elementWidth) { case 1: { int length = ((byte[]) data).length; this.currentPromotedAddress += (length >> 1) + (length & 1); break; } case 2: { this.currentPromotedAddress += ((short[]) data).length * 1; break; } case 4: { this.currentPromotedAddress += ((int[]) data).length * 2; break; } case 8: { this.currentPromotedAddress += ((long[]) data).length * 4; break; } default: { throw new DexException("bogus element_width: " + Hex.u2(elementWidth)); } } } }
private void readMap(Dex.Section in) throws IOException { int mapSize = in.readInt(); Section previous = null; for (int i = 0; i < mapSize; i++) { short type = in.readShort(); in.readShort(); // unused Section section = getSection(type); int size = in.readInt(); int offset = in.readInt(); if ((section.size != 0 && section.size != size) || (section.off != Section.UNDEF_OFFSET && section.off != offset)) { throw new DexException("Unexpected map value for 0x" + Integer.toHexString(type)); } section.size = size; section.off = offset; if (previous != null && previous.off > section.off) { throw new DexException("Map is unsorted at " + previous + ", " + section); } previous = section; } header.off = 0; Arrays.sort(sections); // Skip header section, since its offset must be zero. for (int i = 1; i < sections.length; ++i) { if (sections[i].off == Section.UNDEF_OFFSET) { sections[i].off = sections[i - 1].off; } } }
throw new DexException("Unexpected magic: " + Arrays.toString(magic)); int headerSize = headerIn.readInt(); if (headerSize != SizeOf.HEADER_ITEM) { throw new DexException("Unexpected header: 0x" + Integer.toHexString(headerSize)); throw new DexException("Unexpected endian tag: 0x" + Integer.toHexString(endianTag)); mapList.off = headerIn.readInt(); if (mapList.off == 0) { throw new DexException("Cannot merge dex files that do not contain a map");
throw new DexException("bogus element_width: " + Hex.u2(elementWidth));
public short[] transform(short[] encodedInstructions) throws DexException { ShortArrayCodeOutput out = new ShortArrayCodeOutput(encodedInstructions.length); InstructionPromoter ipmo = new InstructionPromoter(); InstructionWriter iw = new InstructionWriter(out, ipmo); InstructionReader ir = new InstructionReader(new ShortArrayCodeInput(encodedInstructions)); try { // First visit, we collect mappings from original target address to promoted target address. ir.accept(new InstructionTransformVisitor(ipmo)); // Then do the real transformation work. ir.accept(new InstructionTransformVisitor(iw)); } catch (EOFException e) { throw new DexException(e); } return out.getArray(); }