예제 #1
0
 /**
  * Performs the work that is required to construct any sort of <tt>UnitGraph</tt>.
  *
  * @param body The body of the method for which to construct a control flow graph.
  */
 protected UnitGraph(Body body) {
   this.body = body;
   unitChain = body.getUnits();
   method = body.getMethod();
   if (Options.v().verbose())
     G.v()
         .out
         .println(
             "[" + method.getName() + "]     Constructing " + this.getClass().getName() + "...");
 }
예제 #2
0
  /** Prints the given <code>JimpleBody</code> to the specified <code>PrintWriter</code>. */
  private void printLocalsInBody(Body body, UnitPrinter up) {
    // Print out local variables
    {
      Map typeToLocals = new DeterministicHashMap(body.getLocalCount() * 2 + 1, 0.7f);

      // Collect locals
      {
        Iterator localIt = body.getLocals().iterator();

        while (localIt.hasNext()) {
          Local local = (Local) localIt.next();

          List localList;

          Type t = local.getType();

          if (typeToLocals.containsKey(t)) localList = (List) typeToLocals.get(t);
          else {
            localList = new ArrayList();
            typeToLocals.put(t, localList);
          }

          localList.add(local);
        }
      }

      // Print locals
      {
        Iterator typeIt = typeToLocals.keySet().iterator();

        while (typeIt.hasNext()) {
          Type type = (Type) typeIt.next();

          List localList = (List) typeToLocals.get(type);
          Object[] locals = localList.toArray();
          up.type(type);
          up.literal(" ");

          for (int k = 0; k < locals.length; k++) {
            if (k != 0) up.literal(", ");

            up.local((Local) locals[k]);
          }

          up.literal(";");
          up.newline();
        }
      }

      if (!typeToLocals.isEmpty()) {
        up.newline();
      }
    }
  }
예제 #3
0
  /**
   * @ast method
   * @aspect Expressions
   * @declaredat
   *     /Users/eric/Documents/workspaces/clara-soot/JastAddExtensions/JimpleBackend/Expressions.jrag:84
   */
  public soot.Value eval(Body b) {
    TypeDecl dest = getDest().type();
    TypeDecl source = getSource().type();
    if (dest.isString()) {

      Value lvalue = getDest().eval(b);

      Value v = asImmediate(b, lvalue);

      // new StringBuffer(left)
      Local local =
          b.newTemp(b.newNewExpr(lookupType("java.lang", "StringBuffer").sootRef(), this));
      b.setLine(this);
      b.add(
          b.newInvokeStmt(
              b.newSpecialInvokeExpr(
                  local,
                  Scene.v()
                      .getMethod("<java.lang.StringBuffer: void <init>(java.lang.String)>")
                      .makeRef(),
                  v,
                  this),
              this));

      // append right
      Local rightResult =
          b.newTemp(
              b.newVirtualInvokeExpr(
                  local,
                  lookupType("java.lang", "StringBuffer")
                      .methodWithArgs("append", new TypeDecl[] {source.stringPromotion()})
                      .sootRef(),
                  asImmediate(b, getSource().eval(b)),
                  this));

      // toString
      Local result =
          b.newTemp(
              b.newVirtualInvokeExpr(
                  rightResult,
                  Scene.v()
                      .getMethod("<java.lang.StringBuffer: java.lang.String toString()>")
                      .makeRef(),
                  this));

      Value v2 = lvalue instanceof Local ? lvalue : (Value) lvalue.clone();
      getDest().emitStore(b, v2, result, this);
      return result;
    } else {
      return super.eval(b);
    }
  }
예제 #4
0
  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();
    }
  }
