Search in sources :

Example 11 with ThisRef

use of soot.jimple.ThisRef 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)

Example 12 with ThisRef

use of soot.jimple.ThisRef 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)

Aggregations

ThisRef (soot.jimple.ThisRef)12 Local (soot.Local)11 ParameterRef (soot.jimple.ParameterRef)10 Unit (soot.Unit)7 Value (soot.Value)7 CaughtExceptionRef (soot.jimple.CaughtExceptionRef)7 HashMap (java.util.HashMap)5 ValueBox (soot.ValueBox)5 IdentityStmt (soot.jimple.IdentityStmt)5 Stmt (soot.jimple.Stmt)5 ArrayList (java.util.ArrayList)4 Iterator (java.util.Iterator)4 Trap (soot.Trap)3 InstanceInvokeExpr (soot.jimple.InstanceInvokeExpr)3 SpecialInvokeExpr (soot.jimple.SpecialInvokeExpr)3 LinkedList (java.util.LinkedList)2 List (java.util.List)2 Body (soot.Body)2 Hierarchy (soot.Hierarchy)2 RefType (soot.RefType)2