Search in sources :

Example 91 with SootClass

use of soot.SootClass in project soot by Sable.

the class AccessManager method ensureAccess.

/**
 * Modifies code so that an access to <code>target</code> is legal from code
 * in <code>container</code>.
 *
 * The "accessors" option assumes suitable accessor methods will be created
 * after checking.
 */
public static boolean ensureAccess(SootMethod container, ClassMember target, String options) {
    boolean accessors = options.equals("accessors");
    boolean allowChanges = !(options.equals("none"));
    boolean safeChangesOnly = !(options.equals("unsafe"));
    SootClass targetClass = target.getDeclaringClass();
    if (!ensureAccess(container, targetClass, options))
        return false;
    if (isAccessLegal(container, target))
        return true;
    if (!allowChanges && !accessors)
        return false;
    if (target.getDeclaringClass().isApplicationClass()) {
        if (accessors)
            return true;
        if (safeChangesOnly)
            throw new RuntimeException("Not implemented yet!");
        target.setModifiers(target.getModifiers() | Modifier.PUBLIC);
        return true;
    } else
        return false;
}
Also used : SootClass(soot.SootClass)

Example 92 with SootClass

use of soot.SootClass in project soot by Sable.

the class AccessManager method createAccessorName.

/**
 * Creates a name for an accessor method.
 *
 * @param member
 * @param setter
 * @return
 */
public static String createAccessorName(ClassMember member, boolean setter) {
    SootClass target = member.getDeclaringClass();
    String name = "access$";
    if (member instanceof SootField) {
        SootField f = (SootField) member;
        if (setter) {
            name += "set$";
        } else {
            name += "get$";
        }
        name += f.getName();
    } else {
        SootMethod m = (SootMethod) member;
        name += m.getName() + "$";
        for (Iterator it = m.getParameterTypes().iterator(); it.hasNext(); ) {
            Type type = (Type) it.next();
            name += type.toString().replaceAll("\\.", "\\$\\$") + "$";
        }
    }
    return name;
}
Also used : Type(soot.Type) VoidType(soot.VoidType) Iterator(java.util.Iterator) SootMethod(soot.SootMethod) SootField(soot.SootField) SootClass(soot.SootClass)

Example 93 with SootClass

use of soot.SootClass in project soot by Sable.

the class AccessManager method createGetAccessor.

private static void createGetAccessor(SootMethod container, AssignStmt as, FieldRef ref) {
    java.util.List parameterTypes = new LinkedList();
    java.util.List<SootClass> thrownExceptions = new LinkedList<SootClass>();
    Body accessorBody = Jimple.v().newBody();
    soot.util.Chain accStmts = accessorBody.getUnits();
    LocalGenerator lg = new LocalGenerator(accessorBody);
    Body containerBody = container.getActiveBody();
    soot.util.Chain containerStmts = containerBody.getUnits();
    SootClass target = ref.getField().getDeclaringClass();
    SootMethod accessor;
    String name = createAccessorName(ref.getField(), false);
    accessor = target.getMethodByNameUnsafe(name);
    if (accessor == null) {
        Type returnType = ref.getField().getType();
        Local thisLocal = lg.generateLocal(target.getType());
        if (ref instanceof InstanceFieldRef) {
            parameterTypes.add(target.getType());
            accStmts.addFirst(Jimple.v().newIdentityStmt(thisLocal, Jimple.v().newParameterRef(target.getType(), 0)));
        }
        Local l = lg.generateLocal(ref.getField().getType());
        Value v;
        if (ref instanceof InstanceFieldRef) {
            v = Jimple.v().newInstanceFieldRef(thisLocal, ref.getFieldRef());
        } else {
            v = Jimple.v().newStaticFieldRef(ref.getFieldRef());
        }
        accStmts.add(Jimple.v().newAssignStmt(l, v));
        accStmts.add(Jimple.v().newReturnStmt(l));
        accessor = Scene.v().makeSootMethod(name, parameterTypes, returnType, Modifier.PUBLIC | Modifier.STATIC, thrownExceptions);
        accessorBody.setMethod(accessor);
        accessor.setActiveBody(accessorBody);
        target.addMethod(accessor);
    }
    java.util.List args = new LinkedList();
    if (ref instanceof InstanceFieldRef) {
        args.add(((InstanceFieldRef) ref).getBase());
    }
    InvokeExpr newExpr = Jimple.v().newStaticInvokeExpr(accessor.makeRef(), args);
    as.setRightOp(newExpr);
}
Also used : LocalGenerator(soot.javaToJimple.LocalGenerator) Local(soot.Local) SootClass(soot.SootClass) LinkedList(java.util.LinkedList) Type(soot.Type) VoidType(soot.VoidType) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) VirtualInvokeExpr(soot.jimple.VirtualInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) InstanceFieldRef(soot.jimple.InstanceFieldRef) Value(soot.Value) SootMethod(soot.SootMethod) Body(soot.Body)

