Search in sources :

Example 6 with FastHierarchy

use of soot.FastHierarchy in project soot by Sable.

the class VirtualCalls method resolveLibrarySignature.

protected void resolveLibrarySignature(Type declaredType, Type sigType, NumberedString subSig, SootMethod container, ChunkedQueue<SootMethod> targets, boolean appOnly, RefType base) {
    FastHierarchy fastHierachy = Scene.v().getOrMakeFastHierarchy();
    assert (declaredType instanceof RefType);
    Pair<Type, NumberedString> pair = new Pair<Type, NumberedString>(base, subSig);
    {
        Set<Pair<Type, NumberedString>> types = baseToPossibleSubTypes.get(pair);
        // just retrieve the previous result.
        if (types != null) {
            for (Pair<Type, NumberedString> tuple : types) {
                Type st = tuple.getO1();
                if (!fastHierachy.canStoreType(st, declaredType)) {
                    resolve(st, st, sigType, subSig, container, targets, appOnly);
                } else {
                    resolve(st, declaredType, sigType, subSig, container, targets, appOnly);
                }
            }
            return;
        }
    }
    Set<Pair<Type, NumberedString>> types = new HashSet<Pair<Type, NumberedString>>();
    // get return type; method name; parameter types
    String[] split = subSig.getString().replaceAll("(.*) (.*)\\((.*)\\)", "$1;$2;$3").split(";");
    Type declaredReturnType = Scene.v().getType(split[0]);
    String declaredName = split[1];
    List<Type> declaredParamTypes = new ArrayList<Type>();
    // separate the parameter types
    if (split.length == 3) {
        for (String type : split[2].split(",")) {
            declaredParamTypes.add(Scene.v().getType(type));
        }
    }
    Chain<SootClass> classes = Scene.v().getClasses();
    for (SootClass sc : classes) {
        for (SootMethod sm : sc.getMethods()) {
            if (sm.isConcrete() || sm.isNative()) {
                // method name has to match
                if (!sm.getName().equals(declaredName))
                    continue;
                // type or a sub type of it
                if (!fastHierachy.canStoreType(sm.getReturnType(), declaredReturnType))
                    continue;
                List<Type> paramTypes = sm.getParameterTypes();
                // ones (same type or super type).
                if (declaredParamTypes.size() != paramTypes.size())
                    continue;
                boolean check = true;
                for (int i = 0; i < paramTypes.size(); i++) {
                    if (!fastHierachy.canStoreType(declaredParamTypes.get(i), paramTypes.get(i))) {
                        check = false;
                        break;
                    }
                }
                if (check) {
                    Type st = sc.getType();
                    if (!fastHierachy.canStoreType(st, declaredType)) {
                        // therefore not used in library client
                        if (!sc.isFinal()) {
                            NumberedString newSubSig = sm.getNumberedSubSignature();
                            resolve(st, st, sigType, newSubSig, container, targets, appOnly);
                            types.add(new Pair<Type, NumberedString>(st, newSubSig));
                        }
                    } else {
                        resolve(st, declaredType, sigType, subSig, container, targets, appOnly);
                        types.add(new Pair<Type, NumberedString>(st, subSig));
                    }
                }
            }
        }
    }
    baseToPossibleSubTypes.putAll(pair, types);
}
Also used : NumberedString(soot.util.NumberedString) HashSet(java.util.HashSet) Set(java.util.Set) ArrayList(java.util.ArrayList) NumberedString(soot.util.NumberedString) SootClass(soot.SootClass) RefType(soot.RefType) FastHierarchy(soot.FastHierarchy) RefType(soot.RefType) AnySubType(soot.AnySubType) NullType(soot.NullType) ArrayType(soot.ArrayType) Type(soot.Type) SootMethod(soot.SootMethod) Pair(soot.toolkits.scalar.Pair) HashSet(java.util.HashSet)

Example 7 with FastHierarchy

use of soot.FastHierarchy in project soot by Sable.

the class OnFlyCallGraphBuilder method addType.