예제 #5
0
  /**
   * Prints out the method corresponding to b Body, (declaration and body), in the textual format
   * corresponding to the IR used to encode b body.
   *
   * @param out a PrintWriter instance to print to.
   */
  public void printTo(Body b, PrintWriter out) {
    b.validate();

    boolean isPrecise = !useAbbreviations();

    String decl = b.getMethod().getDeclaration();

    out.println("    " + decl);
    // incJimpleLnNum();

    // only print tags if not printing attributes in a file
    if (!addJimpleLn()) {
      /*for( Iterator tIt = b.getMethod().getTags().iterator(); tIt.hasNext(); ) {    final Tag t = (Tag) tIt.next();
          out.println(t);
          incJimpleLnNum();

      }*/
    }

    if (addJimpleLn()) {
      setJimpleLnNum(addJimpleLnTags(getJimpleLnNum(), b.getMethod()));
      // G.v().out.println("added jimple ln tag for method: "+b.getMethod().toString()+"
      // "+b.getMethod().getDeclaringClass().getName());
    }

    out.println("    {");
    incJimpleLnNum();

    UnitGraph unitGraph = new soot.toolkits.graph.BriefUnitGraph(b);

    LabeledUnitPrinter up;
    if (isPrecise) up = new NormalUnitPrinter(b);
    else up = new BriefUnitPrinter(b);

    if (addJimpleLn()) {
      up.setPositionTagger(new AttributesUnitPrinter(getJimpleLnNum()));
    }

    printLocalsInBody(b, up);

    printStatementsInBody(b, out, up, unitGraph);

    out.println("    }");
    incJimpleLnNum();
  }
예제 #6
0
 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 FaintVariableAnalysis(Body body) {

    Chain<Local> locals = body.getLocals();

    allVariables = new CollectionFlowUniverse<Local>(locals);

    universalSet = new ArrayPackedSet(allVariables);

    for (Local l : locals) universalSet.add(l);

    useSetMap = new HashMap<Unit, BoundedFlowSet>();
    defSetMap = new HashMap<Unit, BoundedFlowSet>();

    UnitGraph graph = new BriefUnitGraph(body);
    for (Unit u : graph) {

      BoundedFlowSet defSet = new ArrayPackedSet(allVariables);
      BoundedFlowSet useSet = new ArrayPackedSet(allVariables);

      for (ValueBox v : u.getDefBoxes()) {
        // Only do this for locals. We're not going to even try to handle anything
        // other than locals.
        if (v.getValue() instanceof Local) {
          defSet.add(v.getValue());
        }
      }
      for (ValueBox v : u.getUseBoxes()) {
        // Only do this for locals. We're not going to even try to handle anything
        // other than locals.
        if (v.getValue() instanceof Local) {
          useSet.add(v.getValue());
        }
      }

      defSetMap.put(u, defSet);
      useSetMap.put(u, useSet);
    }
  }
