public void removeInstruction(int index) { if (index >= instructionList.size() - 1) { throw new IndexOutOfBoundsException(); } MethodLocation toRemove = instructionList.get(index); toRemove.instruction = null; MethodLocation next = instructionList.get(index + 1); toRemove.mergeInto(next); instructionList.remove(index); int codeAddress = toRemove.codeAddress; for (int i = index; i < instructionList.size(); i++) { MethodLocation location = instructionList.get(i); location.index = i; location.codeAddress = codeAddress; Instruction instruction = location.getInstruction(); if (instruction != null) { codeAddress += instruction.getCodeUnits(); } else { assert i == instructionList.size() - 1; } } this.fixInstructions = true; }
public void replaceInstruction(int index, @Nonnull BuilderInstruction replacementInstruction) { if (index >= instructionList.size() - 1) { throw new IndexOutOfBoundsException(); } MethodLocation replaceLocation = instructionList.get(index); replacementInstruction.location = replaceLocation; BuilderInstruction old = replaceLocation.instruction; assert old != null; old.location = null; replaceLocation.instruction = replacementInstruction; // TODO: factor out index/address fix up loop int codeAddress = replaceLocation.codeAddress + replaceLocation.instruction.getCodeUnits(); for (int i = index + 1; i < instructionList.size(); i++) { MethodLocation location = instructionList.get(i); location.codeAddress = codeAddress; Instruction instruction = location.getInstruction(); if (instruction != null) { codeAddress += instruction.getCodeUnits(); } else { assert i == instructionList.size() - 1; } } this.fixInstructions = true; }
/** * Extracts the list of dalvik instructions from dexlib and converts them into our own instruction data model * * @param code * The dexlib method implementation */ protected void extractDexInstructions(MethodImplementation code) { int address = 0; for (Instruction instruction : code.getInstructions()) { DexlibAbstractInstruction dexInstruction = fromInstruction(instruction, address); instructions.add(dexInstruction); instructionAtAddress.put(address, dexInstruction); address += instruction.getCodeUnits(); } }
public static MethodLocation getNextLocation(MethodLocation location, TIntObjectMap<MethodLocation> addressToLocation) { int address = location.getCodeAddress(); int nextAddress = address + location.getInstruction().getCodeUnits(); return addressToLocation.get(nextAddress); }
int codeSize = lastInstructionAddress + instructions.get(instructions.size() - 1).getCodeUnits();
currentCodeAddress += instruction.getCodeUnits();
private boolean isDead(int address) { Op op = manipulator.getOp(address); log.debug("Dead test @{} for: {}", address, op); if (exceptionHandlingAddresses.contains(address)) { // If virtual execution was perfect, unvisited exception handling code could safely be removed provided // you also removed the try/catch but that level of accuracy is difficult. Instead, compromise by not // removing unvisited code, but try and remove for other reasons such as dead assignment. return false; } if (manipulator.wasAddressReached(address)) { return false; } if (op instanceof GotoOp) { // These are handled specifically by isUselessBranch return false; } if (op instanceof NopOp) { int nextAddress = address + op.getLocation().getInstruction().getCodeUnits(); Opcode nextOp = manipulator.getLocation(nextAddress).getInstruction().getOpcode(); if (nextOp == Opcode.ARRAY_PAYLOAD) { // Necessary nop padding return false; } } return true; }
codeAddress += instruction.getCodeUnits(); index++;
instructions.get(instructions.size()-1).getCodeUnits(); ((Instruction31t)instruction).getRegisterA(), targetOffset-codeOffset)); effectiveInstructions.add(payloadInstruction); endOffset += payloadInstruction.getCodeUnits(); ((Instruction31t)instruction).getRegisterA(), targetOffset-codeOffset)); effectiveInstructions.add(payloadInstruction); endOffset += payloadInstruction.getCodeUnits();
currentCodeAddress += instruction.getInstruction().getCodeUnits();
@Override protected Stmt switchStatement(DexBody body, Instruction targetData, Local key) { PackedSwitchPayload i = (PackedSwitchPayload) targetData; List<? extends SwitchElement> seList = i.getSwitchElements(); // the default target always follows the switch statement int defaultTargetAddress = codeAddress + instruction.getCodeUnits(); Unit defaultTarget = body.instructionAtAddress(defaultTargetAddress).getUnit(); List<IntConstant> lookupValues = new ArrayList<IntConstant>(); List<Unit> targets = new ArrayList<Unit>(); for (SwitchElement se : seList) { lookupValues.add(IntConstant.v(se.getKey())); int offset = se.getOffset(); targets.add(body.instructionAtAddress(codeAddress + offset).getUnit()); } LookupSwitchStmt switchStmt = Jimple.v().newLookupSwitchStmt(key, lookupValues, targets, defaultTarget); setUnit(switchStmt); if (IDalvikTyper.ENABLE_DVKTYPER) { DalvikTyper.v().setType(switchStmt.getKeyBox(), IntType.v(), true); } return switchStmt; }
@Override protected Stmt switchStatement(DexBody body, Instruction targetData, Local key) { SparseSwitchPayload i = (SparseSwitchPayload) targetData; List<? extends SwitchElement> seList = i.getSwitchElements(); // the default target always follows the switch statement int defaultTargetAddress = codeAddress + instruction.getCodeUnits(); Unit defaultTarget = body.instructionAtAddress(defaultTargetAddress).getUnit(); List<IntConstant> lookupValues = new ArrayList<IntConstant>(); List<Unit> targets = new ArrayList<Unit>(); for (SwitchElement se : seList) { lookupValues.add(IntConstant.v(se.getKey())); int offset = se.getOffset(); targets.add(body.instructionAtAddress(codeAddress + offset).getUnit()); } LookupSwitchStmt switchStmt = Jimple.v().newLookupSwitchStmt(key, lookupValues, targets, defaultTarget); setUnit(switchStmt); addTags(switchStmt); if (IDalvikTyper.ENABLE_DVKTYPER) { DalvikTyper.v().setType(switchStmt.getKeyBox(), IntType.v(), true); } return switchStmt; }
new AnalyzedInstruction(this, instruction, i, registerCount)); assert analyzedInstructions.indexOfKey(currentCodeAddress) == i; currentCodeAddress += instruction.getCodeUnits();
int codeUnitCount = 0; for (Instruction instruction: instructions) { codeUnitCount += instruction.getCodeUnits(); if (instruction.getOpcode().referenceType == ReferenceType.METHOD) { ReferenceInstruction refInsn = (ReferenceInstruction)instruction; throw new ExceptionWithContext(ex, "Error while writing instruction at code offset 0x%x", codeOffset); codeOffset += instruction.getCodeUnits();
@Override public int getCodeUnits() { return originalInstruction.getCodeUnits(); } }
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(); } }
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(); } }
@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; }
@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; }
@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; }