SpecialInvokeExpr Проблема с сажей - PullRequest
0 голосов
/ 25 октября 2019

Проблема в том, что я хотел бы вставить специальное выражение вызова в мой код, не присваивая его значению, например, в jimple ему назначается $ r2.

Ошибка в том, что я использую unit.insertBefore (). Это приводит к тому, что я не могу вставить его без использования присваивания для выражения вызова.

Есть ли способ обойти это?

Проблема находится в строке 92 файла Test2.java, представленного ниже.

Любая помощь будет принята с благодарностью. Спасибо.

ФАЙЛ: Test2.java

package dfa;

import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import soot.options.Options;
import soot.*;
import soot.jimple.AssignStmt;
import soot.jimple.InstanceInvokeExpr;
import soot.jimple.InvokeExpr;
import soot.jimple.InvokeStmt;
import soot.jimple.Jimple;
import soot.jimple.SpecialInvokeExpr;
import soot.jimple.Stmt;
import soot.jimple.VirtualInvokeExpr;
import soot.jimple.toolkits.callgraph.Units;
import soot.toolkits.graph.BriefUnitGraph;
import soot.toolkits.graph.UnitGraph;
import soot.jimple.AssignStmt;
import soot.jimple.InstanceInvokeExpr;
import soot.jimple.InvokeExpr;
import soot.jimple.Jimple;
import soot.jimple.Stmt;
import soot.jimple.StringConstant;
import soot.toolkits.graph.*;
import soot.util.Chain;

public class Testing2 {
      public static void main(String[] args) {
          soot.G.reset();

        Options.v().set_process_dir(Collections.singletonList("/home/sean/Projects/Soot/HelloWorld.jar"));
        Options.v().set_src_prec(Options.src_prec_java);
        Options.v().set_whole_program(true);
        Options.v().set_allow_phantom_refs(true);
        Options.v().set_output_format(Options.output_format_jimple);
        Options.v().setPhaseOption("cg.spark", "verbose:false");

        Scene.v().loadNecessaryClasses();
        SootClass entryClass = Scene.v().getSootClassUnsafe("HelloWorld");
        SootMethod sMethod = entryClass.getMethodByNameUnsafe("main");
        Options.v().set_main_class(sMethod.getSignature());

        Scene.v().setEntryPoints(Collections.singletonList(sMethod));
        PackManager.v().runPacks();
        Body body = sMethod.getActiveBody();
        UnitGraph graph = new BriefUnitGraph(body);

        // Perform LV Analysis on the Graph
        LiveVariableAnalysis analysis = new LiveVariableAnalysis(graph);

        // Print live variables at the entry and exit of each node
        Iterator<Unit> unitIt = graph.iterator();
        analysis.getFlowBefore(unitIt.next());  
        Stmt stm =null;
        Chain units = graph.getBody().getUnits();
        Set<Value> activeList = new HashSet<>(); //USED FOR ACTIVE DATA
        Value base = null;
        //WANT TO ITERATE THROUGH EACH UNIT WHICH HAS STATEMENTS ASSOCIATED WITH EACH UNIT
        while (unitIt.hasNext()) {
            Unit s = unitIt.next();
            stm = (Stmt)s;
            System.out.println("Statement: " + stm);
            if (stm.containsInvokeExpr()) { 
                System.out.println("CONTAINS INVOKE EXPR");
                activeList.add(stm.getInvokeExpr().getArg(0));
                System.out.println(stm.getInvokeExpr().getArgs());
                InvokeExpr ie = stm.getInvokeExpr();
                InstanceInvokeExpr iie = (InstanceInvokeExpr)ie;
                base = iie.getBase();               
            }

        }

        for(Value s : activeList)
        {
            System.out.println("ACTIVE LIST IS: \t"+s);
            LinkedList<Value> args2 = new LinkedList<Value>(); 
            args2.add(s);

            Local tmp = Jimple.v().newLocal("$r"+Integer.toString(graph.getBody().getLocalCount()), RefType.v("java.io.PrintStream"));
            graph.getBody().getLocals().add(tmp);
            SootMethodRef setRef = Scene.v().getMethod("<java.io.PrintStream: void println(java.lang.String)>").makeRef();          
            VirtualInvokeExpr vr = Jimple.v().newVirtualInvokeExpr((Local) base, setRef, args2);
            AssignStmt a = Jimple.v().newAssignStmt(tmp, vr);       
            vr = Jimple.v().newVirtualInvokeExpr((Local)a.getLeftOp(), setRef, args2);
            a = Jimple.v().newAssignStmt(tmp, vr);
            units.insertBefore(a,stm);

            SpecialInvokeExpr vr2 = Jimple.v().newSpecialInvokeExpr((Local) base, setRef, args2);
            AssignStmt a2 = Jimple.v().newAssignStmt(tmp, vr2);
            vr2 = Jimple.v().newSpecialInvokeExpr((Local)a2.getLeftOp(), setRef, args2);            
            System.out.println("TESTING: " + vr2);          
            a2 = Jimple.v().newAssignStmt(tmp, vr2);
//          units.insertBefore(a2, stm);    
        }       
        //WANT TO VIEW THE CODE FOR THE UNIT
        System.out.println();
        System.out.println("UNIT 1:");
        Iterator<Unit> unitIt1 = graph.iterator();

        while (unitIt1.hasNext()) {
            Unit s = unitIt1.next();
            stm = (Stmt)s;
            System.out.println("\t"+stm);

            if (stm.containsInvokeExpr()) { 
                InvokeExpr ie = stm.getInvokeExpr();
                InstanceInvokeExpr iie = (InstanceInvokeExpr)ie;
                base = iie.getBase();
                }
        }       
//      PRINT OUT WHOLE BODY NOW
        System.out.println("Body: ");
        System.out.println(body);       
      }
}

