Search in sources :

Example 51 with ValueBox

use of soot.ValueBox in project soot by Sable.

the class DexDefUseAnalysis method initialize.

protected void initialize() {
    int lastLocalNumber = 0;
    for (Local l : body.getLocals()) {
        localToNumber.put(l, lastLocalNumber++);
    }
    localToDefsBits = new BitSet[body.getLocalCount()];
    localToUsesBits = new BitSet[body.getLocalCount()];
    unitList = new ArrayList<>(body.getUnits());
    for (int i = 0; i < unitList.size(); i++) {
        Unit u = unitList.get(i);
        // Record the definitions
        if (u instanceof DefinitionStmt) {
            Value val = ((DefinitionStmt) u).getLeftOp();
            if (val instanceof Local) {
                final int localIdx = localToNumber.get(val);
                BitSet bs = localToDefsBits[localIdx];
                if (bs == null) {
                    bs = new BitSet();
                    localToDefsBits[localIdx] = bs;
                }
                bs.set(i);
            }
        }
        // Record the uses
        for (ValueBox vb : u.getUseBoxes()) {
            Value val = vb.getValue();
            if (val instanceof Local) {
                final int localIdx = localToNumber.get(val);
                BitSet bs = localToUsesBits[localIdx];
                if (bs == null) {
                    bs = new BitSet();
                    localToUsesBits[localIdx] = bs;
                }
                bs.set(i);
            }
        }
    }
}
Also used : ValueBox(soot.ValueBox) Value(soot.Value) BitSet(java.util.BitSet) Local(soot.Local) Unit(soot.Unit) DefinitionStmt(soot.jimple.DefinitionStmt)

Example 52 with ValueBox

use of soot.ValueBox in project soot by Sable.

the class ShortcutIfGenerator method inASTStatementSequenceNode.

public void inASTStatementSequenceNode(ASTStatementSequenceNode node) {
    for (AugmentedStmt as : node.getStatements()) {
        Stmt s = as.get_Stmt();
        if (!(s instanceof DefinitionStmt))
            continue;
        DefinitionStmt ds = (DefinitionStmt) s;
        ValueBox rightBox = ds.getRightOpBox();
        Value right = rightBox.getValue();
        /*
			 * Going to match int i = (int) z where z is a boolean
			 * or int i= z i.e. without the cast
			 */
        // right type should contain the expected type on the left
        // in the case of the cast this is the cast type else just get the left type
        Type rightType = null;
        ValueBox OpBox = null;
        if (right instanceof CastExpr) {
            rightType = ((CastExpr) right).getCastType();
            OpBox = ((CastExpr) right).getOpBox();
        } else {
            rightType = ds.getLeftOp().getType();
            OpBox = rightBox;
        }
        if (!(rightType instanceof IntType)) {
            continue;
        }
        Value Op = OpBox.getValue();
        if (!(Op.getType() instanceof BooleanType)) {
            continue;
        }
        // ready for the switch
        ImmediateBox trueBox = new ImmediateBox(IntConstant.v(1));
        ImmediateBox falseBox = new ImmediateBox(IntConstant.v(0));
        DShortcutIf shortcut = new DShortcutIf(OpBox, trueBox, falseBox);
        if (DEBUG)
            System.out.println("created: " + shortcut);
        rightBox.setValue(shortcut);
    }
}
Also used : IntType(soot.IntType) Type(soot.Type) BooleanType(soot.BooleanType) ImmediateBox(soot.jimple.internal.ImmediateBox) ValueBox(soot.ValueBox) DShortcutIf(soot.dava.internal.javaRep.DShortcutIf) Value(soot.Value) CastExpr(soot.jimple.CastExpr) BooleanType(soot.BooleanType) AugmentedStmt(soot.dava.internal.asg.AugmentedStmt) DefinitionStmt(soot.jimple.DefinitionStmt) Stmt(soot.jimple.Stmt) AugmentedStmt(soot.dava.internal.asg.AugmentedStmt) DefinitionStmt(soot.jimple.DefinitionStmt) IntType(soot.IntType)

Example 53 with ValueBox

use of soot.ValueBox in project soot by Sable.

the class BuildIntermediateAppClasses method internalTransform.

