org.jf.dexlib2.iface.instruction.Instruction Java Examples

The following examples show how to use org.jf.dexlib2.iface.instruction.Instruction. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: InstructionMethodItemFactory.java    From zjdroid with Apache License 2.0 6 votes vote down vote up
public static InstructionMethodItem makeInstructionFormatMethodItem(
        MethodDefinition methodDef, int codeAddress, Instruction instruction) {

    if (instruction instanceof OffsetInstruction) {
        return new OffsetInstructionFormatMethodItem(methodDef.classDef.options, methodDef, codeAddress,
                (OffsetInstruction)instruction);
    }

    if (instruction instanceof UnresolvedOdexInstruction) {
        return new UnresolvedOdexInstructionMethodItem(methodDef, codeAddress,
                (UnresolvedOdexInstruction)instruction);
    }

    switch (instruction.getOpcode().format) {
        case ArrayPayload:
            return new ArrayDataMethodItem(methodDef, codeAddress, (ArrayPayload)instruction);
        case PackedSwitchPayload:
            return new PackedSwitchMethodItem(methodDef, codeAddress, (PackedSwitchPayload)instruction);
        case SparseSwitchPayload:
            return new SparseSwitchMethodItem(methodDef, codeAddress, (SparseSwitchPayload)instruction);
        default:
            return new InstructionMethodItem<Instruction>(methodDef, codeAddress, instruction);
    }
}
 
Example #2
Source File: BasicBlockInstruction.java    From CFGScanDroid with GNU General Public License v2.0 6 votes vote down vote up
public BasicBlockInstruction(int address, Instruction insn) {
	this.instruction = insn;
	this.leader = address == 0 ? true : false;
	this.branch = isBranch();
	this.destinations = null;
	this.address = address;

	DexBackedInstruction dexBackedInstruction = (DexBackedInstruction)insn;
	this.offset = dexBackedInstruction.instructionStart;
	this.length = insn.getCodeUnits() * 2;
	this.rawBytes = new byte[this.length];
	// DexReader reader = readerAt(this.offset);
	for(int i=0; i<this.length; ++i) {
		this.rawBytes[i] = (byte)dexBackedInstruction.dexFile.readByte(this.offset + i);
		// System.out.print(this.rawBytes[i]);
		// System.out.print(' ');
	}
	// System.out.println();
}
 
Example #3
Source File: DexWriter.java    From HeyGirl with Apache License 2.0 6 votes vote down vote up
private void fixInstructions(@Nonnull MutableMethodImplementation methodImplementation) {
    List<? extends Instruction> instructions = methodImplementation.getInstructions();

    for (int i=0; i<instructions.size(); i++) {
        Instruction instruction = instructions.get(i);

        if (instruction.getOpcode() == Opcode.CONST_STRING) {
            if (stringSection.getItemIndex(
                    (StringRef)((ReferenceInstruction)instruction).getReference()) >= 65536) {
                methodImplementation.replaceInstruction(i, new BuilderInstruction31c(Opcode.CONST_STRING_JUMBO,
                        ((OneRegisterInstruction)instruction).getRegisterA(),
                        ((ReferenceInstruction)instruction).getReference()));
            }
        }
    }
}
 
Example #4
Source File: DexWriter.java    From ZjDroid with Apache License 2.0 6 votes vote down vote up
private void fixInstructions(@Nonnull MutableMethodImplementation methodImplementation) {
    List<? extends Instruction> instructions = methodImplementation.getInstructions();

    for (int i=0; i<instructions.size(); i++) {
        Instruction instruction = instructions.get(i);

        if (instruction.getOpcode() == Opcode.CONST_STRING) {
            if (stringSection.getItemIndex(
                    (StringRef)((ReferenceInstruction)instruction).getReference()) >= 65536) {
                methodImplementation.replaceInstruction(i, new BuilderInstruction31c(Opcode.CONST_STRING_JUMBO,
                        ((OneRegisterInstruction)instruction).getRegisterA(),
                        ((ReferenceInstruction)instruction).getReference()));
            }
        }
    }
}
 
