Ejemplo n.º 1
0
  /** For instance invokes */
  public static ArrayList<SootMethod> resolveAppCall(Type tgtType, SootMethodRef methodRef) {
    final NumberedString mSubsignature = methodRef.getSubSignature();
    if (tgtType instanceof RefType) {
      // find first class upwards in hierarchy, starting from cls, that implements method (i.e.,
      // *concrete* method)
      SootClass cls = ((RefType) tgtType).getSootClass();
      while (!cls.declaresMethod(mSubsignature))
        cls =
            cls
                .getSuperclass(); // if method not in this class, it HAS to be in a superclass, so a
                                  // superclass must exist

      if (!cls.hasTag(ClassTag.TAG_NAME)) return null; // not an app method

      // finally, store resolved app method
      SootMethod m = cls.getMethod(mSubsignature);
      assert m.hasTag(MethodTag.TAG_NAME);

      ArrayList<SootMethod> methods = new ArrayList<SootMethod>();
      methods.add(m); // just one element, directly resolved
      return methods;
    }

    if (tgtType instanceof AnySubType) {
      // return set of all app subtypes that implement referenced method
      SootClass baseCls = ((AnySubType) tgtType).getBase().getSootClass();
      List subClasses =
          baseCls.isInterface()
              ? Scene.v().getActiveHierarchy().getImplementersOf(baseCls)
              : Scene.v().getActiveHierarchy().getSubclassesOf(baseCls);
      ArrayList<SootMethod> methods = new ArrayList<SootMethod>();
      for (Object oSubCls : subClasses) {
        SootClass subCls = (SootClass) oSubCls;
        if (subCls.hasTag(ClassTag.TAG_NAME)) {
          try {
            SootMethod m = subCls.getMethod(mSubsignature);
            assert m.hasTag(MethodTag.TAG_NAME);
            if (!m.isAbstract()) methods.add(m);
          } catch (RuntimeException e) {
          }
        }
      }

      return methods;
    }

    assert tgtType instanceof ArrayType; // only other case observed so far
    return new ArrayList(); // no array class/method is in app
  }
