Example #1
0
  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;
 }