Example #5
Source File: InstructionMethodItemFactory.java    From HeyGirl with Apache License 2.0 6 votes vote down vote up
public static InstructionMethodItem makeInstructionFormatMethodItem(
        MethodDefinition methodDef, int codeAddress, Instruction instruction) {

    if (instruction instanceof OffsetInstruction) {
        return new OffsetInstructionFormatMethodItem(methodDef.classDef.options, methodDef, codeAddress,
                (OffsetInstruction)instruction);
    }

    if (instruction instanceof UnresolvedOdexInstruction) {
        return new UnresolvedOdexInstructionMethodItem(methodDef, codeAddress,
                (UnresolvedOdexInstruction)instruction);
    }

    switch (instruction.getOpcode().format) {
        case ArrayPayload:
            return new ArrayDataMethodItem(methodDef, codeAddress, (ArrayPayload)instruction);
        case PackedSwitchPayload:
            return new PackedSwitchMethodItem(methodDef, codeAddress, (PackedSwitchPayload)instruction);
        case SparseSwitchPayload:
            return new SparseSwitchMethodItem(methodDef, codeAddress, (SparseSwitchPayload)instruction);
        default:
            return new InstructionMethodItem<Instruction>(methodDef, codeAddress, instruction);
    }
}
 
Example #6
Source File: MethodDefinition.java    From ZjDroid with Apache License 2.0 5 votes vote down vote up
public int findSwitchPayload(int targetOffset, Opcode type) {
    int targetIndex;
    try {
        targetIndex = instructionOffsetMap.getInstructionIndexAtCodeOffset(targetOffset);
    } catch (InvalidInstructionOffset ex) {
        throw new InvalidSwitchPayload(targetOffset);
    }

    //TODO: does dalvik let you pad with multiple nops?
    //TODO: does dalvik let a switch instruction point to a non-payload instruction?

    Instruction instruction = instructions.get(targetIndex);
    if (instruction.getOpcode() != type) {
        // maybe it's pointing to a NOP padding instruction. Look at the next instruction
        if (instruction.getOpcode() == Opcode.NOP) {
            targetIndex += 1;
            if (targetIndex < instructions.size()) {
                instruction = instructions.get(targetIndex);
                if (instruction.getOpcode() == type) {
                    return instructionOffsetMap.getInstructionCodeOffset(targetIndex);
                }
            }
        }
        throw new InvalidSwitchPayload(targetOffset);
    } else {
        return targetOffset;
    }
}
 
Example #7
Source File: MethodDefinition.java    From HeyGirl with Apache License 2.0 5 votes vote down vote up
public int findSwitchPayload(int targetOffset, Opcode type) {
    int targetIndex;
    try {
        targetIndex = instructionOffsetMap.getInstructionIndexAtCodeOffset(targetOffset);
    } catch (InvalidInstructionOffset ex) {
        throw new InvalidSwitchPayload(targetOffset);
    }

    //TODO: does dalvik let you pad with multiple nops?
    //TODO: does dalvik let a switch instruction point to a non-payload instruction?

    Instruction instruction = instructions.get(targetIndex);
    if (instruction.getOpcode() != type) {
        // maybe it's pointing to a NOP padding instruction. Look at the next instruction
        if (instruction.getOpcode() == Opcode.NOP) {
            targetIndex += 1;
            if (targetIndex < instructions.size()) {
                instruction = instructions.get(targetIndex);
                if (instruction.getOpcode() == type) {
                    return instructionOffsetMap.getInstructionCodeOffset(targetIndex);
                }
            }
        }
        throw new InvalidSwitchPayload(targetOffset);
    } else {
        return targetOffset;
    }
}
 