예제 #8
0
  /*
   * Generates the sequence of instructions needed to instrument ifStmtUnit
   *
   * @param ifStmtUnit: the unit to be instrumented
   * @return A Chain of Units that represent the instrumentation of ifStmtUnit
   */
  private static Chain<Unit> generateInstrumentationUnits(Unit ifStmtUnit, Body b) {

    AbstractBinopExpr expression =
        (AbstractBinopExpr)
            ((JIfStmt) ifStmtUnit).getCondition(); // implementation of AbstractBinopExpr
    Value operand1 = expression.getOp1();
    Value operand2 = expression.getOp2();

    JimpleLocal op1Local = (JimpleLocal) operand1;

    // Local localOperand = Jimple.v().newLocal("op1", operand1.getType());
    // b.getLocals().add(localOperand);

    // We need to use these operand as Locals or constants
    /**
     * JimpleLocal test; if(operand1 instanceof soot.jimple.internal.JimpleLocal) test =
     * (JimpleLocal)operand1; else test = null;
     */
    String op = expression.getClass().toString();

    Chain<Unit> resultUnits = new HashChain<Unit>();
    Local tmpRef;
    // Add locals directely on the top of the body, java.io.printStream tmpRef
    tmpRef = Jimple.v().newLocal("tmpRef", RefType.v("java.io.PrintStream"));
    b.getLocals().addFirst(tmpRef);

    // add "tmpRef = java.lang.System.out"
    resultUnits.add(
        Jimple.v()
            .newAssignStmt(
                tmpRef,
                Jimple.v()
                    .newStaticFieldRef(
                        Scene.v()
                            .getField("<java.lang.System: java.io.PrintStream out>")
                            .makeRef())));
    {
      SootMethod toCall =
          Scene.v().getMethod("<java.io.PrintStream: void println(java.lang.String)>");
      resultUnits.add(
          Jimple.v()
              .newInvokeStmt(
                  Jimple.v()
                      .newVirtualInvokeExpr(
                          tmpRef, toCall.makeRef(), StringConstant.v("Operande 1: "))));
      resultUnits.add(
          Jimple.v()
              .newInvokeStmt(
                  Jimple.v()
                      .newVirtualInvokeExpr(
                          tmpRef,
                          toCall.makeRef(),
                          StringConstant.v(operand1.getClass().toString()))));

      resultUnits.add(
          Jimple.v()
              .newInvokeStmt(
                  Jimple.v()
                      .newVirtualInvokeExpr(
                          tmpRef, toCall.makeRef(), StringConstant.v("Operande 2:"))));

      resultUnits.add(
          Jimple.v()
              .newInvokeStmt(
                  Jimple.v()
                      .newVirtualInvokeExpr(
                          tmpRef,
                          toCall.makeRef(),
                          StringConstant.v(operand2.getClass().toString()))));

      resultUnits.add(
          Jimple.v()
              .newInvokeStmt(
                  Jimple.v()
                      .newVirtualInvokeExpr(
                          tmpRef, toCall.makeRef(), StringConstant.v("Operateur: "))));

      resultUnits.add(
          Jimple.v()
              .newInvokeStmt(
                  Jimple.v().newVirtualInvokeExpr(tmpRef, toCall.makeRef(), StringConstant.v(op))));
    }

    return resultUnits;
  }
