public void addInstruction(MethodLocation location, BuilderInstruction instruction) { int index = location.getIndex(); implementation.addInstruction(index, instruction); MethodLocation newLocation = instruction.getLocation(); MethodLocation oldLocation = implementation.getInstructions().get(index + 1).getLocation(); try { java.lang.reflect.Method m = MethodLocation.class.getDeclaredMethod("mergeInto", MethodLocation.class); m.setAccessible(true); m.invoke(oldLocation, newLocation); } catch (Exception e) { log.error("Error invoking MethodLocation.mergeInto(). Wrong dexlib version?", e); } rebuildGraph(); }
public void addInstruction(@Nullable BuilderInstruction instruction) { impl.addInstruction(instruction); currentLocation = impl.instructionList.get(impl.instructionList.size()-1); } }
public void addInstruction(@Nullable BuilderInstruction instruction) { impl.addInstruction(instruction); currentLocation = impl.instructionList.get(impl.instructionList.size()-1); } }
public void addInstruction(@Nullable BuilderInstruction instruction) { impl.addInstruction(instruction); currentLocation = impl.instructionList.get(impl.instructionList.size()-1); } }
public void addInstruction(int index, BuilderInstruction instruction) { // the end check here is intentially >= rather than >, because the list always includes an "empty" // (null instruction) MethodLocation at the end. To add an instruction to the end of the list, the user would // provide the index of this empty item, which would be size() - 1. if (index >= instructionList.size()) { throw new IndexOutOfBoundsException(); } if (index == instructionList.size() - 1) { addInstruction(instruction); return; } int codeAddress = instructionList.get(index).getCodeAddress(); MethodLocation newLoc = new MethodLocation(instruction, codeAddress, index); instructionList.add(index, newLoc); instruction.location = newLoc; codeAddress += instruction.getCodeUnits(); for (int i=index+1; i<instructionList.size(); i++) { MethodLocation location = instructionList.get(i); location.index++; location.codeAddress = codeAddress; if (location.instruction != null) { codeAddress += location.instruction.getCodeUnits(); } else { // only the last MethodLocation should have a null instruction assert i == instructionList.size()-1; } } this.fixInstructions = true; }
public void addInstruction(int index, BuilderInstruction instruction) { // the end check here is intentially >= rather than >, because the list always includes an "empty" // (null instruction) MethodLocation at the end. To add an instruction to the end of the list, the user would // provide the index of this empty item, which would be size() - 1. if (index >= instructionList.size()) { throw new IndexOutOfBoundsException(); } if (index == instructionList.size() - 1) { addInstruction(instruction); return; } int codeAddress = instructionList.get(index).getCodeAddress(); MethodLocation newLoc = new MethodLocation(instruction, codeAddress, index); instructionList.add(index, newLoc); instruction.location = newLoc; codeAddress += instruction.getCodeUnits(); for (int i=index+1; i<instructionList.size(); i++) { MethodLocation location = instructionList.get(i); location.index++; location.codeAddress = codeAddress; if (location.instruction != null) { codeAddress += location.instruction.getCodeUnits(); } else { // only the last MethodLocation should have a null instruction assert i == instructionList.size()-1; } } this.fixInstructions = true; }
public void addInstruction(int index, BuilderInstruction instruction) { // the end check here is intentially >= rather than >, because the list always includes an "empty" // (null instruction) MethodLocation at the end. To add an instruction to the end of the list, the user would // provide the index of this empty item, which would be size() - 1. if (index >= instructionList.size()) { throw new IndexOutOfBoundsException(); } if (index == instructionList.size() - 1) { addInstruction(instruction); return; } int codeAddress = instructionList.get(index).getCodeAddress(); instructionList.add(index, new MethodLocation(instruction, codeAddress, index)); codeAddress += instruction.getCodeUnits(); for (int i=index+1; i<instructionList.size(); i++) { MethodLocation location = instructionList.get(i); location.index++; location.codeAddress = codeAddress; if (location.instruction != null) { codeAddress += location.instruction.getCodeUnits(); } else { // only the last MethodLocation should have a null instruction assert i == instructionList.size()-1; } } this.fixInstructions = true; }
private static MethodImplementation modifyMethodAndFix(@Nonnull MethodImplementation implementation, Method method) { MutableMethodImplementation mutableImplementation = new MutableMethodImplementation(implementation); System.out.println(mutableImplementation.getRegisterCount()); List<BuilderInstruction> instructions = mutableImplementation.getInstructions(); mutableImplementation.addInstruction(0, new BuilderInstruction21c(Opcode.CONST_STRING, 0, new ImmutableStringReference("AndFix:" + method.getDefiningClass().replace("/", ".")))); mutableImplementation.addInstruction(1, new BuilderInstruction35c(Opcode.INVOKE_STATIC, 1, 0, 0, 0, 0, 0, new ImmutableMethodReference("Landroid/util/Log;", "e", Lists.newArrayList("Ljava/lang/String;", "Ljava/lang/String;"), "I"))); return mutableImplementation; }
private static MethodImplementation modifyMethodTpatch(@Nonnull MethodImplementation implementation, Method method) { MutableMethodImplementation mutableImplementation = new MutableMethodImplementation(implementation); System.out.println(mutableImplementation.getRegisterCount()); List<BuilderInstruction> instructions = mutableImplementation.getInstructions(); boolean isModified = false; for (int i = 0; i < instructions.size(); i++) { isModified = false; if (instructions.get(i).getOpcode() == Opcode.INVOKE_DIRECT) { if (!isModified) { mutableImplementation.addInstruction(i++, new BuilderInstruction21c(Opcode.CONST_STRING, 0, new ImmutableStringReference("tpatch:" + method.getDefiningClass().replace("/", ".")))); mutableImplementation.addInstruction(i++, new BuilderInstruction35c(Opcode.INVOKE_STATIC, 1, 0, 0, 0, 0, 0, new ImmutableMethodReference("Landroid/util/Log;", "e", Lists.newArrayList("Ljava/lang/String;", "Ljava/lang/String;"), "I"))); isModified = true; break; } } // mutableImplementation.addInstruction(instructions.get(i)); } return mutableImplementation; }
index--; } else { addInstruction(location.index, new BuilderInstruction10x(Opcode.NOP)); index++;
index--; } else { addInstruction(location.index, new BuilderInstruction10x(Opcode.NOP)); index++;
index--; } else { addInstruction(location.index, new BuilderInstruction10x(Opcode.NOP)); index++;