Search in sources :

Example 41 with Body

use of soot.Body in project soot by Sable.

the class AbstractJimpleBasedICFG method getStartPointsOf.

@Override
public Collection<Unit> getStartPointsOf(SootMethod m) {
    if (m.hasActiveBody()) {
        Body body = m.getActiveBody();
        DirectedGraph<Unit> unitGraph = getOrCreateUnitGraph(body);
        return unitGraph.getHeads();
    }
    return Collections.emptySet();
}
Also used : Unit(soot.Unit) Body(soot.Body)

Example 42 with Body

use of soot.Body in project soot by Sable.

the class AbstractJimpleBasedICFG method isStartPoint.

@Override
public boolean isStartPoint(Unit u) {
    Body body = unitToOwner.get(u);
    DirectedGraph<Unit> unitGraph = getOrCreateUnitGraph(body);
    return unitGraph.getHeads().contains(u);
}
Also used : Unit(soot.Unit) Body(soot.Body)

Example 43 with Body

use of soot.Body in project soot by Sable.

the class ReflectiveCallsInliner method initializeReflectiveCallsTable.

private void initializeReflectiveCallsTable() {
    int callSiteId = 0;
    SootClass reflCallsClass = Scene.v().getSootClass("soot.rtlib.tamiflex.ReflectiveCalls");
    SootMethod clinit = reflCallsClass.getMethodByName(SootMethod.staticInitializerName);
    Body body = clinit.retrieveActiveBody();
    PatchingChain<Unit> units = body.getUnits();
    LocalGenerator localGen = new LocalGenerator(body);
    Chain<Unit> newUnits = new HashChain<Unit>();
    SootClass setClass = Scene.v().getSootClass("java.util.Set");
    SootMethodRef addMethodRef = setClass.getMethodByName("add").makeRef();
    for (SootMethod m : RTI.methodsContainingReflectiveCalls()) {
        {
            if (!RTI.classForNameClassNames(m).isEmpty()) {
                SootFieldRef fieldRef = Scene.v().makeFieldRef(reflCallsClass, "classForName", RefType.v("java.util.Set"), true);
                Local setLocal = localGen.generateLocal(RefType.v("java.util.Set"));
                newUnits.add(Jimple.v().newAssignStmt(setLocal, Jimple.v().newStaticFieldRef(fieldRef)));
                for (String className : RTI.classForNameClassNames(m)) {
                    InterfaceInvokeExpr invokeExpr = Jimple.v().newInterfaceInvokeExpr(setLocal, addMethodRef, StringConstant.v(callSiteId + className));
                    newUnits.add(Jimple.v().newInvokeStmt(invokeExpr));
                }
                callSiteId++;
            }
        }
        {
            if (!RTI.classNewInstanceClassNames(m).isEmpty()) {
                SootFieldRef fieldRef = Scene.v().makeFieldRef(reflCallsClass, "classNewInstance", RefType.v("java.util.Set"), true);
                Local setLocal = localGen.generateLocal(RefType.v("java.util.Set"));
                newUnits.add(Jimple.v().newAssignStmt(setLocal, Jimple.v().newStaticFieldRef(fieldRef)));
                for (String className : RTI.classNewInstanceClassNames(m)) {
                    InterfaceInvokeExpr invokeExpr = Jimple.v().newInterfaceInvokeExpr(setLocal, addMethodRef, StringConstant.v(callSiteId + className));
                    newUnits.add(Jimple.v().newInvokeStmt(invokeExpr));
                }
                callSiteId++;
            }
        }
        {
            if (!RTI.constructorNewInstanceSignatures(m).isEmpty()) {
                SootFieldRef fieldRef = Scene.v().makeFieldRef(reflCallsClass, "constructorNewInstance", RefType.v("java.util.Set"), true);
                Local setLocal = localGen.generateLocal(RefType.v("java.util.Set"));
                newUnits.add(Jimple.v().newAssignStmt(setLocal, Jimple.v().newStaticFieldRef(fieldRef)));
                for (String constrSig : RTI.constructorNewInstanceSignatures(m)) {
                    InterfaceInvokeExpr invokeExpr = Jimple.v().newInterfaceInvokeExpr(setLocal, addMethodRef, StringConstant.v(callSiteId + constrSig));
                    newUnits.add(Jimple.v().newInvokeStmt(invokeExpr));
                }
                callSiteId++;
            }
        }
        {
            if (!RTI.methodInvokeSignatures(m).isEmpty()) {
                SootFieldRef fieldRef = Scene.v().makeFieldRef(reflCallsClass, "methodInvoke", RefType.v("java.util.Set"), true);
                Local setLocal = localGen.generateLocal(RefType.v("java.util.Set"));
                newUnits.add(Jimple.v().newAssignStmt(setLocal, Jimple.v().newStaticFieldRef(fieldRef)));
                for (String methodSig : RTI.methodInvokeSignatures(m)) {
                    InterfaceInvokeExpr invokeExpr = Jimple.v().newInterfaceInvokeExpr(setLocal, addMethodRef, StringConstant.v(callSiteId + methodSig));
                    newUnits.add(Jimple.v().newInvokeStmt(invokeExpr));
                }
                callSiteId++;
            }
        }
    }
    Unit secondLastStmt = units.getPredOf(units.getLast());
    units.insertAfter(newUnits, secondLastStmt);
    if (Options.v().validate())
        body.validate();
}
Also used : LocalGenerator(soot.javaToJimple.LocalGenerator) HashChain(soot.util.HashChain) SootMethodRef(soot.SootMethodRef) Local(soot.Local) InterfaceInvokeExpr(soot.jimple.InterfaceInvokeExpr) SootClass(soot.SootClass) Unit(soot.Unit) SootFieldRef(soot.SootFieldRef) SootMethod(soot.SootMethod) Body(soot.Body) JimpleBody(soot.jimple.JimpleBody)