Example #8
Source File: InstructionOffsetMap.java    From HeyGirl with Apache License 2.0 5 votes vote down vote up
public InstructionOffsetMap(@Nonnull List<? extends Instruction> instructions) {
    this.instructionCodeOffsets = new int[instructions.size()];

    int codeOffset = 0;
    for (int i=0; i<instructions.size(); i++) {
        instructionCodeOffsets[i] = codeOffset;
        codeOffset += instructions.get(i).getCodeUnits();
    }
}
 
Example #9
Source File: BuilderClassPool.java    From ZjDroid with Apache License 2.0 5 votes vote down vote up
@Nullable @Override
public Iterable<? extends Instruction> getInstructions(@Nonnull BuilderMethod builderMethod) {
    MethodImplementation impl = builderMethod.getImplementation();
    if (impl == null) {
        return null;
    }
    return impl.getInstructions();
}
 
Example #10
Source File: DexBackedInstruction.java    From ZjDroid with Apache License 2.0 5 votes vote down vote up
@Nonnull
public static Instruction readFrom(@Nonnull DexReader reader) {
    int opcodeValue = reader.peekUbyte();

    if (opcodeValue == 0) {
        opcodeValue = reader.peekUshort();
    }

    Opcode opcode = reader.dexBuf.getOpcodes().getOpcodeByValue(opcodeValue);

    Instruction instruction = buildInstruction(reader.dexBuf, opcode, reader.getOffset());
    reader.moveRelative(instruction.getCodeUnits()*2);
    return instruction;
}
 
Example #11
Source File: MethodDefinition.java    From HeyGirl with Apache License 2.0 5 votes vote down vote up
private boolean needsAnalyzed() {
    for (Instruction instruction: methodImpl.getInstructions()) {
        if (instruction.getOpcode().odexOnly()) {
            return true;
        }
    }
    return false;
}
 
Example #12
Source File: DexBackedInstruction.java    From HeyGirl with Apache License 2.0 5 votes vote down vote up
@Nonnull
public static Instruction readFrom(@Nonnull DexReader reader) {
    int opcodeValue = reader.peekUbyte();

    if (opcodeValue == 0) {
        opcodeValue = reader.peekUshort();
    }

    Opcode opcode = reader.dexBuf.getOpcodes().getOpcodeByValue(opcodeValue);

    Instruction instruction = buildInstruction(reader.dexBuf, opcode, reader.getOffset());
    reader.moveRelative(instruction.getCodeUnits()*2);
    return instruction;
}
 
Example #13
Source File: ImmutableMethodImplementation.java    From zjdroid with Apache License 2.0 5 votes vote down vote up
public ImmutableMethodImplementation(int registerCount,
                                     @Nullable Iterable<? extends Instruction> instructions,
                                     @Nullable List<? extends TryBlock<? extends ExceptionHandler>> tryBlocks,
                                     @Nullable Iterable<? extends DebugItem> debugItems) {
    this.registerCount = registerCount;
    this.instructions = ImmutableInstruction.immutableListOf(instructions);
    this.tryBlocks = ImmutableTryBlock.immutableListOf(tryBlocks);
    this.debugItems = ImmutableDebugItem.immutableListOf(debugItems);
}
 
Example #14
Source File: InstructionOffsetMap.java    From ZjDroid with Apache License 2.0 5 votes vote down vote up
public InstructionOffsetMap(@Nonnull List<? extends Instruction> instructions) {
    this.instructionCodeOffsets = new int[instructions.size()];

    int codeOffset = 0;
    for (int i=0; i<instructions.size(); i++) {
        instructionCodeOffsets[i] = codeOffset;
        codeOffset += instructions.get(i).getCodeUnits();
    }
}
 
Example #15
Source File: ImmutableInstruction.java    From zjdroid with Apache License 2.0 4 votes vote down vote up
@Nonnull
@Override
protected ImmutableInstruction makeImmutable(@Nonnull Instruction item) {
    return ImmutableInstruction.of(item);
}
 