public void addType(Local receiver, Context srcContext, Type type, Context typeContext) {
    FastHierarchy fh = Scene.v().getOrMakeFastHierarchy();
    if (receiverToSites.get(receiver) != null) {
        for (Iterator<VirtualCallSite> siteIt = receiverToSites.get(receiver).iterator(); siteIt.hasNext(); ) {
            final VirtualCallSite site = siteIt.next();
            if (site.kind() == Kind.THREAD && !fh.canStoreType(type, clRunnable))
                continue;
            if (site.kind() == Kind.EXECUTOR && !fh.canStoreType(type, clRunnable))
                continue;
            if (site.kind() == Kind.ASYNCTASK && !fh.canStoreType(type, clAsyncTask))
                continue;
            if (site.kind() == Kind.HANDLER && !fh.canStoreType(type, clHandler))
                continue;
            if (site.iie() instanceof SpecialInvokeExpr && site.kind != Kind.THREAD && site.kind != Kind.EXECUTOR && site.kind != Kind.ASYNCTASK) {
                SootMethod target = VirtualCalls.v().resolveSpecial((SpecialInvokeExpr) site.iie(), site.subSig(), site.container(), appOnly);
                // simply do not add the target in that case
                if (target != null) {
                    targetsQueue.add(target);
                }
            } else {
                VirtualCalls.v().resolve(type, receiver.getType(), site.subSig(), site.container(), targetsQueue, appOnly);
            }
            while (targets.hasNext()) {
                SootMethod target = targets.next();
                cm.addVirtualEdge(MethodContext.v(site.container(), srcContext), site.stmt(), target, site.kind(), typeContext);
            }
        }
    }
    if (baseToInvokeSite.get(receiver) != null) {
        addBaseType(receiver, srcContext, type);
    }
}
Also used : FastHierarchy(soot.FastHierarchy) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) SootMethod(soot.SootMethod)

Example 8 with FastHierarchy

use of soot.FastHierarchy in project soot by Sable.

the class VirtualCalls method resolveAnySubType.

protected void resolveAnySubType(Type declaredType, Type sigType, NumberedString subSig, SootMethod container, ChunkedQueue<SootMethod> targets, boolean appOnly, RefType base) {
    FastHierarchy fastHierachy = Scene.v().getOrMakeFastHierarchy();
    {
        Set<Type> subTypes = baseToSubTypes.get(base);
        if (subTypes != null && !subTypes.isEmpty()) {
            for (final Type st : subTypes) {
                resolve(st, declaredType, sigType, subSig, container, targets, appOnly);
            }
            return;
        }
    }
    Set<Type> newSubTypes = new HashSet<>();
    newSubTypes.add(base);
    LinkedList<SootClass> worklist = new LinkedList<SootClass>();
    HashSet<SootClass> workset = new HashSet<SootClass>();
    FastHierarchy fh = fastHierachy;
    SootClass cl = base.getSootClass();
    if (workset.add(cl))
        worklist.add(cl);
    while (!worklist.isEmpty()) {
        cl = worklist.removeFirst();
        if (cl.isInterface()) {
            for (Iterator<SootClass> cIt = fh.getAllImplementersOfInterface(cl).iterator(); cIt.hasNext(); ) {
                final SootClass c = cIt.next();
                if (workset.add(c))
                    worklist.add(c);
            }
        } else {
            if (cl.isConcrete()) {
                resolve(cl.getType(), declaredType, sigType, subSig, container, targets, appOnly);
                newSubTypes.add(cl.getType());
            }
            for (Iterator<SootClass> cIt = fh.getSubclassesOf(cl).iterator(); cIt.hasNext(); ) {
                final SootClass c = cIt.next();
                if (workset.add(c))
                    worklist.add(c);
            }
        }
    }
    baseToSubTypes.putAll(base, newSubTypes);
}
Also used : FastHierarchy(soot.FastHierarchy) RefType(soot.RefType) AnySubType(soot.AnySubType) NullType(soot.NullType) ArrayType(soot.ArrayType) Type(soot.Type) HashSet(java.util.HashSet) Set(java.util.Set) SootClass(soot.SootClass) LinkedList(java.util.LinkedList) HashSet(java.util.HashSet)

Example 9 with FastHierarchy

use of soot.FastHierarchy in project soot by Sable.

the class ThrowableSet method whichCatchableAs.

/**
 * Partitions the exceptions in this <code>ThrowableSet</code> into those
 * which would be caught by a handler with the passed <code>catch</code>
 * parameter type and those which would not.
 *
 * @param catcher
 *            type of the handler parameter to be tested.
 *
 * @return a pair of <code>ThrowableSet</code>s, one containing the types in
 *         this <code>ThrowableSet</code> which would be be caught as
 *         <code>catcher</code> and the other containing the types in this
 *         <code>ThrowableSet</code> which would not be caught as
 *         <code>catcher</code>.
 */