Ejemplo n.º 2
0
  /**
   * Finds in class hierarchy and returns all app and lib concrete methods possibly referenced by
   * method ref. Method is assumed to be virtual (not special or static). Returns true if there are
   * library methods among targets found.
   */
  public static boolean getConcreteCallTargets(
      InvokeExpr instInvExpr, /*OUT*/
      Set<SootMethod> appTargets, /*OUT*/
      Set<SootMethod> libTargets) {
    // get class of method ref; we start searching from this class
    SootMethodRef mref = instInvExpr.getMethodRef();
    SootClass cls = mref.declaringClass(); // starting class
    final NumberedString subsignature = mref.getSubSignature(); // signature to search for

    // CASE 1: object is of declared class type or inherited from some superclass
    //         find first superclass, starting from current cls, that declares method; there HAS to
    // be such a class
    // note that if cls is interface, superclass if java.lang.Object
    // note that we don't check if there is indeed an interface declaring the method; we assume this
    // is the case if no superclass declares it
    while (!cls.declaresMethod(subsignature) && cls.hasSuperclass())
      cls = cls.getSuperclass(); // never an interface
    // now, method might not be in superclass, or might be abstract; in that case, it's not a target
    SootMethod m;
    if (cls.declaresMethod(subsignature)) {
      m = cls.getMethod(subsignature);
      if (!m.isAbstract()) {
        if (cls.hasTag(ClassTag.TAG_NAME)) appTargets.add(m); // add app method
        else libTargets.add(m); // add lib method
      }
    }

    // (only for virtual/interface calls)
    // CASE 2: object's actual type is a subclass; any subclass declaring the method is a possible
    // target
    //         we have to check all superclasses of implementers, because starting cls might be
    // interface
    if (instInvExpr instanceof VirtualInvokeExpr || instInvExpr instanceof InterfaceInvokeExpr) {
      cls = mref.declaringClass(); // start again from declaring class
      List<SootClass> allSubclasses = getAllSubtypes(cls);
      for (SootClass subCls : allSubclasses) {
        m = getMethodInClassOrSuperclass(subCls, subsignature);
        if (m != null && !m.isAbstract()) {
          if (m.getDeclaringClass().hasTag(ClassTag.TAG_NAME)) appTargets.add(m); // add app method
          else libTargets.add(m); // add lib method
        }
      }
    }

    return !libTargets.isEmpty();
  }
 private Value mutate(Value value) {
   if (value instanceof FieldRef) {
     FieldRef ref = (FieldRef) value;
     SootField field = ref.getField();
     Type type = field.getType();
     if (type instanceof RefType) {
       RefType ref_type = (RefType) type;
       SootClass soot_class = ref_type.getSootClass();
       if (shouldMap(soot_class)) {
         addField(field, ref);
       }
     } else if (type instanceof ArrayType) {
       ArrayType array_type = (ArrayType) type;
       Type base_type = array_type.baseType;
       if (base_type instanceof RefType) {
         RefType ref_type = (RefType) base_type;
         SootClass soot_class = ref_type.getSootClass();
         if (shouldMap(soot_class)) {
           addField(field, ref);
         }
       }
     }
     SootClass soot_class = field.getDeclaringClass();
     if (shouldMap(soot_class)) {
       addField(field, ref);
     }
     return value;
   } else if (value instanceof InvokeExpr) {
     InvokeExpr expr = (InvokeExpr) value;
     SootMethodRef ref = expr.getMethodRef();
     SootClass soot_class = ref.declaringClass();
     final NumberedString subSignature = ref.getSubSignature();
     if (shouldMap(soot_class)) {
       SootClass new_class = getMapping(soot_class);
       if (new_class.declaresMethod(subSignature)) {
         SootMethod new_method = RootbeerScene.v().getMethod(new_class, subSignature.getString());
         addAddedMethod(new_method);
         fixArguments(new_method);
         RootbeerScene.v().getDfsInfo().addReachableMethodSig(new_method.getSignature());
         expr.setMethodRef(new_method.makeRef());
       }
     } else {
       if (soot_class.declaresMethod(ref.getSubSignature())) {
         SootMethod method = soot_class.getMethod(ref.getSubSignature());
         fixArguments(method);
       }
     }
     ref = remapRef(ref);
     try {
       if (shouldMap(soot_class)) {
         soot_class = getMapping(soot_class);
       }
       SootMethod method = soot_class.getMethod(ref.getSubSignature());
       RootbeerScene.v().getDfsInfo().addReachableMethodSig(method.getSignature());
       expr.setMethodRef(method.makeRef());
     } catch (Exception ex) {
       // ex.printStackTrace();
     }
     return value;
   } else if (value instanceof NewExpr) {
     NewExpr expr = (NewExpr) value;
     RefType base_type = expr.getBaseType();
     SootClass soot_class = base_type.getSootClass();
     if (shouldMap(soot_class)) {
       SootClass new_class = getMapping(soot_class);
       expr.setBaseType(new_class.getType());
     }
     return value;
   } else if (value instanceof NewArrayExpr) {
     NewArrayExpr expr = (NewArrayExpr) value;
     Type base_type = expr.getBaseType();
     base_type = fixType(base_type);
     expr.setBaseType(base_type);
     return value;
   } else if (value instanceof NewMultiArrayExpr) {
     NewMultiArrayExpr expr = (NewMultiArrayExpr) value;
     ArrayType array_type = expr.getBaseType();
     Type base_type = array_type.baseType;
     if (base_type instanceof RefType) {
       RefType ref_type = (RefType) base_type;
       SootClass soot_class = ref_type.getSootClass();
       if (shouldMap(soot_class)) {
         SootClass new_class = getMapping(soot_class);
         ArrayType new_type = ArrayType.v(new_class.getType(), array_type.numDimensions);
         expr.setBaseType(new_type);
       }
     }
     return value;
   } else if (value instanceof CastExpr) {
     CastExpr expr = (CastExpr) value;
     Type cast_type = expr.getCastType();
     cast_type = fixType(cast_type);
     expr.setCastType(cast_type);
     return value;
   } else if (value instanceof ParameterRef) {
     ParameterRef ref = (ParameterRef) value;
     Type new_type = fixType(ref.getType());
     return new ParameterRef(new_type, ref.getIndex());
   } else if (value instanceof ThisRef) {
     ThisRef ref = (ThisRef) value;
     Type new_type = fixType(ref.getType());
     return new ThisRef((RefType) new_type);
   } else if (value instanceof Local) {
     Local local = (Local) value;
     Type type = local.getType();
     local.setType(fixType(type));
     return value;
   } else {
     return value;
   }
 }