Example #16
Source File: InvokeSpecialInstruction.java    From JAADAS with GNU General Public License v3.0 4 votes vote down vote up
public InvokeSpecialInstruction (Instruction instruction, int codeAdress) {
    super(instruction, codeAdress);
}
 
Example #17
Source File: DexWriter.java    From zjdroid with Apache License 2.0 4 votes vote down vote up
private void writeDebugAndCodeItems(@Nonnull DexDataWriter offsetWriter,
                                    @Nonnull DeferredOutputStream temp) throws IOException {
    ByteArrayOutputStream ehBuf = new ByteArrayOutputStream();
    debugSectionOffset = offsetWriter.getPosition();
    DebugWriter<StringKey, TypeKey> debugWriter =
            new DebugWriter<StringKey, TypeKey>(stringSection, typeSection, offsetWriter);

    DexDataWriter codeWriter = new DexDataWriter(temp, 0);

    List<CodeItemOffset<MethodKey>> codeOffsets = Lists.newArrayList();

    for (ClassKey classKey: classSection.getSortedClasses()) {
        Collection<? extends MethodKey> directMethods = classSection.getSortedDirectMethods(classKey);
        Collection<? extends MethodKey> virtualMethods = classSection.getSortedVirtualMethods(classKey);

        Iterable<MethodKey> methods = Iterables.concat(directMethods, virtualMethods);

        for (MethodKey methodKey: methods) {
            List<? extends TryBlock<? extends ExceptionHandler>> tryBlocks =
                    classSection.getTryBlocks(methodKey);
            Iterable<? extends Instruction> instructions = classSection.getInstructions(methodKey);
            Iterable<? extends DebugItem> debugItems = classSection.getDebugItems(methodKey);

            if (instructions != null && stringSection.hasJumboIndexes()) {
                boolean needsFix = false;
                for (Instruction instruction: instructions) {
                    if (instruction.getOpcode() == Opcode.CONST_STRING) {
                        if (stringSection.getItemIndex(
                                (StringRef)((ReferenceInstruction)instruction).getReference()) >= 65536) {
                            needsFix = true;
                            break;
                        }
                    }
                }

                if (needsFix) {
                    MutableMethodImplementation mutableMethodImplementation =
                            classSection.makeMutableMethodImplementation(methodKey);
                    fixInstructions(mutableMethodImplementation);

                    instructions = mutableMethodImplementation.getInstructions();
                    tryBlocks = mutableMethodImplementation.getTryBlocks();
                    debugItems = mutableMethodImplementation.getDebugItems();
                }
            }

            int debugItemOffset = writeDebugItem(offsetWriter, debugWriter,
                    classSection.getParameterNames(methodKey), debugItems);
            int codeItemOffset = writeCodeItem(codeWriter, ehBuf, methodKey, tryBlocks, instructions, debugItemOffset);

            if (codeItemOffset != -1) {
                codeOffsets.add(new CodeItemOffset<MethodKey>(methodKey, codeItemOffset));
            }
        }
    }

    offsetWriter.align();
    codeSectionOffset = offsetWriter.getPosition();

    codeWriter.close();
    temp.writeTo(offsetWriter);
    temp.close();

    for (CodeItemOffset<MethodKey> codeOffset: codeOffsets) {
        classSection.setCodeItemOffset(codeOffset.method, codeSectionOffset + codeOffset.codeOffset);
    }
}
 
Example #18
Source File: SputInstruction.java    From JAADAS with GNU General Public License v3.0 4 votes vote down vote up
public SputInstruction (Instruction instruction, int codeAdress) {
    super(instruction, codeAdress);
}
 
Example #19
Source File: ImmutableInstruction.java    From ZjDroid with Apache License 2.0 4 votes vote down vote up
@Nonnull
@Override
protected ImmutableInstruction makeImmutable(@Nonnull Instruction item) {
    return ImmutableInstruction.of(item);
}
 
