public void transform() {
    if (clazz.isPhantom()) return;

    // build ancestor
    // List<SootClass> ancestors = Scene.v().getActiveHierarchy().getSuperclassesOf(clazz);
    List<SootClass> ancestors = new LinkedList<SootClass>();

    // fill in ancestor list without using Soot.Hierarchy
    SootClass curAncestor = clazz;
    while (curAncestor.hasSuperclass()) {
      ancestors.add(curAncestor.getSuperclass());
      curAncestor = curAncestor.getSuperclass();
    }

    for (SootClass ancestor : ancestors) {
      if (ancestor.isPhantom()) continue;

      cloneReachableNonHiddenAncestorMethods(ancestor);
    }

    // modify ancestors fields
    for (SootClass ancestor : ancestors) {
      if (ancestor.isPhantom()) continue;

      SootUtils.makeFieldsVisible(ancestor);
    }

    cloneHiddenAncestorMethodsAndFixInvokeSpecial();
  }
Exemple #2
0
  public static HashSet<SootMethod> getAllImplementations(SootMethod method) {
    Chain appClasses = Scene.v().getApplicationClasses();
    HashSet<SootClass> implementingClasses = new HashSet<SootClass>(1);
    HashSet<SootMethod> overridingMethods = new HashSet<SootMethod>(1);

    SootClass t = method.getDeclaringClass();
    if (
    /*t.isAbstract() || */ t.isPhantom() || t.isPhantomClass()) {
      boolean b1 = t.isAbstract();
      boolean be = t.isPhantom();
      boolean b3 = t.isPhantomClass();

      try {
        throw new Exception("Need to implement for Plantom Classes");
      } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
    if (t.isAbstract()) {
      for (Object object : appClasses) {
        SootClass clazz = (SootClass) object;
        SootClass superClass = clazz.getSuperclass();
        {
          if (superClass.getName().equals(t.toString())) {
            implementingClasses.add(clazz);
            SootMethod m2 =
                clazz.getMethod(
                    method.getName(), method.getParameterTypes(), method.getReturnType());
            overridingMethods.add(m2);
          }
        }
      }
    }
    if (t.isInterface()) {
      for (Object object : appClasses) {
        SootClass clazz = (SootClass) object;
        Chain<SootClass> interfaces = clazz.getInterfaces();
        for (SootClass sootClass : interfaces) {
          if (sootClass.getName().equals(t.toString())) {
            implementingClasses.add(clazz);
            SootMethod m2 =
                clazz.getMethod(
                    method.getName(), method.getParameterTypes(), method.getReturnType());
            overridingMethods.add(m2);
          }
        }
      }
    }
    return overridingMethods;
  }
  public static SootClass mockSootClass(String clsName) {
    SootClass sc = null;

    if (Scene.v().containsClass(clsName)) {
      sc = Scene.v().getSootClass(clsName);

      if (sc.isPhantom()) {
        // sc.setPhantom(false);
        sc.setApplicationClass();
        sc.setInScene(true);

        try {
          for (Field field : sc.getClass().getFields()) {
            if (field.getName().equals("isPhantom")) {
              field.setAccessible(true);
              field.setBoolean(sc, false);
            }
          }
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    } else {
      sc = new SootClass(clsName);
      sc.setSuperclass(Scene.v().getSootClass("java.lang.Object"));

      sc.setPhantom(false);
      sc.setApplicationClass();
      sc.setInScene(true);
    }

    mockConstructor(sc);

    return sc;
  }
  protected void internalTransform(String phaseName, Map options) {
    if (Options.v().verbose())
      G.v().out.println("Transforming all classes in the Scene to Shimple...");

    // *** FIXME: Add debug output to indicate which class/method is being shimplified.
    // *** FIXME: Is ShimpleTransformer the right solution?  The call graph may deem
    //            some classes unreachable.

    Iterator classesIt = Scene.v().getClasses().iterator();
    while (classesIt.hasNext()) {
      SootClass sClass = (SootClass) classesIt.next();
      if (sClass.isPhantom()) continue;

      Iterator methodsIt = sClass.getMethods().iterator();
      while (methodsIt.hasNext()) {
        SootMethod method = (SootMethod) methodsIt.next();
        if (!method.isConcrete()) continue;

        if (method.hasActiveBody()) {
          Body body = method.getActiveBody();
          ShimpleBody sBody = null;

          if (body instanceof ShimpleBody) {
            sBody = (ShimpleBody) body;
            if (!sBody.isSSA()) sBody.rebuild();
          } else {
            sBody = Shimple.v().newBody(body);
          }

          method.setActiveBody(sBody);
        } else {
          MethodSource ms = new ShimpleMethodSource(method.getSource());
          method.setSource(ms);
        }
      }
    }
  }
  private StructureConstant createClassInfoErrorStruct() {
    /*
     * Check that clazz can be loaded, i.e. that the superclass
     * and interfaces of the class exist and are accessible to the
     * class. Also check that any exception the class uses in catch
     * clauses exist and is accessible to the class. If the class
     * cannot be loaded we override the ClassInfoHeader struct
     * produced by the ClassCompiler for the class with one which
     * tells the code in bc.c to throw an appropriate exception
     * whenever clazz is accessed.
     */

    int errorType = ClassCompiler.CI_ERROR_TYPE_NONE;
    String errorMessage = null;
    if (!sootClass.isInterface() && sootClass.hasSuperclass()) {
      // Check superclass
      SootClass superclazz = sootClass.getSuperclass();
      if (superclazz.isPhantom()) {
        errorType = ClassCompiler.CI_ERROR_TYPE_NO_CLASS_DEF_FOUND;
        errorMessage = superclazz.getName();
      } else if (!checkClassAccessible(superclazz, sootClass)) {
        errorType = ClassCompiler.CI_ERROR_TYPE_ILLEGAL_ACCESS;
        errorMessage = String.format(ILLEGAL_ACCESS_ERROR_CLASS, superclazz, sootClass);
      } else if (superclazz.isInterface()) {
        errorType = ClassCompiler.CI_ERROR_TYPE_INCOMPATIBLE_CLASS_CHANGE;
        errorMessage =
            String.format("class %s has interface %s as super class", sootClass, superclazz);
      }
      // No need to check for ClassCircularityError. Soot doesn't handle
      // such problems so the compilation will fail earlier.
    }

    if (errorType == ClassCompiler.CI_ERROR_TYPE_NONE) {
      // Check interfaces
      for (SootClass interfaze : sootClass.getInterfaces()) {
        if (interfaze.isPhantom()) {
          errorType = ClassCompiler.CI_ERROR_TYPE_NO_CLASS_DEF_FOUND;
          errorMessage = interfaze.getName();
          break;
        } else if (!checkClassAccessible(interfaze, sootClass)) {
          errorType = ClassCompiler.CI_ERROR_TYPE_ILLEGAL_ACCESS;
          errorMessage = String.format(ILLEGAL_ACCESS_ERROR_CLASS, interfaze, sootClass);
          break;
        } else if (!interfaze.isInterface()) {
          errorType = ClassCompiler.CI_ERROR_TYPE_INCOMPATIBLE_CLASS_CHANGE;
          errorMessage =
              String.format(
                  "class %s tries to implement class %s as interface", sootClass, interfaze);
          break;
        }
      }
    }

    if (errorType == ClassCompiler.CI_ERROR_TYPE_NONE) {
      // Check exceptions used in catch clauses. I cannot find any info in
      // the VM spec specifying that this has to be done when the class is loaded.
      // However, this is how it's done in other VMs so we do it too.
      for (String exName : catches) {
        Clazz ex = config.getClazzes().load(exName);
        if (ex == null || ex.getSootClass().isPhantom()) {
          errorType = ClassCompiler.CI_ERROR_TYPE_NO_CLASS_DEF_FOUND;
          errorMessage = exName;
          break;
        } else if (!checkClassAccessible(ex.getSootClass(), sootClass)) {
          errorType = ClassCompiler.CI_ERROR_TYPE_ILLEGAL_ACCESS;
          errorMessage = String.format(ILLEGAL_ACCESS_ERROR_CLASS, ex, sootClass);
          break;
        }
      }
    }

    if (errorType == ClassCompiler.CI_ERROR_TYPE_NONE) {
      return null;
    }

    // Create a ClassInfoError struct
    StructureConstantBuilder error = new StructureConstantBuilder();
    error.add(new NullConstant(I8_PTR)); // Points to the runtime Class struct
    error.add(new IntegerConstant(ClassCompiler.CI_ERROR));
    error.add(getString(getInternalName(sootClass)));
    error.add(new IntegerConstant(errorType));
    error.add(getString(errorMessage));
    return error.build();
  }