public static Unit insertAfter(SootMethod sootMethod, Unit insertedUnit, Unit originUnit) {
    Body b = sootMethod.retrieveActiveBody();
    PatchingChain<Unit> units = b.getUnits();

    units.insertAfter(insertedUnit, originUnit);

    return insertedUnit;
  }
 private static List<Unit> searchIfStmts(Body b) {
   List<Unit> searchResult = new ArrayList<Unit>();
   PatchingChain<Unit> statements = b.getUnits();
   Iterator<Unit> unitIt = statements.iterator();
   // iterate through the Units of the body
   while (unitIt.hasNext()) {
     Unit tempUnit = unitIt.next();
     // if the unit is a "if statement"
     if (tempUnit instanceof soot.jimple.internal.JIfStmt) searchResult.add(tempUnit);
   }
   return searchResult;
 }
  public static Stmt getFirstNonIdentityStmt(SootMethod sootMethod) {
    Stmt rtVal = null;

    Body b = sootMethod.retrieveActiveBody();
    PatchingChain<Unit> units = b.getUnits();

    for (Iterator<Unit> iter = units.iterator(); iter.hasNext(); ) {
      Stmt stmt = (Stmt) iter.next();

      if (!(stmt instanceof IdentityStmt)) {
        rtVal = stmt;
      }
    }

    return rtVal;
  }
  public static void main(String args[]) {
    // Set classPath
    String exemplePath = "/Users/gamyot/Documents/workspace/Soot_Exemples/src/";
    String objectPath = "/System/Library/Frameworks/JavaVM.framework/Classes/classes.jar";
    String tracePath = "/Users/gamyot/Documents/workspace/SootInstrumenter/src/";

    Scene.v().setSootClassPath(".:" + objectPath + ":" + exemplePath + ":" + tracePath);

    Scene.v().loadClassAndSupport("java.lang.Object");
    Scene.v().loadClassAndSupport("java.lang.System");

    // Set up the class we’re working with
    SootClass c = Scene.v().loadClassAndSupport("MyExemples.ExempleBasic");
    c.setApplicationClass();

    // Get methods
    Iterator<SootMethod> methodIterator = c.methodIterator();
    while (methodIterator.hasNext()) methodList.add(methodIterator.next());
    // Iterate through the method list
    for (SootMethod m : methodList) {
      Body body = m.retrieveActiveBody();
      PatchingChain<Unit> unitList = body.getUnits();
      // get the all the "if statements" Units
      List<Unit> ifStmtList = searchIfStmts(body);

      // for each "if statement" unit, instrument and add the instrumentation code right after
      for (Unit ifStmtUnit : ifStmtList) {
        // Chain<Unit> instrumentedChain = generateInstrumentationUnits(ifStmtUnit, body);
        // unitList.insertAfter(instrumentedChain, ifStmtUnit);
        Chain<Unit> testChain = generateInstrumentationUnits(ifStmtUnit, body);
        unitList.insertAfter(testChain, ifStmtUnit);
      }
      // Output all the units for this method on terminal
      String methodName = m.getName();
      System.out.println(
          "____Method: \"" + methodName + "\"__________________________________________________");
      LoadAndGenerate.printAllUnits(body);
    }

    try {
      LoadAndGenerate.outputClassToBinary(c);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
Example #5
0
  /**
   * Returns basic block that contains the statement, or null. If id stmt, it looks in tag of first
   * non-id stmt.
   */
  public static Block getBB(Stmt s) {
    Block bb;
    // 2010-02-26: return null when s == null
    if (s != null) {
      // move to first non-id stmt
      Stmt sNonId = s;
      if (sNonId instanceof IdentityStmt) {
        PatchingChain pchain =
            ProgramFlowGraph.inst().getContainingMethod(sNonId).retrieveActiveBody().getUnits();
        do {
          sNonId = (Stmt) pchain.getSuccOf(sNonId);
        } while (sNonId instanceof IdentityStmt);
      }

      // retrieve basic block for non-id stmt
      StmtTag sTag = (StmtTag) sNonId.getTag(StmtTag.TAG_NAME);
      bb = sTag.getBasicBlock();
    } else {
      bb = null;
    }

    return bb;
  }
  public static void insertBefore(SootMethod sootMethod, Unit insertedUnit, Unit originUnit) {
    Body b = sootMethod.retrieveActiveBody();
    PatchingChain<Unit> units = b.getUnits();

    units.insertBefore(insertedUnit, originUnit);
  }
  public boolean DoAnalysis(boolean verbose) {
    Stack<List<Set<SootClass>>> current_exception_sets = new Stack<List<Set<SootClass>>>();
    {
      List<Set<SootClass>> exception_sets = new ArrayList<Set<SootClass>>();
      exception_sets.add(method_exception_set);
      current_exception_sets.push(exception_sets);
    }

    PatchingChain<Unit> chain = body.getUnits();
    Unit next = chain.getFirst();

    int previous_class_count = method_exception_set.size();
    for (Map.Entry<Unit, List<TwoValuePair<Trap, Set<SootClass>>>> entry :
        trap_begin_exception_sets.entrySet()) {
      for (TwoValuePair<Trap, Set<SootClass>> tvp : entry.getValue()) {
        previous_class_count += tvp.w.size();
      }
    }

    do {

      if (trap_begin_exception_sets.containsKey(next)) {
        List<TwoValuePair<Trap, Set<SootClass>>> tvps = trap_begin_exception_sets.get(next);
        List<Set<SootClass>> sets_to_add = new ArrayList<Set<SootClass>>();
        for (TwoValuePair<Trap, Set<SootClass>> tvp : tvps) {
          sets_to_add.add(tvp.w);
        }
        current_exception_sets.push(sets_to_add);
      }
      if (next instanceof InvokeStmt || next instanceof AssignStmt) {
        SootMethod callee = null;

        if (next instanceof AssignStmt) {
          if (((AssignStmt) next).getRightOp() instanceof InvokeExpr) {
            callee = ((InvokeExpr) ((AssignStmt) next).getRightOp()).getMethod();
          }
        } else {
          callee = ((InvokeStmt) next).getInvokeExpr().getMethod();
        }

        if (callee != null) { // invocation only

          Collection<SootClass> exception_classes;
          if (class_map.containsKey(callee.getDeclaringClass())) {
            assert class_map.get(callee.getDeclaringClass()).method_analysis.containsKey(callee);

            exception_classes =
                class_map
                    .get(callee.getDeclaringClass())
                    .method_analysis
                    .get(callee)
                    .method_exception_set;
          } else {
            exception_classes = callee.getExceptions();
          }
          for (SootClass exception_class : exception_classes) {
            for (Set<SootClass> current_exception_set : current_exception_sets.peek()) {
              current_exception_set.add(exception_class);
            }
          }
        }

      } else if (next instanceof ThrowStmt) {

        assert chain.getPredOf(next) instanceof JInvokeStmt;
        assert ((JInvokeStmt) chain.getPredOf(next)).getInvokeExpr() instanceof SpecialInvokeExpr;
        assert ((SpecialInvokeExpr) ((JInvokeStmt) chain.getPredOf(next)).getInvokeExpr()).getBase()
            instanceof JimpleLocal;
        assert ((JimpleLocal)
                    ((SpecialInvokeExpr) ((JInvokeStmt) chain.getPredOf(next)).getInvokeExpr())
                        .getBase())
                .getType()
            instanceof RefType;

        SootClass exception_class =
            ((RefType)
                    ((JimpleLocal)
                            ((SpecialInvokeExpr)
                                    ((JInvokeStmt) chain.getPredOf(next)).getInvokeExpr())
                                .getBase())
                        .getType())
                .getSootClass();

        for (Set<SootClass> current_exception_set : current_exception_sets.peek()) {
          current_exception_set.add(exception_class);
        }
      }

      if (trap_end_exception_sets.containsKey(next)) {

        List<TwoValuePair<Trap, Set<SootClass>>> tvps = trap_end_exception_sets.get(next);

        if (verbose) {
          for (Set<SootClass> current_exception_set : current_exception_sets.peek()) {
            if (current_exception_set.size() == 0) {
              for (TwoValuePair<Trap, Set<SootClass>> tvp : tvps) {
                if (!tvp.v.getException().getName().equals("java.lang.RuntimeException"))
                  System.out.println(
                      "Warning: In "
                          + method.toString()
                          + ": Unncessary exception handler for catching "
                          + tvp.v.getException().getName());
              }
            }
          }
        }

        for (TwoValuePair<Trap, Set<SootClass>> tvp : tvps) {

          Iterator<SootClass> i = tvp.w.iterator();
          while (i.hasNext()) {
            SootClass exception_class = i.next();

            if (tvp.v.getException()
                == exception_class) { // getting properly caught by the handler.
              i.remove();
            } else {
              SootClass super_exception_class = exception_class;
              while (super_exception_class != null) {

                if (tvp.v.getException() == super_exception_class) {
                  i.remove();
                  if (verbose
                      && super_exception_class != exception_class
                      && GetMostRestrictiveFormOfException(tvps, exception_class)
                          == tvp.v.getException()
                      && !super_exception_class.getName().equals("java.lang.RuntimeException")) {
                    System.out.println(
                        "Warning: In "
                            + method.toString()
                            + ": attempting to catch "
                            + exception_class.getName()
                            + " with "
                            + super_exception_class.getName()
                            + " Consider catching the most restrictive exception class");
                  }
                  break;
                }
                try {
                  super_exception_class = super_exception_class.getSuperclass();
                } catch (
                    RuntimeException
                        e) { // unfortunately soot doesn't have a specific exception class for "no
                  // superclass for java.lang.Object" exception
                  super_exception_class = null;
                }
              }
            }
          }
        }

        current_exception_sets.pop();

        for (Set<SootClass> current_exception_set :
            current_exception_sets
                .peek()) { // This list iteration is not necessary if we are still making the
          // assumption that there's only one unique set that contains exception
          // classes if the range for traps are the same
          for (TwoValuePair<Trap, Set<SootClass>> tvp : tvps) {
            for (SootClass exception_class : tvp.w) {
              current_exception_set.add(exception_class);
            }
          }
        }
      }
      next = chain.getSuccOf(next);
    } while (next != null);

    int new_class_count = method_exception_set.size();
    for (Map.Entry<Unit, List<TwoValuePair<Trap, Set<SootClass>>>> entry :
        trap_begin_exception_sets.entrySet()) {
      for (TwoValuePair<Trap, Set<SootClass>> tvp : entry.getValue()) {
        new_class_count += tvp.w.size();
      }
    }

    return new_class_count != previous_class_count;
  }