protected void internalTransform(String phaseName, Map<String, String> options) {
    if (output) {
        out.println("Building Intermediate Classes...");
    }
    BodyBuilder.retrieveAllBodies();
    // iterate through application classes, build intermediate classes
    Iterator<SootClass> it = Scene.v().getApplicationClasses().snapshotIterator();
    while (it.hasNext()) {
        List<SootMethod> initMethodsToRewrite = new ArrayList<>();
        Map<String, SootMethod> methodsToAdd = new HashMap<>();
        SootClass sc = it.next();
        SootClass originalSuperclass = sc.getSuperclass();
        if (output) {
            out.println("Processing " + sc.getName() + " with super " + originalSuperclass.getName());
        }
        Iterator<SootMethod> methodIterator = sc.methodIterator();
        while (methodIterator.hasNext()) {
            SootMethod method = methodIterator.next();
            if (!method.isConcrete()) {
                continue;
            }
            try {
                method.getActiveBody();
            } catch (Exception e) {
                if (method.retrieveActiveBody() == null)
                    throw new RuntimeException(method.getSignature() + " has no body. This was not expected dude.");
            }
            String subSig = method.getSubSignature();
            if (subSig.equals("void main(java.lang.String[])") && method.isPublic() && method.isStatic()) {
                // skip the main method - it needs to be named 'main'
                continue;
            } else if (subSig.indexOf("init>(") > 0) {
                if (subSig.startsWith("void <init>(")) {
                    initMethodsToRewrite.add(method);
                }
                // skip constructors, just add for rewriting at the end
                continue;
            } else {
                Scene.v().releaseActiveHierarchy();
                findAccessibleInSuperClassesBySubSig(sc, subSig).ifPresent(m -> methodsToAdd.put(subSig, m));
            }
        }
        if (methodsToAdd.size() > 0) {
            final String fullName = ClassRenamer.v().getNewName(ClassRenamer.getPackageName(sc.getName()), null);
            if (output) {
                out.println("\tBuilding " + fullName);
            }
            // make non-final soot class
            SootClass mediatingClass = new SootClass(fullName, sc.getModifiers() & (~Modifier.FINAL));
            Main.IntermediateAppClasses.add(mediatingClass);
            mediatingClass.setSuperclass(originalSuperclass);
            Scene.v().addClass(mediatingClass);
            mediatingClass.setApplicationClass();
            mediatingClass.setInScene(true);
            ThisRef thisRef = new ThisRef(mediatingClass.getType());
            for (String subSig : methodsToAdd.keySet()) {
                SootMethod originalSuperclassMethod = methodsToAdd.get(subSig);
                List<Type> paramTypes = originalSuperclassMethod.getParameterTypes();
                Type returnType = originalSuperclassMethod.getReturnType();
                List<SootClass> exceptions = originalSuperclassMethod.getExceptions();
                int modifiers = originalSuperclassMethod.getModifiers() & ~Modifier.ABSTRACT & ~Modifier.NATIVE;
                SootMethod newMethod;
                {
                    // build new junk method to call original method
                    String newMethodName = MethodRenamer.v().getNewName();
                    newMethod = Scene.v().makeSootMethod(newMethodName, paramTypes, returnType, modifiers, exceptions);
                    mediatingClass.addMethod(newMethod);
                    Body body = Jimple.v().newBody(newMethod);
                    newMethod.setActiveBody(body);
                    Chain<Local> locals = body.getLocals();
                    PatchingChain<Unit> units = body.getUnits();
                    BodyBuilder.buildThisLocal(units, thisRef, locals);
                    BodyBuilder.buildParameterLocals(units, locals, paramTypes);
                    if (returnType instanceof VoidType) {
                        units.add(Jimple.v().newReturnVoidStmt());
                    } else if (returnType instanceof PrimType) {
                        units.add(Jimple.v().newReturnStmt(IntConstant.v(0)));
                    } else {
                        units.add(Jimple.v().newReturnStmt(NullConstant.v()));
                    }
                    newmethods++;
                }
                // end build new junk method to call original method
                {
                    // build copy of old method
                    newMethod = Scene.v().makeSootMethod(originalSuperclassMethod.getName(), paramTypes, returnType, modifiers, exceptions);
                    mediatingClass.addMethod(newMethod);
                    Body body = Jimple.v().newBody(newMethod);
                    newMethod.setActiveBody(body);
                    Chain<Local> locals = body.getLocals();
                    PatchingChain<Unit> units = body.getUnits();
                    Local ths = BodyBuilder.buildThisLocal(units, thisRef, locals);
                    List<Local> args = BodyBuilder.buildParameterLocals(units, locals, paramTypes);
                    SootMethodRef superclassMethodRef = originalSuperclassMethod.makeRef();
                    if (returnType instanceof VoidType) {
                        units.add(Jimple.v().newInvokeStmt(Jimple.v().newSpecialInvokeExpr(ths, superclassMethodRef, args)));
                        units.add(Jimple.v().newReturnVoidStmt());
                    } else {
                        Local loc = Jimple.v().newLocal("retValue", returnType);
                        body.getLocals().add(loc);
                        units.add(Jimple.v().newAssignStmt(loc, Jimple.v().newSpecialInvokeExpr(ths, superclassMethodRef, args)));
                        units.add(Jimple.v().newReturnStmt(loc));
                    }
                    newmethods++;
                }
            // end build copy of old method
            }
            sc.setSuperclass(mediatingClass);
            // rewrite class init methods to call the proper superclass inits
            int i = initMethodsToRewrite.size();
            while (i-- > 0) {
                SootMethod im = initMethodsToRewrite.remove(i);
                Body b = im.getActiveBody();
                Local thisLocal = b.getThisLocal();
                Iterator<Unit> uIt = b.getUnits().snapshotIterator();
                while (uIt.hasNext()) {
                    for (ValueBox valueBox : uIt.next().getUseBoxes()) {
                        Value v = valueBox.getValue();
                        if (v instanceof SpecialInvokeExpr) {
                            SpecialInvokeExpr sie = (SpecialInvokeExpr) v;
                            SootMethodRef smr = sie.getMethodRef();
                            if (sie.getBase().equivTo(thisLocal) && smr.declaringClass().getName().equals(originalSuperclass.getName()) && smr.getSubSignature().getString().startsWith("void " + constructorName)) {
                                SootMethod newSuperInit;
                                if (!mediatingClass.declaresMethod(constructorName, smr.parameterTypes())) {
                                    List<Type> paramTypes = smr.parameterTypes();
                                    newSuperInit = Scene.v().makeSootMethod(constructorName, paramTypes, smr.returnType());
                                    mediatingClass.addMethod(newSuperInit);
                                    JimpleBody body = Jimple.v().newBody(newSuperInit);
                                    newSuperInit.setActiveBody(body);
                                    PatchingChain<Unit> initUnits = body.getUnits();
                                    Collection<Local> locals = body.getLocals();
                                    Local ths = BodyBuilder.buildThisLocal(initUnits, thisRef, locals);
                                    List<Local> args = BodyBuilder.buildParameterLocals(initUnits, locals, paramTypes);
                                    initUnits.add(Jimple.v().newInvokeStmt(Jimple.v().newSpecialInvokeExpr(ths, smr, args)));
                                    initUnits.add(Jimple.v().newReturnVoidStmt());
                                } else {
                                    newSuperInit = mediatingClass.getMethod(constructorName, smr.parameterTypes());
                                }
                                sie.setMethodRef(newSuperInit.makeRef());
                            }
                        }
                    }
                }
            }
        // end of rewrite class init methods to call the proper superclass inits
        }
    }
    newclasses = Main.IntermediateAppClasses.size();
    Scene.v().releaseActiveHierarchy();
    Scene.v().getActiveHierarchy();
    Scene.v().setFastHierarchy(new FastHierarchy());
}
Also used : Body(soot.Body) ThisRef(soot.jimple.ThisRef) PatchingChain(soot.PatchingChain) Main(soot.jbco.Main) BodyBuilder(soot.jbco.util.BodyBuilder) HashMap(java.util.HashMap) NullConstant(soot.jimple.NullConstant) FastHierarchy(soot.FastHierarchy) Modifier(soot.Modifier) SootMethodRef(soot.SootMethodRef) ArrayList(java.util.ArrayList) SootMethod(soot.SootMethod) IJbcoTransform(soot.jbco.IJbcoTransform) Chain(soot.util.Chain) Map(java.util.Map) Local(soot.Local) Scene(soot.Scene) IntConstant(soot.jimple.IntConstant) Value(soot.Value) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) Iterator(java.util.Iterator) Unit(soot.Unit) Collection(java.util.Collection) Jimple(soot.jimple.Jimple) SootClass(soot.SootClass) ValueBox(soot.ValueBox) Type(soot.Type) List(java.util.List) JimpleBody(soot.jimple.JimpleBody) SootMethod.constructorName(soot.SootMethod.constructorName) PrimType(soot.PrimType) VoidType(soot.VoidType) Hierarchy(soot.Hierarchy) Optional(java.util.Optional) SceneTransformer(soot.SceneTransformer) VoidType(soot.VoidType) PatchingChain(soot.PatchingChain) Chain(soot.util.Chain) HashMap(java.util.HashMap) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) ArrayList(java.util.ArrayList) Unit(soot.Unit) PrimType(soot.PrimType) ArrayList(java.util.ArrayList) List(java.util.List) Body(soot.Body) JimpleBody(soot.jimple.JimpleBody) JimpleBody(soot.jimple.JimpleBody) PatchingChain(soot.PatchingChain) SootMethodRef(soot.SootMethodRef) Local(soot.Local) SootClass(soot.SootClass) Type(soot.Type) PrimType(soot.PrimType) VoidType(soot.VoidType) FastHierarchy(soot.FastHierarchy) ThisRef(soot.jimple.ThisRef) ValueBox(soot.ValueBox) Value(soot.Value) SootMethod(soot.SootMethod)