Example #20
Source File: DexlibAbstractInstruction.java    From JAADAS with GNU General Public License v3.0 4 votes vote down vote up
/**
 * @param instruction the underlying dexlib instruction
 * @param codeAddress the bytecode address of this instruction
 */
public DexlibAbstractInstruction(Instruction instruction, int codeAddress) {
    this.instruction = instruction;
    this.codeAddress = codeAddress;
}
 
Example #21
Source File: DexWriter.java    From ZjDroid with Apache License 2.0 4 votes vote down vote up
private void writeDebugAndCodeItems(@Nonnull DexDataWriter offsetWriter,
                                    @Nonnull DeferredOutputStream temp) throws IOException {
    ByteArrayOutputStream ehBuf = new ByteArrayOutputStream();
    debugSectionOffset = offsetWriter.getPosition();
    DebugWriter<StringKey, TypeKey> debugWriter =
            new DebugWriter<StringKey, TypeKey>(stringSection, typeSection, offsetWriter);

    DexDataWriter codeWriter = new DexDataWriter(temp, 0);

    List<CodeItemOffset<MethodKey>> codeOffsets = Lists.newArrayList();

    for (ClassKey classKey: classSection.getSortedClasses()) {
        Collection<? extends MethodKey> directMethods = classSection.getSortedDirectMethods(classKey);
        Collection<? extends MethodKey> virtualMethods = classSection.getSortedVirtualMethods(classKey);

        Iterable<MethodKey> methods = Iterables.concat(directMethods, virtualMethods);

        for (MethodKey methodKey: methods) {
            List<? extends TryBlock<? extends ExceptionHandler>> tryBlocks =
                    classSection.getTryBlocks(methodKey);
            Iterable<? extends Instruction> instructions = classSection.getInstructions(methodKey);
            Iterable<? extends DebugItem> debugItems = classSection.getDebugItems(methodKey);

            if (instructions != null && stringSection.hasJumboIndexes()) {
                boolean needsFix = false;
                for (Instruction instruction: instructions) {
                    if (instruction.getOpcode() == Opcode.CONST_STRING) {
                        if (stringSection.getItemIndex(
                                (StringRef)((ReferenceInstruction)instruction).getReference()) >= 65536) {
                            needsFix = true;
                            break;
                        }
                    }
                }

                if (needsFix) {
                    MutableMethodImplementation mutableMethodImplementation =
                            classSection.makeMutableMethodImplementation(methodKey);
                    fixInstructions(mutableMethodImplementation);

                    instructions = mutableMethodImplementation.getInstructions();
                    tryBlocks = mutableMethodImplementation.getTryBlocks();
                    debugItems = mutableMethodImplementation.getDebugItems();
                }
            }

            int debugItemOffset = writeDebugItem(offsetWriter, debugWriter,
                    classSection.getParameterNames(methodKey), debugItems);
            int codeItemOffset = writeCodeItem(codeWriter, ehBuf, methodKey, tryBlocks, instructions, debugItemOffset);

            if (codeItemOffset != -1) {
                codeOffsets.add(new CodeItemOffset<MethodKey>(methodKey, codeItemOffset));
            }
        }
    }

    offsetWriter.align();
    codeSectionOffset = offsetWriter.getPosition();

    codeWriter.close();
    temp.writeTo(offsetWriter);
    temp.close();

    for (CodeItemOffset<MethodKey> codeOffset: codeOffsets) {
        classSection.setCodeItemOffset(codeOffset.method, codeSectionOffset + codeOffset.codeOffset);
    }
}
 