Example 44 with Body

use of soot.Body in project soot by Sable.

the class ReflectiveCallsInliner method inlineRelectiveCalls.

private void inlineRelectiveCalls(SootMethod m, Set<String> targets, Kind callKind) {
    if (!m.hasActiveBody())
        m.retrieveActiveBody();
    Body b = m.getActiveBody();
    PatchingChain<Unit> units = b.getUnits();
    Iterator<Unit> iter = units.snapshotIterator();
    LocalGenerator localGen = new LocalGenerator(b);
    // for all units
    while (iter.hasNext()) {
        Chain<Unit> newUnits = new HashChain<Unit>();
        Stmt s = (Stmt) iter.next();
        // reflective invoke expression
        if (s.containsInvokeExpr()) {
            InvokeExpr ie = s.getInvokeExpr();
            boolean found = false;
            Type fieldSetGetType = null;
            if (callKind == Kind.ClassForName && (ie.getMethodRef().getSignature().equals("<java.lang.Class: java.lang.Class forName(java.lang.String)>") || ie.getMethodRef().getSignature().equals("<java.lang.Class: java.lang.Class forName(java.lang.String,boolean,java.lang.ClassLoader)>"))) {
                found = true;
                Value classNameValue = ie.getArg(0);
                newUnits.add(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(Scene.v().getMethod("<soot.rtlib.tamiflex.ReflectiveCalls: void knownClassForName(int,java.lang.String)>").makeRef(), IntConstant.v(callSiteId), classNameValue)));
            } else if (callKind == Kind.ClassNewInstance && ie.getMethodRef().getSignature().equals("<java.lang.Class: java.lang.Object newInstance()>")) {
                found = true;
                Local classLocal = (Local) ((InstanceInvokeExpr) ie).getBase();
                newUnits.add(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(Scene.v().getMethod("<soot.rtlib.tamiflex.ReflectiveCalls: void knownClassNewInstance(int,java.lang.Class)>").makeRef(), IntConstant.v(callSiteId), classLocal)));
            } else if (callKind == Kind.ConstructorNewInstance && ie.getMethodRef().getSignature().equals("<java.lang.reflect.Constructor: java.lang.Object newInstance(java.lang.Object[])>")) {
                found = true;
                Local constrLocal = (Local) ((InstanceInvokeExpr) ie).getBase();
                newUnits.add(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(Scene.v().getMethod("<soot.rtlib.tamiflex.ReflectiveCalls: void knownConstructorNewInstance(int,java.lang.reflect.Constructor)>").makeRef(), IntConstant.v(callSiteId), constrLocal)));
            } else if (callKind == Kind.MethodInvoke && ie.getMethodRef().getSignature().equals("<java.lang.reflect.Method: java.lang.Object invoke(java.lang.Object,java.lang.Object[])>")) {
                found = true;
                Local methodLocal = (Local) ((InstanceInvokeExpr) ie).getBase();
                Value recv = ie.getArg(0);
                newUnits.add(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(Scene.v().getMethod("<soot.rtlib.tamiflex.ReflectiveCalls: void knownMethodInvoke(int,java.lang.Object,java.lang.reflect.Method)>").makeRef(), IntConstant.v(callSiteId), recv, methodLocal)));
            } else if (callKind == Kind.FieldSet) {
                SootMethod sootMethod = ie.getMethodRef().resolve();
                if (sootMethod.getDeclaringClass().getName().equals("java.lang.reflect.Field") && fieldSets.contains(sootMethod.getName())) {
                    found = true;
                    // assign
                    fieldSetGetType = sootMethod.getParameterType(1);
                    // type
                    // of
                    // 2nd
                    // parameter
                    // (1st
                    // is
                    // receiver
                    // object)
                    Value recv = ie.getArg(0);
                    Value field = ((InstanceInvokeExpr) ie).getBase();
                    newUnits.add(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(Scene.v().getMethod("<soot.rtlib.tamiflex.ReflectiveCalls: void knownFieldSet(int,java.lang.Object,java.lang.reflect.Field)>").makeRef(), IntConstant.v(callSiteId), recv, field)));
                }
            } else if (callKind == Kind.FieldGet) {
                SootMethod sootMethod = ie.getMethodRef().resolve();
                if (sootMethod.getDeclaringClass().getName().equals("java.lang.reflect.Field") && fieldGets.contains(sootMethod.getName())) {
                    found = true;
                    // assign
                    fieldSetGetType = sootMethod.getReturnType();
                    // return
                    // type
                    // of
                    // get
                    Value recv = ie.getArg(0);
                    Value field = ((InstanceInvokeExpr) ie).getBase();
                    newUnits.add(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(Scene.v().getMethod("<soot.rtlib.tamiflex.ReflectiveCalls: void knownFieldSet(int,java.lang.Object,java.lang.reflect.Field)>").makeRef(), IntConstant.v(callSiteId), recv, field)));
                }
            }
            if (!found)
                continue;
            NopStmt endLabel = Jimple.v().newNopStmt();
            // for all recorded targets
            for (String target : targets) {
                NopStmt jumpTarget = Jimple.v().newNopStmt();
                // boolean predLocal = Opaque.getFalse();
                Local predLocal = localGen.generateLocal(BooleanType.v());
                StaticInvokeExpr staticInvokeExpr = Jimple.v().newStaticInvokeExpr(UNINTERPRETED_METHOD);
                newUnits.add(Jimple.v().newAssignStmt(predLocal, staticInvokeExpr));
                // if predLocal == 0 goto <original reflective call>
                newUnits.add(Jimple.v().newIfStmt(Jimple.v().newEqExpr(IntConstant.v(0), predLocal), jumpTarget));
                SootMethod newMethod = createNewMethod(callKind, target, fieldSetGetType);
                List<Value> args = new LinkedList<Value>();
                switch(callKind) {
                    case ClassForName:
                    case ClassNewInstance:
                        // no arguments
                        break;
                    case ConstructorNewInstance:
                        // add Object[] argument
                        args.add((Value) ie.getArgs().get(0));
                        break;
                    case MethodInvoke:
                        // add Object argument
                        args.add((Value) ie.getArgs().get(0));
                        // add Object[] argument
                        args.add((Value) ie.getArgs().get(1));
                        break;
                    case FieldSet:
                        // add Object argument
                        args.add((Value) ie.getArgs().get(0));
                        // add value argument
                        args.add((Value) ie.getArgs().get(1));
                        break;
                    case FieldGet:
                        // add Object argument
                        args.add((Value) ie.getArgs().get(0));
                        break;
                    default:
                        throw new IllegalStateException();
                }
                StaticInvokeExpr methodInvokeExpr = Jimple.v().newStaticInvokeExpr(newMethod.makeRef(), args);
                Local retLocal = localGen.generateLocal(newMethod.getReturnType());
                newUnits.add(Jimple.v().newAssignStmt(retLocal, methodInvokeExpr));
                if (s instanceof AssignStmt) {
                    AssignStmt assignStmt = (AssignStmt) s;
                    Value leftOp = assignStmt.getLeftOp();
                    AssignStmt newAssignStmt = Jimple.v().newAssignStmt(leftOp, retLocal);
                    newUnits.add(newAssignStmt);
                }
                GotoStmt gotoStmt = Jimple.v().newGotoStmt(endLabel);
                newUnits.add(gotoStmt);
                newUnits.add(jumpTarget);
            }
            Unit end = newUnits.getLast();
            units.insertAfter(newUnits, s);
            units.remove(s);
            units.insertAfter(s, end);
            units.insertAfter(endLabel, s);
        }
    }
    callSiteId++;
}
Also used : LocalGenerator(soot.javaToJimple.LocalGenerator) HashChain(soot.util.HashChain) AssignStmt(soot.jimple.AssignStmt) Local(soot.Local) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) Unit(soot.Unit) LinkedList(java.util.LinkedList) InvokeStmt(soot.jimple.InvokeStmt) NopStmt(soot.jimple.NopStmt) GotoStmt(soot.jimple.GotoStmt) AssignStmt(soot.jimple.AssignStmt) Stmt(soot.jimple.Stmt) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) RefType(soot.RefType) BooleanType(soot.BooleanType) Type(soot.Type) RefLikeType(soot.RefLikeType) ArrayType(soot.ArrayType) PrimType(soot.PrimType) VoidType(soot.VoidType) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) InterfaceInvokeExpr(soot.jimple.InterfaceInvokeExpr) VirtualInvokeExpr(soot.jimple.VirtualInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) NopStmt(soot.jimple.NopStmt) GotoStmt(soot.jimple.GotoStmt) Value(soot.Value) SootMethod(soot.SootMethod) Body(soot.Body) JimpleBody(soot.jimple.JimpleBody)

