Search in sources :

Example 6 with LocalGenerator

use of soot.javaToJimple.LocalGenerator 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 7 with LocalGenerator

use of soot.javaToJimple.LocalGenerator 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 8 with LocalGenerator

use of soot.javaToJimple.LocalGenerator 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 9 with LocalGenerator

use of soot.javaToJimple.LocalGenerator in project soot by Sable.

the class DexTrapStackFixer method internalTransform.

@Override
protected void internalTransform(Body b, String phaseName, Map<String, String> options) {
    for (Trap t : b.getTraps()) {
        // If the first statement already catches the exception, we're fine
        if (isCaughtExceptionRef(t.getHandlerUnit()))
            continue;
        // Add the exception reference
        Local l = new LocalGenerator(b).generateLocal(t.getException().getType());
        Stmt caughtStmt = Jimple.v().newIdentityStmt(l, Jimple.v().newCaughtExceptionRef());
        b.getUnits().add(caughtStmt);
        b.getUnits().add(Jimple.v().newGotoStmt(t.getHandlerUnit()));
        t.setHandlerUnit(caughtStmt);
    }
}
Also used : LocalGenerator(soot.javaToJimple.LocalGenerator) Local(soot.Local) Trap(soot.Trap) IdentityStmt(soot.jimple.IdentityStmt) Stmt(soot.jimple.Stmt)

Example 10 with LocalGenerator

use of soot.javaToJimple.LocalGenerator in project soot by Sable.

the class Util method emptyBody.

/**
 * Remove all statements except from IdentityStatements for parameters.
 * Return default value (null or zero or nothing depending on the return
 * type).
 *
 * @param jBody
 */
public static void emptyBody(Body jBody) {
    // identity statements
    List<Unit> idStmts = new ArrayList<Unit>();
    List<Local> idLocals = new ArrayList<Local>();
    for (Unit u : jBody.getUnits()) {
        if (u instanceof IdentityStmt) {
            IdentityStmt i = (IdentityStmt) u;
            if (i.getRightOp() instanceof ParameterRef || i.getRightOp() instanceof ThisRef) {
                idStmts.add(u);
                idLocals.add((Local) i.getLeftOp());
            }
        }
    }
    jBody.getUnits().clear();
    jBody.getLocals().clear();
    jBody.getTraps().clear();
    final LocalGenerator lg = new LocalGenerator(jBody);
    for (Unit u : idStmts) jBody.getUnits().add(u);
    for (Local l : idLocals) jBody.getLocals().add(l);
    Type rType = jBody.getMethod().getReturnType();
    jBody.getUnits().add(Jimple.v().newNopStmt());
    if (rType instanceof VoidType) {
        jBody.getUnits().add(Jimple.v().newReturnVoidStmt());
    } else {
        Type t = jBody.getMethod().getReturnType();
        Local l = lg.generateLocal(t);
        AssignStmt ass = null;
        if (t instanceof RefType || t instanceof ArrayType) {
            ass = Jimple.v().newAssignStmt(l, NullConstant.v());
        } else if (t instanceof LongType) {
            ass = Jimple.v().newAssignStmt(l, LongConstant.v(0));
        } else if (t instanceof FloatType) {
            ass = Jimple.v().newAssignStmt(l, FloatConstant.v(0.0f));
        } else if (t instanceof IntType) {
            ass = Jimple.v().newAssignStmt(l, IntConstant.v(0));
        } else if (t instanceof DoubleType) {
            ass = Jimple.v().newAssignStmt(l, DoubleConstant.v(0));
        } else if (t instanceof BooleanType || t instanceof ByteType || t instanceof CharType || t instanceof ShortType) {
            ass = Jimple.v().newAssignStmt(l, IntConstant.v(0));
        } else {
            throw new RuntimeException("error: return type unknown: " + t + " class: " + t.getClass());
        }
        jBody.getUnits().add(ass);
        jBody.getUnits().add(Jimple.v().newReturnStmt(l));
    }
}
Also used : VoidType(soot.VoidType) LocalGenerator(soot.javaToJimple.LocalGenerator) LongType(soot.LongType) AssignStmt(soot.jimple.AssignStmt) ShortType(soot.ShortType) ArrayList(java.util.ArrayList) BooleanType(soot.BooleanType) Local(soot.Local) ByteType(soot.ByteType) Unit(soot.Unit) FloatType(soot.FloatType) IntType(soot.IntType) RefType(soot.RefType) ArrayType(soot.ArrayType) RefType(soot.RefType) DoubleType(soot.DoubleType) FloatType(soot.FloatType) IntType(soot.IntType) ShortType(soot.ShortType) CharType(soot.CharType) LongType(soot.LongType) BooleanType(soot.BooleanType) ByteType(soot.ByteType) ArrayType(soot.ArrayType) Type(soot.Type) VoidType(soot.VoidType) ParameterRef(soot.jimple.ParameterRef) ThisRef(soot.jimple.ThisRef) DoubleType(soot.DoubleType) CharType(soot.CharType) IdentityStmt(soot.jimple.IdentityStmt)

Aggregations

LocalGenerator (soot.javaToJimple.LocalGenerator)10 Local (soot.Local)9 SootMethod (soot.SootMethod)7 AssignStmt (soot.jimple.AssignStmt)7 Body (soot.Body)6 SootClass (soot.SootClass)6 Type (soot.Type)6 VoidType (soot.VoidType)6 SpecialInvokeExpr (soot.jimple.SpecialInvokeExpr)6 LinkedList (java.util.LinkedList)5 Unit (soot.Unit)5 InstanceInvokeExpr (soot.jimple.InstanceInvokeExpr)5 InvokeExpr (soot.jimple.InvokeExpr)5 JimpleBody (soot.jimple.JimpleBody)5 StaticInvokeExpr (soot.jimple.StaticInvokeExpr)5 Stmt (soot.jimple.Stmt)5 VirtualInvokeExpr (soot.jimple.VirtualInvokeExpr)5 InstanceFieldRef (soot.jimple.InstanceFieldRef)4 InvokeStmt (soot.jimple.InvokeStmt)4 ArrayType (soot.ArrayType)3