Search in sources :

Example 1 with HashChain

use of soot.util.HashChain 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 2 with HashChain

use of soot.util.HashChain in project soot by Sable.

the class ReflectiveCallsInliner method addCaching.

private void addCaching(Kind kind) {
    SootClass c;
    String methodName;
    switch(kind) {
        case ClassNewInstance:
            c = Scene.v().getSootClass("java.lang.Class");
            methodName = "knownClassNewInstance";
            break;
        case ConstructorNewInstance:
            c = Scene.v().getSootClass("java.lang.reflect.Constructor");
            methodName = "knownConstructorNewInstance";
            break;
        case MethodInvoke:
            c = Scene.v().getSootClass("java.lang.reflect.Method");
            methodName = "knownMethodInvoke";
            break;
        case ClassForName:
            // to the String argument
            return;
        default:
            throw new IllegalStateException("unknown kind: " + kind);
    }
    SootClass reflCallsClass = Scene.v().getSootClass("soot.rtlib.tamiflex.ReflectiveCalls");
    SootMethod m = reflCallsClass.getMethodByName(methodName);
    JimpleBody body = (JimpleBody) m.retrieveActiveBody();
    LocalGenerator localGen = new LocalGenerator(body);
    Unit firstStmt = body.getFirstNonIdentityStmt();
    firstStmt = body.getUnits().getPredOf(firstStmt);
    Stmt jumpTarget = Jimple.v().newNopStmt();
    Chain<Unit> newUnits = new HashChain<Unit>();
    // alreadyCheckedLocal = m.alreadyChecked
    InstanceFieldRef fieldRef = Jimple.v().newInstanceFieldRef(body.getParameterLocal(m.getParameterCount() - 1), Scene.v().makeFieldRef(c, ALREADY_CHECKED_FIELDNAME, BooleanType.v(), false));
    Local alreadyCheckedLocal = localGen.generateLocal(BooleanType.v());
    newUnits.add(Jimple.v().newAssignStmt(alreadyCheckedLocal, fieldRef));
    // if(!alreadyChecked) goto jumpTarget
    newUnits.add(Jimple.v().newIfStmt(Jimple.v().newEqExpr(alreadyCheckedLocal, IntConstant.v(0)), jumpTarget));
    // return
    newUnits.add(Jimple.v().newReturnVoidStmt());
    // jumpTarget: nop
    newUnits.add(jumpTarget);
    // m.alreadyChecked = true
    InstanceFieldRef fieldRef2 = Jimple.v().newInstanceFieldRef(body.getParameterLocal(m.getParameterCount() - 1), Scene.v().makeFieldRef(c, ALREADY_CHECKED_FIELDNAME, BooleanType.v(), false));
    newUnits.add(Jimple.v().newAssignStmt(fieldRef2, IntConstant.v(1)));
    body.getUnits().insertAfter(newUnits, firstStmt);
    if (Options.v().validate())
        body.validate();
}
Also used : LocalGenerator(soot.javaToJimple.LocalGenerator) HashChain(soot.util.HashChain) InstanceFieldRef(soot.jimple.InstanceFieldRef) SootMethod(soot.SootMethod) Local(soot.Local) SootClass(soot.SootClass) Unit(soot.Unit) JimpleBody(soot.jimple.JimpleBody) InvokeStmt(soot.jimple.InvokeStmt) NopStmt(soot.jimple.NopStmt) GotoStmt(soot.jimple.GotoStmt) AssignStmt(soot.jimple.AssignStmt) Stmt(soot.jimple.Stmt)

Example 3 with HashChain

use of soot.util.HashChain 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)

Aggregations

Local (soot.Local)3 SootMethod (soot.SootMethod)3 Unit (soot.Unit)3 LocalGenerator (soot.javaToJimple.LocalGenerator)3 JimpleBody (soot.jimple.JimpleBody)3 HashChain (soot.util.HashChain)3 Body (soot.Body)2 SootClass (soot.SootClass)2 AssignStmt (soot.jimple.AssignStmt)2 GotoStmt (soot.jimple.GotoStmt)2 InterfaceInvokeExpr (soot.jimple.InterfaceInvokeExpr)2 InvokeStmt (soot.jimple.InvokeStmt)2 NopStmt (soot.jimple.NopStmt)2 Stmt (soot.jimple.Stmt)2 LinkedList (java.util.LinkedList)1 ArrayType (soot.ArrayType)1 BooleanType (soot.BooleanType)1 PrimType (soot.PrimType)1 RefLikeType (soot.RefLikeType)1 RefType (soot.RefType)1