public Pair whichCatchableAs(RefType catcher) {
    if (INSTRUMENTING) {
        Manager.v().removesOfAnySubType++;
    }
    FastHierarchy h = Scene.v().getOrMakeFastHierarchy();
    Set<RefLikeType> caughtIncluded = null;
    Set<AnySubType> caughtExcluded = null;
    Set<RefLikeType> uncaughtIncluded = null;
    Set<AnySubType> uncaughtExcluded = null;
    if (INSTRUMENTING) {
        Manager.v().removesFromSearch++;
    }
    for (AnySubType exclusion : exceptionsExcluded) {
        RefType exclusionBase = exclusion.getBase();
        // Is the current type explicitly excluded?
        if (catcher.getSootClass().isPhantom() && exclusionBase.equals(catcher))
            return new Pair(ThrowableSet.Manager.v().EMPTY, this);
        if (h.canStoreType(catcher, exclusionBase)) {
            // caught by catcher.
            return new Pair(ThrowableSet.Manager.v().EMPTY, this);
        } else if (h.canStoreType(exclusionBase, catcher)) {
            // exclusion wouldn't be in exceptionsExcluded if one
            // of its supertypes were not in exceptionsIncluded,
            // so we know the next loop will add either that supertype
            // or catcher to caughtIncluded. Thus:
            caughtExcluded = addExceptionToSet(exclusion, caughtExcluded);
        } else {
            uncaughtExcluded = addExceptionToSet(exclusion, uncaughtExcluded);
        }
    }
    for (RefLikeType inclusion : exceptionsIncluded) {
        if (inclusion instanceof RefType) {
            // only if it is in the inclusion list and ignore any hierarchy.
            if (catcher.getSootClass().isPhantom()) {
                if (inclusion.equals(catcher))
                    caughtIncluded = addExceptionToSet(inclusion, caughtIncluded);
                else
                    uncaughtIncluded = addExceptionToSet(inclusion, uncaughtIncluded);
            } else if (h.canStoreType(inclusion, catcher)) {
                caughtIncluded = addExceptionToSet(inclusion, caughtIncluded);
            } else {
                uncaughtIncluded = addExceptionToSet(inclusion, uncaughtIncluded);
            }
        } else {
            RefType base = ((AnySubType) inclusion).getBase();
            // only if it is in the inclusion list and ignore any hierarchy.
            if (catcher.getSootClass().isPhantom()) {
                if (base.equals(catcher))
                    caughtIncluded = addExceptionToSet(inclusion, caughtIncluded);
                else {
                    if (base.getClassName().equals("java.lang.Throwable"))
                        caughtIncluded = addExceptionToSet(catcher, caughtIncluded);
                    uncaughtIncluded = addExceptionToSet(inclusion, uncaughtIncluded);
                }
            } else if (h.canStoreType(base, catcher)) {
                // All subtypes of base will be caught. Any exclusions
                // will already have been copied to caughtExcluded by
                // the preceding loop.
                caughtIncluded = addExceptionToSet(inclusion, caughtIncluded);
            } else if (h.canStoreType(catcher, base)) {
                // Some subtypes of base will be caught, and
                // we know that not all of those catchable subtypes
                // are among exceptionsExcluded, since in that case we
                // would already have returned from within the
                // preceding loop. So, remove AnySubType(catcher)
                // from the uncaught types.
                uncaughtIncluded = addExceptionToSet(inclusion, uncaughtIncluded);
                uncaughtExcluded = addExceptionToSet(AnySubType.v(catcher), uncaughtExcluded);
                caughtIncluded = addExceptionToSet(AnySubType.v(catcher), caughtIncluded);
            // Any already excluded subtypes of inclusion
            // which are subtypes of catcher will have been
            // added to caughtExcluded by the previous loop.
            } else {
                uncaughtIncluded = addExceptionToSet(inclusion, uncaughtIncluded);
            }
        }
    }
    ThrowableSet caughtSet = Manager.v().registerSetIfNew(caughtIncluded, caughtExcluded);
    ThrowableSet uncaughtSet = Manager.v().registerSetIfNew(uncaughtIncluded, uncaughtExcluded);
    return new Pair(caughtSet, uncaughtSet);
}
Also used : RefLikeType(soot.RefLikeType) RefType(soot.RefType) FastHierarchy(soot.FastHierarchy) AnySubType(soot.AnySubType)

Example 10 with FastHierarchy

use of soot.FastHierarchy 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

FastHierarchy (soot.FastHierarchy)14 RefType (soot.RefType)8 AnySubType (soot.AnySubType)7 SootMethod (soot.SootMethod)7 HashSet (java.util.HashSet)6 SootClass (soot.SootClass)6 RefLikeType (soot.RefLikeType)5 Type (soot.Type)5 ArrayList (java.util.ArrayList)4 Body (soot.Body)4 Unit (soot.Unit)4 Value (soot.Value)4 ValueBox (soot.ValueBox)4 ArrayType (soot.ArrayType)3 SootMethodRef (soot.SootMethodRef)3 SpecialInvokeExpr (soot.jimple.SpecialInvokeExpr)3 Iterator (java.util.Iterator)2 Set (java.util.Set)2 Local (soot.Local)2 NullType (soot.NullType)2