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();
  }