Example 54 with ValueBox

use of soot.ValueBox in project soot by Sable.

the class CollectConstants method internalTransform.

protected void internalTransform(String phaseName, Map<String, String> options) {
    if (output) {
        out.println("Collecting Constant Data");
    }
    BodyBuilder.retrieveAllNames();
    Chain<SootClass> appClasses = Scene.v().getApplicationClasses();
    for (SootClass sc : appClasses) {
        for (SootMethod m : sc.getMethods()) {
            if (!m.hasActiveBody() || m.getName().contains(SootMethod.staticInitializerName)) {
                continue;
            }
            for (ValueBox useBox : m.getActiveBody().getUseBoxes()) {
                Value v = useBox.getValue();
                if (v instanceof Constant) {
                    Constant constant = (Constant) v;
                    Type type = constant.getType();
                    List<Constant> constants = typesToValues.computeIfAbsent(type, t -> new ArrayList<>());
                    if (!constants.contains(constant)) {
                        this.constants++;
                        constants.add(constant);
                    }
                }
            }
        }
    }
    int count = 0;
    String name = "newConstantJbcoName";
    SootClass[] classes = appClasses.toArray(new SootClass[appClasses.size()]);
    for (Type type : typesToValues.keySet()) {
        if (type instanceof NullType) {
            // type = RefType.v("java.lang.Object");
            continue;
        }
        for (Constant constant : typesToValues.get(type)) {
            name += "_";
            SootClass randomClass;
            do {
                randomClass = classes[Rand.getInt(classes.length)];
            } while (!isSuitableClassToAddFieldConstant(randomClass, constant));
            SootField newField = Scene.v().makeSootField(FieldRenamer.getNewName(), type, Modifier.STATIC ^ Modifier.PUBLIC);
            randomClass.addField(newField);
            FieldRenamer.sootFieldsRenamed.add(newField);
            FieldRenamer.addOldAndNewName(name, newField.getName());
            constantsToFields.put(constant, newField);
            addInitializingValue(randomClass, newField, constant);
            FieldRenamer.addOldAndNewName("addedConstant" + count++, newField.getName());
        }
    }
    updatedConstants += count;
}
Also used : ClassConstant(soot.jimple.ClassConstant) NullConstant(soot.jimple.NullConstant) Constant(soot.jimple.Constant) LongConstant(soot.jimple.LongConstant) DoubleConstant(soot.jimple.DoubleConstant) IntConstant(soot.jimple.IntConstant) StringConstant(soot.jimple.StringConstant) FloatConstant(soot.jimple.FloatConstant) SootClass(soot.SootClass) RefType(soot.RefType) NullType(soot.NullType) Type(soot.Type) VoidType(soot.VoidType) ValueBox(soot.ValueBox) Value(soot.Value) SootMethod(soot.SootMethod) SootField(soot.SootField) NullType(soot.NullType)