Example #22
Source File: DexMethod.java    From apkfile with Apache License 2.0 4 votes vote down vote up
private void analyze(@Nonnull DexBackedMethodImplementation implementation) {
    debugItemCount = Utils.makeCollection(implementation.getDebugItems()).size();
    registerCount = implementation.getRegisterCount();
    tryCatchCount = implementation.getTryBlocks().size();

    for (Instruction instruction : implementation.getInstructions()) {
        instructionCount++;
        Opcode op = instruction.getOpcode();
        opCounts.adjustOrPutValue(op.apiToValueMap.get(DexFile.TARGET_API), 1, 1);

        if (instruction instanceof ReferenceInstruction) {
            ReferenceInstruction refInstr = (ReferenceInstruction) instruction;
            if (op.referenceType == ReferenceType.METHOD || op.referenceType == ReferenceType.FIELD) {
                boolean isApiPackage = false;
                for (String apiPackage : API_PACKAGES) {
                    String refStr = ReferenceUtil.getReferenceString(refInstr.getReference());
                    if (refStr.startsWith(apiPackage)) {
                        isApiPackage = true;
                        break;
                    }
                }
                if (!isApiPackage) {
                    continue;
                }
            }

            switch (op.referenceType) {
                case ReferenceType.METHOD:
                    MethodReference methodRef = (MethodReference) refInstr.getReference();
                    if (shortMethodSignatures) {
                        ShortMethodReference shortMethodRef = new ShortMethodReference(methodRef);
                        frameworkApiCounts.adjustOrPutValue(shortMethodRef, 1, 1);
                    } else {
                        frameworkApiCounts.adjustOrPutValue(methodRef, 1, 1);
                    }
                    break;
                case ReferenceType.FIELD:
                    FieldReference fieldRef = (FieldReference) refInstr.getReference();
                    frameworkFieldReferenceCounts.adjustOrPutValue(fieldRef, 1, 1);
                    break;
                case ReferenceType.STRING:
                    StringReference stringRef = (StringReference) refInstr.getReference();
                    stringReferenceCounts.adjustOrPutValue(stringRef, 1, 1);
                    break;
            }
        }
    }

    analyzeEntropy();
}
 
Example #23
Source File: ClassPool.java    From ZjDroid with Apache License 2.0 4 votes vote down vote up
private void internCode(@Nonnull Method method) {
    // this also handles parameter names, which aren't directly tied to the MethodImplementation, even though the debug items are
    boolean hasInstruction = false;

    MethodImplementation methodImpl = method.getImplementation();
    if (methodImpl != null) {
        for (Instruction instruction: methodImpl.getInstructions()) {
            hasInstruction = true;
            if (instruction instanceof ReferenceInstruction) {
                Reference reference = ((ReferenceInstruction)instruction).getReference();
                switch (instruction.getOpcode().referenceType) {
                    case ReferenceType.STRING:
                        stringPool.intern((StringReference)reference);
                        break;
                    case ReferenceType.TYPE:
                        typePool.intern((TypeReference)reference);
                        break;
                    case ReferenceType.FIELD:
                        fieldPool.intern((FieldReference) reference);
                        break;
                    case ReferenceType.METHOD:
                        methodPool.intern((MethodReference)reference);
                        break;
                    default:
                        throw new ExceptionWithContext("Unrecognized reference type: %d",
                                instruction.getOpcode().referenceType);
                }
            }
        }

        List<? extends TryBlock> tryBlocks = methodImpl.getTryBlocks();
        if (!hasInstruction && tryBlocks.size() > 0) {
            throw new ExceptionWithContext("Method %s has no instructions, but has try blocks.",
                    ReferenceUtil.getMethodDescriptor(method));
        }

        for (TryBlock<? extends ExceptionHandler> tryBlock: methodImpl.getTryBlocks()) {
            for (ExceptionHandler handler: tryBlock.getExceptionHandlers()) {
                typePool.internNullable(handler.getExceptionType());
            }
        }
    }
}
 
Example #24
Source File: MethodLocation.java    From ZjDroid with Apache License 2.0 4 votes vote down vote up
@Nullable
public Instruction getInstruction() {
    return instruction;
}
 
Example #25
Source File: PackedSwitchInstruction.java    From JAADAS with GNU General Public License v3.0 4 votes vote down vote up
public PackedSwitchInstruction (Instruction instruction, int codeAdress) {
    super(instruction, codeAdress);
}
 