Example 94 with SootClass

use of soot.SootClass in project soot by Sable.

the class StaticMethodBinder method internalTransform.

protected void internalTransform(String phaseName, Map opts) {
    Filter instanceInvokesFilter = new Filter(new InstanceInvokeEdgesPred());
    SMBOptions options = new SMBOptions(opts);
    String modifierOptions = PhaseOptions.getString(opts, "allowed-modifier-changes");
    HashMap instanceToStaticMap = new HashMap();
    CallGraph cg = Scene.v().getCallGraph();
    Hierarchy hierarchy = Scene.v().getActiveHierarchy();
    Iterator classesIt = Scene.v().getApplicationClasses().iterator();
    while (classesIt.hasNext()) {
        SootClass c = (SootClass) classesIt.next();
        LinkedList methodsList = new LinkedList();
        for (Iterator it = c.methodIterator(); it.hasNext(); ) {
            methodsList.add(it.next());
        }
        while (!methodsList.isEmpty()) {
            SootMethod container = (SootMethod) methodsList.removeFirst();
            if (!container.isConcrete())
                continue;
            if (!instanceInvokesFilter.wrap(cg.edgesOutOf(container)).hasNext())
                continue;
            JimpleBody b = (JimpleBody) container.getActiveBody();
            List<Unit> unitList = new ArrayList<Unit>();
            unitList.addAll(b.getUnits());
            Iterator<Unit> unitIt = unitList.iterator();
            while (unitIt.hasNext()) {
                Stmt s = (Stmt) unitIt.next();
                if (!s.containsInvokeExpr())
                    continue;
                InvokeExpr ie = s.getInvokeExpr();
                if (ie instanceof StaticInvokeExpr || ie instanceof SpecialInvokeExpr)
                    continue;
                Iterator targets = new Targets(instanceInvokesFilter.wrap(cg.edgesOutOf(s)));
                if (!targets.hasNext())
                    continue;
                SootMethod target = (SootMethod) targets.next();
                if (targets.hasNext())
                    continue;
                if (!AccessManager.ensureAccess(container, target, modifierOptions))
                    continue;
                if (!target.getDeclaringClass().isApplicationClass() || !target.isConcrete())
                    continue;
                // Don't modify java.lang.Object
                if (target.getDeclaringClass() == Scene.v().getSootClass("java.lang.Object"))
                    continue;
                if (!instanceToStaticMap.containsKey(target)) {
                    List newParameterTypes = new ArrayList();
                    newParameterTypes.add(RefType.v(target.getDeclaringClass().getName()));
                    newParameterTypes.addAll(target.getParameterTypes());
                    // Check for signature conflicts.
                    String newName = target.getName() + "_static";
                    while (target.getDeclaringClass().declaresMethod(newName, newParameterTypes, target.getReturnType())) newName = newName + "_static";
                    SootMethod ct = Scene.v().makeSootMethod(newName, newParameterTypes, target.getReturnType(), target.getModifiers() | Modifier.STATIC, target.getExceptions());
                    target.getDeclaringClass().addMethod(ct);
                    methodsList.addLast(ct);
                    ct.setActiveBody((Body) target.getActiveBody().clone());
                    // Make the invoke graph take into account the
                    // newly-cloned body.
                    {
                        Iterator oldUnits = target.getActiveBody().getUnits().iterator();
                        Iterator newUnits = ct.getActiveBody().getUnits().iterator();
                        while (newUnits.hasNext()) {
                            Stmt oldStmt, newStmt;
                            oldStmt = (Stmt) oldUnits.next();
                            newStmt = (Stmt) newUnits.next();
                            Iterator edges = cg.edgesOutOf(oldStmt);
                            while (edges.hasNext()) {
                                Edge e = (Edge) edges.next();
                                cg.addEdge(new Edge(ct, newStmt, e.tgt(), e.kind()));
                                cg.removeEdge(e);
                            }
                        }
                    }
                    // Shift the parameter list to apply to the new this
                    // parameter.
                    // If the method uses this, then we replace
                    // the r0 := @this with r0 := @parameter0 & shift.
                    // Otherwise, just zap the r0 := @this.
                    {
                        Body newBody = ct.getActiveBody();
                        Chain units = newBody.getUnits();
                        Iterator unitsIt = newBody.getUnits().snapshotIterator();
                        while (unitsIt.hasNext()) {
                            Stmt st = (Stmt) unitsIt.next();
                            if (st instanceof IdentityStmt) {
                                IdentityStmt is = (IdentityStmt) st;
                                if (is.getRightOp() instanceof ThisRef) {
                                    units.swapWith(st, Jimple.v().newIdentityStmt(is.getLeftOp(), Jimple.v().newParameterRef(is.getRightOp().getType(), 0)));
                                } else {
                                    if (is.getRightOp() instanceof ParameterRef) {
                                        ParameterRef ro = (ParameterRef) is.getRightOp();
                                        ro.setIndex(ro.getIndex() + 1);
                                    }
                                }
                            }
                        }
                    }
                    instanceToStaticMap.put(target, ct);
                }
                SootMethod clonedTarget = (SootMethod) instanceToStaticMap.get(target);
                Value thisToAdd = ((InstanceInvokeExpr) ie).getBase();
                // Insert casts to please the verifier.
                if (options.insert_redundant_casts()) {
                    // The verifier will complain if targetUsesThis, and:
                    // the argument passed to the method is not the same
                    // type.
                    // For instance, Bottle.price_static takes a cost.
                    // Cost is an interface implemented by Bottle.
                    SootClass localType, parameterType;
                    localType = ((RefType) ((InstanceInvokeExpr) ie).getBase().getType()).getSootClass();
                    parameterType = target.getDeclaringClass();
                    if (localType.isInterface() || hierarchy.isClassSuperclassOf(localType, parameterType)) {
                        Local castee = Jimple.v().newLocal("__castee", parameterType.getType());
                        b.getLocals().add(castee);
                        b.getUnits().insertBefore(Jimple.v().newAssignStmt(castee, Jimple.v().newCastExpr(((InstanceInvokeExpr) ie).getBase(), parameterType.getType())), s);
                        thisToAdd = castee;
                    }
                }
                // Now rebind the method call & fix the invoke graph.
                {
                    List newArgs = new ArrayList();
                    newArgs.add(thisToAdd);
                    newArgs.addAll(ie.getArgs());
                    StaticInvokeExpr sie = Jimple.v().newStaticInvokeExpr(clonedTarget.makeRef(), newArgs);
                    ValueBox ieBox = s.getInvokeExprBox();
                    ieBox.setValue(sie);
                    cg.addEdge(new Edge(container, s, clonedTarget));
                }
                // (If enabled), add a null pointer check.
                if (options.insert_null_checks()) {
                    boolean caught = TrapManager.isExceptionCaughtAt(Scene.v().getSootClass("java.lang.NullPointerException"), s, b);
                    /* Ah ha. Caught again! */
                    if (caught) {
                        /*
							 * In this case, we don't use throwPoint; instead,
							 * put the code right there.
							 */
                        Stmt insertee = Jimple.v().newIfStmt(Jimple.v().newNeExpr(((InstanceInvokeExpr) ie).getBase(), NullConstant.v()), s);
                        b.getUnits().insertBefore(insertee, s);
                        // This sucks (but less than before).
                        ((IfStmt) insertee).setTarget(s);
                        ThrowManager.addThrowAfter(b, insertee);
                    } else {
                        Stmt throwPoint = ThrowManager.getNullPointerExceptionThrower(b);
                        b.getUnits().insertBefore(Jimple.v().newIfStmt(Jimple.v().newEqExpr(((InstanceInvokeExpr) ie).getBase(), NullConstant.v()), throwPoint), s);
                    }
                }
                // Add synchronizing stuff.
                {
                    if (target.isSynchronized()) {
                        clonedTarget.setModifiers(clonedTarget.getModifiers() & ~Modifier.SYNCHRONIZED);
                        SynchronizerManager.v().synchronizeStmtOn(s, b, (Local) ((InstanceInvokeExpr) ie).getBase());
                    }
                }
                // Resolve name collisions.
                LocalNameStandardizer.v().transform(b, phaseName + ".lns");
            }
        }
    }
}
Also used : Chain(soot.util.Chain) HashMap(java.util.HashMap) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) ArrayList(java.util.ArrayList) Unit(soot.Unit) IfStmt(soot.jimple.IfStmt) IdentityStmt(soot.jimple.IdentityStmt) Stmt(soot.jimple.Stmt) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) Hierarchy(soot.Hierarchy) InstanceInvokeEdgesPred(soot.jimple.toolkits.callgraph.InstanceInvokeEdgesPred) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) Iterator(java.util.Iterator) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) JimpleBody(soot.jimple.JimpleBody) Body(soot.Body) JimpleBody(soot.jimple.JimpleBody) IdentityStmt(soot.jimple.IdentityStmt) SMBOptions(soot.options.SMBOptions) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) Local(soot.Local) Targets(soot.jimple.toolkits.callgraph.Targets) SootClass(soot.SootClass) LinkedList(java.util.LinkedList) ParameterRef(soot.jimple.ParameterRef) IfStmt(soot.jimple.IfStmt) Filter(soot.jimple.toolkits.callgraph.Filter) CallGraph(soot.jimple.toolkits.callgraph.CallGraph) ThisRef(soot.jimple.ThisRef) ValueBox(soot.ValueBox) Value(soot.Value) SootMethod(soot.SootMethod) Edge(soot.jimple.toolkits.callgraph.Edge)