Example 55 with ValueBox

use of soot.ValueBox in project soot by Sable.

the class FieldRenamer method internalTransform.

protected void internalTransform(String phaseName, Map<String, String> options) {
    if (output) {
        if (rename_fields) {
            out.println("Transforming Field Names and Adding Opaque Predicates...");
        } else {
            out.println("Adding Opaques...");
        }
    }
    RefType boolRef = Scene.v().getRefType(booleanClassName);
    BodyBuilder.retrieveAllBodies();
    BodyBuilder.retrieveAllNames();
    for (SootClass sc : Scene.v().getApplicationClasses()) {
        String className = sc.getName();
        if (className.contains(".")) {
            className = className.substring(className.lastIndexOf(".") + 1, className.length());
        }
        oldToNewFieldNames.put(className, className);
        if (rename_fields) {
            if (output) {
                out.println("\tClassName: " + className);
            }
            // rename all the fields in the class
            for (SootField f : sc.getFields()) {
                int weight = soot.jbco.Main.getWeight(phaseName, f.getName());
                if (weight > 0) {
                    renameField(className, f);
                }
            }
        }
        // skip interfaces - they can only hold final fields
        if (sc.isInterface()) {
            continue;
        }
        // add one opaq predicate for true and one for false to each class
        String bool = "opPred1";
        Type t = Rand.getInt() % 2 == 0 ? BooleanType.v() : boolRef;
        while (oldToNewFieldNames.containsKey(bool)) {
            bool += "_";
        }
        SootField f = Scene.v().makeSootField(bool, t, Modifier.PUBLIC | Modifier.STATIC);
        renameField(className, f);
        opaquePreds1ByClass.put(sc, f);
        sc.addField(f);
        setBooleanTo(sc, f, true);
        bool = "opPred2";
        t = t == BooleanType.v() ? boolRef : BooleanType.v();
        while (oldToNewFieldNames.containsKey(bool)) {
            bool += "_";
        }
        f = Scene.v().makeSootField(bool, t, Modifier.PUBLIC | Modifier.STATIC);
        renameField(className, f);
        opaquePreds2ByClass.put(sc, f);
        sc.addField(f);
        if (t == boolRef) {
            setBooleanTo(sc, f, false);
        }
    }
    buildOpaquePairings();
    if (!rename_fields) {
        return;
    }
    if (output) {
        out.println("\r\tUpdating field references in bytecode");
    }
    for (SootClass sc : Scene.v().getApplicationClasses()) {
        for (SootMethod m : sc.getMethods()) {
            if (!m.isConcrete()) {
                continue;
            }
            if (!m.hasActiveBody()) {
                m.retrieveActiveBody();
            }
            for (Unit unit : m.getActiveBody().getUnits()) {
                for (ValueBox box : unit.getUseAndDefBoxes()) {
                    Value value = box.getValue();
                    if (value instanceof FieldRef) {
                        FieldRef fieldRef = (FieldRef) value;
                        SootFieldRef sootFieldRef = fieldRef.getFieldRef();
                        if (sootFieldRef.declaringClass().isLibraryClass()) {
                            continue;
                        }
                        String oldName = sootFieldRef.name();
                        String fullName = sootFieldRef.declaringClass().getName() + '.' + oldName;
                        String newName = oldToNewFieldNames.get(oldName);
                        if (newName == null || namesToNotRename.contains(fullName)) {
                            continue;
                        }
                        if (newName.equals(oldName)) {
                            System.out.println("Strange.. Should not find a field with the same old and new name.");
                        }
                        sootFieldRef = Scene.v().makeFieldRef(sootFieldRef.declaringClass(), newName, sootFieldRef.type(), sootFieldRef.isStatic());
                        fieldRef.setFieldRef(sootFieldRef);
                        try {
                            sootFieldRef.resolve();
                        } catch (Exception e) {
                            System.err.println("********ERROR Updating " + sootFieldRef.name() + " to " + newName);
                            System.err.println("Fields of " + sootFieldRef.declaringClass().getName() + ": " + sootFieldRef.declaringClass().getFields());
                            throw new RuntimeException(e);
                        }
                    }
                }
            }
        }
    }
}
Also used : FieldRef(soot.jimple.FieldRef) SootFieldRef(soot.SootFieldRef) SootClass(soot.SootClass) Unit(soot.Unit) SootFieldRef(soot.SootFieldRef) RefType(soot.RefType) RefType(soot.RefType) BooleanType(soot.BooleanType) IntegerType(soot.IntegerType) Type(soot.Type) VoidType(soot.VoidType) ValueBox(soot.ValueBox) Value(soot.Value) SootMethod(soot.SootMethod) SootField(soot.SootField)

Aggregations

ValueBox (soot.ValueBox)58 Value (soot.Value)43 Local (soot.Local)36 Unit (soot.Unit)33 ArrayList (java.util.ArrayList)26 Type (soot.Type)20 Stmt (soot.jimple.Stmt)20 DefinitionStmt (soot.jimple.DefinitionStmt)17 InvokeExpr (soot.jimple.InvokeExpr)15 SootMethod (soot.SootMethod)13 RefType (soot.RefType)12 AssignStmt (soot.jimple.AssignStmt)11 IntConstant (soot.jimple.IntConstant)11 HashSet (java.util.HashSet)10 IntType (soot.IntType)10 SootClass (soot.SootClass)10 FieldRef (soot.jimple.FieldRef)10 HashMap (java.util.HashMap)9 LongType (soot.LongType)9 VoidType (soot.VoidType)9