Example #26
Source File: ExecuteInlineInstruction.java    From JAADAS with GNU General Public License v3.0 4 votes vote down vote up
public ExecuteInlineInstruction(Instruction instruction, int codeAddress) {
	super(instruction, codeAddress);
}
 
Example #27
Source File: MoveInstruction.java    From JAADAS with GNU General Public License v3.0 4 votes vote down vote up
public MoveInstruction (Instruction instruction, int codeAdress) {
    super(instruction, codeAdress);
}
 
Example #28
Source File: ImmutableInstruction.java    From ZjDroid with Apache License 2.0 4 votes vote down vote up
@Nonnull
public static ImmutableInstruction of(Instruction instruction) {
    if (instruction instanceof ImmutableInstruction) {
        return (ImmutableInstruction)instruction;
    }

    switch (instruction.getOpcode().format) {
        case Format10t:
            return ImmutableInstruction10t.of((Instruction10t)instruction);
        case Format10x:
            if (instruction instanceof UnknownInstruction) {
                return ImmutableUnknownInstruction.of((UnknownInstruction)instruction);
            }
            return ImmutableInstruction10x.of((Instruction10x)instruction);
        case Format11n:
            return ImmutableInstruction11n.of((Instruction11n)instruction);
        case Format11x:
            return ImmutableInstruction11x.of((Instruction11x)instruction);
        case Format12x:
            return ImmutableInstruction12x.of((Instruction12x)instruction);
        case Format20bc:
            return ImmutableInstruction20bc.of((Instruction20bc)instruction);
        case Format20t:
            return ImmutableInstruction20t.of((Instruction20t)instruction);
        case Format21c:
            return ImmutableInstruction21c.of((Instruction21c)instruction);
        case Format21ih:
            return ImmutableInstruction21ih.of((Instruction21ih)instruction);
        case Format21lh:
            return ImmutableInstruction21lh.of((Instruction21lh)instruction);
        case Format21s:
            return ImmutableInstruction21s.of((Instruction21s)instruction);
        case Format21t:
            return ImmutableInstruction21t.of((Instruction21t)instruction);
        case Format22b:
            return ImmutableInstruction22b.of((Instruction22b)instruction);
        case Format22c:
            return ImmutableInstruction22c.of((Instruction22c)instruction);
        case Format22cs:
            return ImmutableInstruction22cs.of((Instruction22cs)instruction);
        case Format22s:
            return ImmutableInstruction22s.of((Instruction22s)instruction);
        case Format22t:
            return ImmutableInstruction22t.of((Instruction22t)instruction);
        case Format22x:
            return ImmutableInstruction22x.of((Instruction22x)instruction);
        case Format23x:
            return ImmutableInstruction23x.of((Instruction23x)instruction);
        case Format30t:
            return ImmutableInstruction30t.of((Instruction30t)instruction);
        case Format31c:
            return ImmutableInstruction31c.of((Instruction31c)instruction);
        case Format31i:
            return ImmutableInstruction31i.of((Instruction31i)instruction);
        case Format31t:
            return ImmutableInstruction31t.of((Instruction31t)instruction);
        case Format32x:
            return ImmutableInstruction32x.of((Instruction32x)instruction);
        case Format35c:
            return ImmutableInstruction35c.of((Instruction35c)instruction);
        case Format35mi:
            return ImmutableInstruction35mi.of((Instruction35mi)instruction);
        case Format35ms:
            return ImmutableInstruction35ms.of((Instruction35ms)instruction);
        case Format3rc:
            return ImmutableInstruction3rc.of((Instruction3rc)instruction);
        case Format3rmi:
            return ImmutableInstruction3rmi.of((Instruction3rmi)instruction);
        case Format3rms:
            return ImmutableInstruction3rms.of((Instruction3rms)instruction);
        case Format51l:
            return ImmutableInstruction51l.of((Instruction51l)instruction);
        case PackedSwitchPayload:
            return ImmutablePackedSwitchPayload.of((PackedSwitchPayload) instruction);
        case SparseSwitchPayload:
            return ImmutableSparseSwitchPayload.of((SparseSwitchPayload) instruction);
        case ArrayPayload:
            return ImmutableArrayPayload.of((ArrayPayload) instruction);
        default:
            throw new RuntimeException("Unexpected instruction type");
    }
}
 