ФАЙЛ: LiveVariableAnalysis.java

package dfa;

import soot.Local;
import soot.Unit;
import soot.ValueBox;
import soot.toolkits.graph.DirectedGraph;
import soot.toolkits.scalar.BackwardFlowAnalysis;
import soot.toolkits.scalar.FlowSet;
import soot.toolkits.scalar.ArraySparseSet;

class LiveVariableAnalysis 
    extends BackwardFlowAnalysis<Unit, FlowSet<Local>> 
{

    private FlowSet<Local> emptySet;

    public LiveVariableAnalysis(DirectedGraph g) {

        // First obligation
        super(g);


        emptySet = new ArraySparseSet<Local>();

        // Second obligation
        doAnalysis();

    }


    // This method performs the joining of successor nodes
    // Since live variables is a may analysis we join by union 
    @Override
    protected void merge(FlowSet<Local> inSet1, 
        FlowSet<Local> inSet2, 
        FlowSet<Local> outSet) 
    {
        inSet1.union(inSet2, outSet);
    }


    @Override
    protected void copy(FlowSet<Local> srcSet, 
        FlowSet<Local> destSet) 
    {
        srcSet.copy(destSet);
    }


    // Used to initialize the in and out sets for each node. In
    // our case we build up the sets as we go, so we initialize
    // with the empty set.
    @Override
    protected FlowSet<Local> newInitialFlow() {
        return emptySet.clone();
    }


    // Returns FlowSet representing the initial set of the entry
    // node. In our case the entry node is the last node and it
    // should contain the empty set.
    @Override
    protected FlowSet<Local> entryInitialFlow() {
        return emptySet.clone();
    }


    // Sets the outSet with the values that flow through the 
    // node from the inSet based on reads/writes at the node
    // Set the outSet (entry) based on the inSet (exit)
    @Override
    protected void flowThrough(FlowSet<Local> inSet, 
        Unit node, FlowSet<Local> outSet) {

        // outSet is the set at enrty of the node
        // inSet is the set at exit of the node
        // out <- (in - write(node)) union read(node)

        // out <- (in - write(node))

        FlowSet writes = (FlowSet)emptySet.clone();

        for (ValueBox def: node.getUseAndDefBoxes()) {
            if (def.getValue() instanceof Local) {
                writes.add(def.getValue());
            }
        }
        inSet.difference(writes, outSet);

        // out <- out union read(node)

        for (ValueBox use: node.getUseBoxes()) {
            if (use.getValue() instanceof Local) {
                outSet.add((Local) use.getValue());
            }
        }
    }
}


...