static SGetOp create(Instruction instruction, int address, VirtualMachine vm) { String opName = instruction.getOpcode().name; int childAddress = address + instruction.getCodeUnits(); Instruction21c instr = (Instruction21c) instruction; int destRegister = instr.getRegisterA(); FieldReference reference = (FieldReference) instr.getReference(); String fieldDescriptor = ReferenceUtil.getFieldDescriptor(reference); return new SGetOp(address, opName, childAddress, destRegister, fieldDescriptor, vm); }
@Override public void computeDataOffsets(DexBody body) { Debug.printDbg("compute data offset"); if (!(instruction instanceof Instruction31t)) throw new IllegalArgumentException( "Expected Instruction31t but got: " + instruction.getClass()); Instruction31t fillArrayInstr = (Instruction31t) instruction; int offset = fillArrayInstr.getCodeOffset(); int targetAddress = codeAddress + offset; Instruction referenceTable = body.instructionAtAddress(targetAddress).instruction; if (!(referenceTable instanceof ArrayPayload)) { throw new RuntimeException( "Address 0x" + Integer.toHexString(targetAddress) + " refers to an invalid PseudoInstruction (" + referenceTable.getClass() + ")."); } ArrayPayload arrayTable = (ArrayPayload) referenceTable; int numElements = arrayTable.getArrayElements().size(); int widthElement = arrayTable.getElementWidth(); int size = (widthElement * numElements) / 2; // addresses are on 16bits // From org.jf.dexlib.Code.Format.ArrayDataPseudoInstruction we learn // that there are 6 bytes after the magic number that we have to jump. // 6 bytes to jump = address + 3 // // out.writeByte(0x00); // magic // out.writeByte(0x03); // number // out.writeShort(elementWidth); // 2 bytes // out.writeInt(elementCount); // 4 bytes // out.write(encodedValues); // setDataFirstByte(targetAddress + 3); // address for 16 bits elements not 8 bits setDataLastByte(targetAddress + 3 + size); // - 1); setDataSize(size); // TODO: how to handle this with dexlib2 ? // ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput(); // arrayTable.write(out, targetAddress); // // byte[] outa = out.getArray(); // byte[] data = new byte[outa.length-6]; // for (int i=6; i<outa.length; i++) { // data[i-6] = outa[i]; // } // setData (data); }
protected boolean isInvokeInit() { if (instruction == null || !instruction.getOpcode().canInitializeReference()) { return false; } ReferenceInstruction instruction = (ReferenceInstruction) this.instruction; Reference reference = instruction.getReference(); if (reference instanceof MethodReference) { return ((MethodReference) reference).getName().equals("<init>"); } return false; }
public boolean setsWideRegister() { return instruction.getOpcode().setsWideRegister(); }
protected void restoreOdexedInstruction() { assert originalInstruction.getOpcode().odexOnly(); instruction = originalInstruction; }
protected void setDeodexedInstruction(Instruction instruction) { assert originalInstruction.getOpcode().odexOnly(); this.instruction = instruction; }