Example #29
Source File: MethodImplementationRewriter.java    From ZjDroid with Apache License 2.0 4 votes vote down vote up
@Override @Nonnull public Iterable<? extends Instruction> getInstructions() {
    return RewriterUtils.rewriteIterable(rewriters.getInstructionRewriter(),
            methodImplementation.getInstructions());
}
 
Example #30
Source File: DexWriter.java    From ZjDroid with Apache License 2.0 4 votes vote down vote up
private void writeDebugAndCodeItems(@Nonnull DexDataWriter offsetWriter,
                                    @Nonnull DeferredOutputStream temp) throws IOException {
    ByteArrayOutputStream ehBuf = new ByteArrayOutputStream();
    debugSectionOffset = offsetWriter.getPosition();
    DebugWriter<StringKey, TypeKey> debugWriter =
            new DebugWriter<StringKey, TypeKey>(stringSection, typeSection, offsetWriter);

    DexDataWriter codeWriter = new DexDataWriter(temp, 0);

    List<CodeItemOffset<MethodKey>> codeOffsets = Lists.newArrayList();

    for (ClassKey classKey: classSection.getSortedClasses()) {
        Collection<? extends MethodKey> directMethods = classSection.getSortedDirectMethods(classKey);
        Collection<? extends MethodKey> virtualMethods = classSection.getSortedVirtualMethods(classKey);

        Iterable<MethodKey> methods = Iterables.concat(directMethods, virtualMethods);

        for (MethodKey methodKey: methods) {
            List<? extends TryBlock<? extends ExceptionHandler>> tryBlocks =
                    classSection.getTryBlocks(methodKey);
            Iterable<? extends Instruction> instructions = classSection.getInstructions(methodKey);
            Iterable<? extends DebugItem> debugItems = classSection.getDebugItems(methodKey);

            if (instructions != null && stringSection.hasJumboIndexes()) {
                boolean needsFix = false;
                for (Instruction instruction: instructions) {
                    if (instruction.getOpcode() == Opcode.CONST_STRING) {
                        if (stringSection.getItemIndex(
                                (StringRef)((ReferenceInstruction)instruction).getReference()) >= 65536) {
                            needsFix = true;
                            break;
                        }
                    }
                }

                if (needsFix) {
                    MutableMethodImplementation mutableMethodImplementation =
                            classSection.makeMutableMethodImplementation(methodKey);
                    fixInstructions(mutableMethodImplementation);

                    instructions = mutableMethodImplementation.getInstructions();
                    tryBlocks = mutableMethodImplementation.getTryBlocks();
                    debugItems = mutableMethodImplementation.getDebugItems();
                }
            }

            int debugItemOffset = writeDebugItem(offsetWriter, debugWriter,
                    classSection.getParameterNames(methodKey), debugItems);
            int codeItemOffset = writeCodeItem(codeWriter, ehBuf, methodKey, tryBlocks, instructions, debugItemOffset);

            if (codeItemOffset != -1) {
                codeOffsets.add(new CodeItemOffset<MethodKey>(methodKey, codeItemOffset));
            }
        }
    }

    offsetWriter.align();
    codeSectionOffset = offsetWriter.getPosition();

    codeWriter.close();
    temp.writeTo(offsetWriter);
    temp.close();

    for (CodeItemOffset<MethodKey> codeOffset: codeOffsets) {
        classSection.setCodeItemOffset(codeOffset.method, codeSectionOffset + codeOffset.codeOffset);
    }
}