Example 95 with SootClass

use of soot.SootClass in project soot by Sable.

the class RenameDuplicatedClasses method internalTransform.

@Override
protected void internalTransform(String phaseName, Map<String, String> options) {
    // If the file system is case sensitive, no need to rename the classes
    if (isFileSystemCaseSensitive()) {
        return;
    }
    String fixedClassNamesStr = PhaseOptions.getString(options, "fixedClassNames");
    String[] classNames = fixedClassNamesStr.split(FIXED_CLASS_NAME_SPERATOR);
    List<String> fixedClassNames = Arrays.asList(classNames);
    duplicatedCheck(fixedClassNames);
    if (Options.v().verbose()) {
        logger.debug("The fixed class names are: " + fixedClassNames);
    }
    Chain<SootClass> sootClasses = Scene.v().getClasses();
    Map<String, String> lowerCaseClassNameToReal = new HashMap<String, String>();
    int count = 0;
    for (Iterator<SootClass> iter = sootClasses.snapshotIterator(); iter.hasNext(); ) {
        SootClass sootClass = iter.next();
        String className = sootClass.getName();
        if (lowerCaseClassNameToReal.containsKey(className.toLowerCase())) {
            if (fixedClassNames.contains(className)) {
                sootClass = Scene.v().getSootClass(lowerCaseClassNameToReal.get(className.toLowerCase()));
                className = lowerCaseClassNameToReal.get(className.toLowerCase());
            }
            String newClassName = className + (count++);
            sootClass.rename(newClassName);
            // if(Options.v().verbose())
            // {
            logger.debug("Rename duplicated class " + className + " to class " + newClassName);
        // }
        } else {
            lowerCaseClassNameToReal.put(className.toLowerCase(), className);
        }
    }
}
Also used : HashMap(java.util.HashMap) SootClass(soot.SootClass)

Aggregations

SootClass (soot.SootClass)194 SootMethod (soot.SootMethod)99 RefType (soot.RefType)69 ArrayList (java.util.ArrayList)60 Type (soot.Type)57 VoidType (soot.VoidType)33 ArrayType (soot.ArrayType)32 Iterator (java.util.Iterator)29 BooleanType (soot.BooleanType)29 DoubleType (soot.DoubleType)29 LongType (soot.LongType)29 Value (soot.Value)29 FloatType (soot.FloatType)28 Local (soot.Local)27 SootField (soot.SootField)27 List (java.util.List)26 CharType (soot.CharType)26 IntType (soot.IntType)26 ByteType (soot.ByteType)25 PrimType (soot.PrimType)23