예제 #9
0
  /**
   * Constructs a graph for the units found in the provided Body instance. Each node in the graph
   * corresponds to a unit. The edges are derived from the control flow.
   *
   * @param body The underlying body we want to make a graph for.
   * @param addExceptionEdges If true then the control flow edges associated with exceptions are
   *     added.
   * @param dontAddEdgeFromStmtBeforeAreaOfProtectionToCatchBlock This was added for Dava. If true,
   *     edges are not added from statement before area of protection to catch. If false, edges ARE
   *     added. For Dava, it should be true. For flow analyses, it should be false.
   * @param Hierarchy Using class hierarchy analysis to find the run method of started thread
   * @param PointsToAnalysis Using point to analysis (SPARK package) to improve the precision of
   *     results
   */
  public PegGraph(
      CallGraph callGraph,
      Hierarchy hierarchy,
      PAG pag,
      Set methodsNeedingInlining,
      Set allocNodes,
      List<List> inlineSites,
      Map<SootMethod, String> synchObj,
      Set multiRunAllocNodes,
      Map<AllocNode, String> allocNodeToObj,
      Body unitBody,
      String threadName,
      SootMethod sm,
      boolean addExceEdge,
      boolean dontAddEdgeFromStmtBeforeAreaOfProtectionToCatchBlock) {
    this.allocNodeToObj = allocNodeToObj;
    this.multiRunAllocNodes = multiRunAllocNodes;
    this.synchObj = synchObj;
    this.inlineSites = inlineSites;
    this.allocNodes = allocNodes;
    this.methodsNeedingInlining = methodsNeedingInlining;
    logFile = new File("log.txt");
    try {
      fileWriter = new FileWriter(logFile);
    } catch (IOException io) {
      System.err.println("Errors occur during create FileWriter !");
      //			throw io;
    }

    body = unitBody;
    synch = new HashSet<List>();
    exceHandlers = new HashSet<Unit>();
    needInlining = true;
    monitorObjs = new HashSet<Object>();
    startToBeginNodes = new HashMap();
    unitChain = body.getUnits();
    int size = unitChain.size();
    // initial unitToSuccs, unitToPreds, unitToPegMap, and startToThread
    unitToSuccs = new HashMap(size * 2 + 1, 0.7f);
    unitToPreds = new HashMap(size * 2 + 1, 0.7f);
    // unitToPegMap is the map of a chain to its corresponding (cfg node --> peg node ) map.
    unitToPegMap = new HashMap(size * 2 + 1, 0.7f);
    startToThread = new HashMap(size * 2 + 1, 0.7f);
    startToAllocNodes = new HashMap(size * 2 + 1, 0.7f);
    waitingNodes = new HashMap<String, FlowSet>(size * 2 + 1, 0.7f);
    joinStmtToThread = new HashMap<JPegStmt, Chain>();
    threadNo = new HashMap();
    threadNameToStart = new HashMap();
    this.allocNodeToObj = new HashMap<AllocNode, String>(size * 2 + 1, 0.7f);
    allocNodeToThread = new HashMap<AllocNode, PegChain>(size * 2 + 1, 0.7f);
    notifyAll = new HashMap<String, Set<JPegStmt>>(size * 2 + 1, 0.7f);

    methodsNeedingInlining = new HashSet();
    allNodes = new ArraySparseSet();
    canNotBeCompacted = new HashSet();
    threadAllocSites = new HashSet();
    specialJoin = new HashSet<JPegStmt>();
    //       if(Main.isVerbose)
    //   System.out.println("     Constructing PegGraph...");

    // if(Main.isProfilingOptimization)
    //   Main.graphTimer.start();
    // make a peg for debug
    /*
    mainPegChain = new HashChain();
    specialTreatment1();
    */
    // end make a peg

    UnitGraph mainUnitGraph = new CompleteUnitGraph(body);
    //	mainPegChain = new HashChain();
    mainPegChain =
        new PegChain(
            callGraph,
            hierarchy,
            pag,
            threadAllocSites,
            methodsNeedingInlining,
            allocNodes,
            inlineSites,
            synchObj,
            multiRunAllocNodes,
            allocNodeToObj,
            body,
            sm,
            threadName,
            true,
            this);

    // testPegChain();

    //		System.out.println("finish building chain");
    // testStartToThread();
    // buildSuccessor(mainUnitGraph, mainPegChain,addExceptionEdges);
    //	buildSuccessorForExtendingMethod(mainPegChain);
    // testSet(exceHandlers, "exceHandlers");
    buildSuccessor(mainPegChain);
    // System.out.println("finish building successors");
    // unmodifiableSuccs(mainPegChain);
    // testUnitToSucc );
    buildPredecessor(mainPegChain);
    // System.out.println("finish building predcessors");
    // unmodifiablePreds(mainPegChain);
    // testSynch();
    addMonitorStmt();
    addTag();
    //	System.out.println(this.toString());
    buildHeadsAndTails();

    // testIterator();
    // testWaitingNodes();

    //	System.out.println("finish building heads and tails");

    // testSet(canNotBeCompacted, "canNotBeCompacted");
    //	computeEdgeAndThreadNo();
    //	testExtendingPoints();
    //	testUnitToSucc();

    // testPegChain();
    /*	if (print) {
    PegToDotFile printer1 = new PegToDotFile(this, false, sm.getName());
    }
    */
    try {
      fileWriter.flush();
      fileWriter.close();
    } catch (IOException io) {
      System.err.println("Errors occur during close file  " + logFile.getName());
      //        throw io;
    }
    // System.out.println("==threadAllocaSits==\n"+threadAllocSites.toString());

  }
