예제 #1
0
  @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);
  }
예제 #2
0
  public void jimplify(DexBody body) {
    if (!(instruction instanceof Instruction31t))
      throw new IllegalArgumentException(
          "Expected Instruction31t but got: " + instruction.getClass());

    Instruction31t fillArrayInstr = (Instruction31t) instruction;
    int destRegister = fillArrayInstr.getRegisterA();
    int offset = fillArrayInstr.getCodeOffset();
    int targetAddress = codeAddress + offset;

    Instruction referenceTable = body.instructionAtAddress(targetAddress).instruction;

    if (!(referenceTable instanceof ArrayPayload)) {
      throw new RuntimeException(
          "Address " + targetAddress + "refers to an invalid PseudoInstruction.");
    }

    ArrayPayload arrayTable = (ArrayPayload) referenceTable;

    //        NopStmt nopStmtBeginning = Jimple.v().newNopStmt();
    //        body.add(nopStmtBeginning);

    Local arrayReference = body.getRegisterLocal(destRegister);
    List<Number> elements = arrayTable.getArrayElements();
    int numElements = elements.size();

    Stmt firstAssign = null;
    for (int i = 0; i < numElements; i++) {
      ArrayRef arrayRef = Jimple.v().newArrayRef(arrayReference, IntConstant.v(i));
      NumericConstant element = getArrayElement(elements.get(i), body, destRegister);
      if (element
          == null) // array was not defined -> element type can not be found (obfuscated bytecode?)
      break;
      AssignStmt assign = Jimple.v().newAssignStmt(arrayRef, element);
      addTags(assign);
      body.add(assign);
      if (i == 0) {
        firstAssign = assign;
      }
    }
    if (firstAssign == null) { // if numElements == 0. Is it possible?
      firstAssign = Jimple.v().newNopStmt();
      body.add(firstAssign);
    }

    //        NopStmt nopStmtEnd = Jimple.v().newNopStmt();
    //        body.add(nopStmtEnd);

    //        defineBlock(nopStmtBeginning, nopStmtEnd);
    setUnit(firstAssign);
  }