Example 45 with Body

use of soot.Body in project soot by Sable.

the class ReflectiveCallsInliner method internalTransform.

@Override
protected void internalTransform(String phaseName, @SuppressWarnings("rawtypes") Map options) {
    if (!initialized) {
        CGOptions cgOptions = new CGOptions(PhaseOptions.v().getPhaseOptions("cg"));
        String logFilePath = cgOptions.reflection_log();
        RTI = new ReflectionTraceInfo(logFilePath);
        Scene.v().getSootClass(SootSig.class.getName()).setApplicationClass();
        Scene.v().getSootClass(UnexpectedReflectiveCall.class.getName()).setApplicationClass();
        Scene.v().getSootClass(IUnexpectedReflectiveCallHandler.class.getName()).setApplicationClass();
        Scene.v().getSootClass(DefaultHandler.class.getName()).setApplicationClass();
        Scene.v().getSootClass(OpaquePredicate.class.getName()).setApplicationClass();
        Scene.v().getSootClass(ReflectiveCalls.class.getName()).setApplicationClass();
        reflectiveCallsClass = new SootClass("soot.rtlib.tamiflex.ReflectiveCallsWrapper", Modifier.PUBLIC);
        Scene.v().addClass(reflectiveCallsClass);
        reflectiveCallsClass.setApplicationClass();
        UNINTERPRETED_METHOD = Scene.v().makeMethodRef(Scene.v().getSootClass("soot.rtlib.tamiflex.OpaquePredicate"), "getFalse", Collections.<Type>emptyList(), BooleanType.v(), true);
        if (useCaching)
            addCaching();
        initializeReflectiveCallsTable();
        callSiteId = 0;
        callNum = 0;
        initialized = true;
    }
    for (SootMethod m : RTI.methodsContainingReflectiveCalls()) {
        m.retrieveActiveBody();
        Body b = m.getActiveBody();
        {
            Set<String> classForNameClassNames = RTI.classForNameClassNames(m);
            if (!classForNameClassNames.isEmpty()) {
                inlineRelectiveCalls(m, classForNameClassNames, ReflectionTraceInfo.Kind.ClassForName);
                if (Options.v().validate())
                    b.validate();
            }
        }
        {
            Set<String> classNewInstanceClassNames = RTI.classNewInstanceClassNames(m);
            if (!classNewInstanceClassNames.isEmpty()) {
                inlineRelectiveCalls(m, classNewInstanceClassNames, ReflectionTraceInfo.Kind.ClassNewInstance);
                if (Options.v().validate())
                    b.validate();
            }
        }
        {
            Set<String> constructorNewInstanceSignatures = RTI.constructorNewInstanceSignatures(m);
            if (!constructorNewInstanceSignatures.isEmpty()) {
                inlineRelectiveCalls(m, constructorNewInstanceSignatures, ReflectionTraceInfo.Kind.ConstructorNewInstance);
                if (Options.v().validate())
                    b.validate();
            }
        }
        {
            Set<String> methodInvokeSignatures = RTI.methodInvokeSignatures(m);
            if (!methodInvokeSignatures.isEmpty()) {
                inlineRelectiveCalls(m, methodInvokeSignatures, ReflectionTraceInfo.Kind.MethodInvoke);
                if (Options.v().validate())
                    b.validate();
            }
        }
        {
            Set<String> fieldSetSignatures = RTI.fieldSetSignatures(m);
            if (!fieldSetSignatures.isEmpty()) {
                inlineRelectiveCalls(m, fieldSetSignatures, ReflectionTraceInfo.Kind.FieldSet);
                if (Options.v().validate())
                    b.validate();
            }
        }
        {
            Set<String> fieldGetSignatures = RTI.fieldGetSignatures(m);
            if (!fieldGetSignatures.isEmpty()) {
                inlineRelectiveCalls(m, fieldGetSignatures, ReflectionTraceInfo.Kind.FieldGet);
                if (Options.v().validate())
                    b.validate();
            }
        }
        // clean up after us
        cleanup(b);
    }
}
Also used : CGOptions(soot.options.CGOptions) RefType(soot.RefType) BooleanType(soot.BooleanType) Type(soot.Type) RefLikeType(soot.RefLikeType) ArrayType(soot.ArrayType) PrimType(soot.PrimType) VoidType(soot.VoidType) Set(java.util.Set) SootMethod(soot.SootMethod) SootClass(soot.SootClass) Body(soot.Body) JimpleBody(soot.jimple.JimpleBody)

Aggregations

Body (soot.Body)57 Unit (soot.Unit)37 SootMethod (soot.SootMethod)32 Local (soot.Local)20 SootClass (soot.SootClass)19 Value (soot.Value)15 InvokeExpr (soot.jimple.InvokeExpr)14 StaticInvokeExpr (soot.jimple.StaticInvokeExpr)13 Type (soot.Type)12 Stmt (soot.jimple.Stmt)12 InstanceInvokeExpr (soot.jimple.InstanceInvokeExpr)11 JimpleBody (soot.jimple.JimpleBody)11 SpecialInvokeExpr (soot.jimple.SpecialInvokeExpr)11 RefType (soot.RefType)10 VoidType (soot.VoidType)10 VirtualInvokeExpr (soot.jimple.VirtualInvokeExpr)10 LinkedList (java.util.LinkedList)9 SootMethodRef (soot.SootMethodRef)9 ArrayList (java.util.ArrayList)8 PrimType (soot.PrimType)8