예제 #10
0
  /** Prints the given <code>JimpleBody</code> to the specified <code>PrintWriter</code>. */
  private void printStatementsInBody(
      Body body, java.io.PrintWriter out, LabeledUnitPrinter up, UnitGraph unitGraph) {
    Chain units = body.getUnits();
    Iterator unitIt = units.iterator();
    Unit currentStmt = null, previousStmt;

    while (unitIt.hasNext()) {

      previousStmt = currentStmt;
      currentStmt = (Unit) unitIt.next();

      // Print appropriate header.
      {
        // Put an empty line if the previous node was a branch node, the current node is a join node
        //   or the previous statement does not have body statement as a successor, or if
        //   body statement has a label on it

        if (currentStmt != units.getFirst()) {
          if (unitGraph.getSuccsOf(previousStmt).size() != 1
              || unitGraph.getPredsOf(currentStmt).size() != 1
              || up.labels().containsKey(currentStmt)) {
            up.newline();
          } else {
            // Or if the previous node does not have body statement as a successor.

            List succs = unitGraph.getSuccsOf(previousStmt);

            if (succs.get(0) != currentStmt) {
              up.newline();
            }
          }
        }

        if (up.labels().containsKey(currentStmt)) {
          up.unitRef(currentStmt, true);
          up.literal(":");
          up.newline();
        }

        if (up.references().containsKey(currentStmt)) {
          up.unitRef(currentStmt, false);
        }
      }

      up.startUnit(currentStmt);
      currentStmt.toString(up);
      up.endUnit(currentStmt);

      up.literal(";");
      up.newline();

      // only print them if not generating attributes files
      // because they mess up line number
      // if (!addJimpleLn()) {
      if (Options.v().print_tags_in_output()) {
        Iterator tagIterator = currentStmt.getTags().iterator();
        while (tagIterator.hasNext()) {
          Tag t = (Tag) tagIterator.next();
          up.noIndent();
          up.literal("/*");
          up.literal(t.toString());
          up.literal("*/");
          up.newline();
        }
        /*Iterator udIt = currentStmt.getUseAndDefBoxes().iterator();
        while (udIt.hasNext()) {
            ValueBox temp = (ValueBox)udIt.next();
            Iterator vbtags = temp.getTags().iterator();
            while (vbtags.hasNext()) {
                Tag t = (Tag) vbtags.next();
                up.noIndent();
                up.literal("VB Tag: "+t.toString());
                up.newline();
            }
        }*/
      }
    }

    out.print(up.toString());
    if (addJimpleLn()) {
      setJimpleLnNum(up.getPositionTagger().getEndLn());
    }

    // Print out exceptions
    {
      Iterator trapIt = body.getTraps().iterator();

      if (trapIt.hasNext()) {
        out.println();
        incJimpleLnNum();
      }

      while (trapIt.hasNext()) {
        Trap trap = (Trap) trapIt.next();

        out.println(
            "        catch "
                + Scene.v().quotedNameOf(trap.getException().getName())
                + " from "
                + up.labels().get(trap.getBeginUnit())
                + " to "
                + up.labels().get(trap.getEndUnit())
                + " with "
                + up.labels().get(trap.getHandlerUnit())
                + ";");

        incJimpleLnNum();
      }
    }
  }
예제 #11
0
 /**
  * @ast method
  * @aspect Expressions
  * @declaredat
  *     /Users/eric/Documents/workspaces/clara-soot/JastAddExtensions/JimpleBackend/Expressions.jrag:183
  */
 public soot.Value createAssignOp(Body b, soot.Value fst, soot.Value snd) {
   return b.newXorExpr(asImmediate(b, fst), asImmediate(b, snd), this);
 }
예제 #12
0
 /**
  * @ast method
  * @aspect Statements
  * @declaredat
  *     /Users/eric/Documents/workspaces/clara-soot/JastAddExtensions/JimpleBackend/Statements.jrag:312
  */
 public void jimplify2(Body b) {
   b.setLine(this);
   b.add(b.newThrowStmt(asImmediate(b, getExpr().eval(b)), this));
 }