Exemple #1
0
  /**
   * Inserts hooks into a single code item.
   *
   * @param hooks
   * @param classData
   * @param code
   */
  private void hookReferences(HookMap hooks, ClassDataItem classData, CodeItem code) {
    if (code == null) {
      return;
    }

    Instruction[] instructions = code.getInstructions();
    for (int index = 0; index < instructions.length; index++) {
      Instruction i = instructions[index];

      if (i instanceof InstructionWithReference) {
        InstructionWithReference inst = (InstructionWithReference) i;

        HookItem oldTarget = HookItem.getInstance(inst.getReferencedItem());

        if (!hooks.containsKey(oldTarget)) {
          continue;
        }

        Item newTarget = hooks.get(oldTarget);

        inst.referencedItem = newTarget;

        if (newTarget instanceof MethodIdItem) {
          // Need to update the invoke type if it changed
          updateInvokeType(inst, (MethodIdItem) newTarget);
        }
      }
    }
  }
Exemple #2
0
  public void hookSuperclass(HookMap hooks, ClassDefItem classDef) {
    HookItem oldTarget = HookItem.getInstance(classDef.getSuperclass());

    if (oldTarget == null) {
      return;
    }

    if (!hooks.containsKey(oldTarget)) {
      return;
    }

    TypeIdItem newTarget = (TypeIdItem) hooks.get(oldTarget);

    assert (newTarget != null);

    if (newTarget == classDef.getClassType()) {
      return;
    }

    classDef.setSuperclass(newTarget);

    HookClass classType = new HookClass(classDef.getClassType());

    if (hooks.mIgnoreMethods.contains(classType)) {
      return;
    }

    if (hooks.mDead.isEmpty()) {
      return;
    }

    // get rid of virtual methods so the hooked class method is called instead

    String className = newTarget.getTypeDescriptor();

    List<EncodedMethod> newDirects = new LinkedList<EncodedMethod>();
    List<EncodedMethod> newVirtuals = new LinkedList<EncodedMethod>();

    ClassDataItem classData = classDef.getClassData();

    for (EncodedMethod encodedMethod : classData.getDirectMethods()) {
      newDirects.add(encodedMethod);
    }

    for (EncodedMethod encodedMethod : classData.getVirtualMethods()) {
      HookMethod method = new HookMethod(encodedMethod.method);
      method.mClasspath = className;

      if (!hooks.mDead.contains(method)) {
        newVirtuals.add(encodedMethod);
      }
    }

    classData.update(newDirects, newVirtuals);
  }