Search in sources :

Example 96 with SootMethod

use of soot.SootMethod in project soot by Sable.

the class ClassRenamer method internalTransform.

@Override
protected void internalTransform(String phaseName, Map<String, String> options) {
    if (isVerbose()) {
        logger.debug("Transforming Class Names...");
    }
    BodyBuilder.retrieveAllBodies();
    BodyBuilder.retrieveAllNames();
    final SootClass mainClass = getMainClassSafely();
    // iterate through application classes, rename classes with junk
    for (SootClass sootClass : Scene.v().getApplicationClasses()) {
        final String className = sootClass.getName();
        if (sootClass.equals(mainClass) || oldToNewClassNames.containsValue(className) || soot.jbco.Main.getWeight(phaseName, className) == 0) {
            continue;
        }
        String newClassName = oldToNewClassNames.get(className);
        if (newClassName == null) {
            newClassName = getNewName(getPackageName(className), className);
        }
        sootClass.setName(newClassName);
        RefType crt = RefType.v(newClassName);
        crt.setSootClass(sootClass);
        sootClass.setRefType(crt);
        sootClass.setResolvingLevel(SootClass.BODIES);
        // will this fix dangling classes?
        // scene.addRefType(sootClass.getType());
        newNameToClass.put(newClassName, sootClass);
        if (isVerbose()) {
            logger.info("\tRenaming " + className + " to " + newClassName);
        }
    }
    Scene.v().releaseActiveHierarchy();
    Scene.v().setFastHierarchy(new FastHierarchy());
    if (isVerbose()) {
        logger.info("\r\tUpdating bytecode class references");
    }
    for (SootClass sootClass : Scene.v().getApplicationClasses()) {
        for (SootMethod sootMethod : sootClass.getMethods()) {
            if (!sootMethod.isConcrete()) {
                continue;
            }
            if (isVerbose()) {
                logger.info("\t\t" + sootMethod.getSignature());
            }
            Body aBody;
            try {
                aBody = sootMethod.getActiveBody();
            } catch (Exception e) {
                continue;
            }
            for (Unit u : aBody.getUnits()) {
                for (ValueBox vb : u.getUseAndDefBoxes()) {
                    Value v = vb.getValue();
                    if (v instanceof ClassConstant) {
                        ClassConstant constant = (ClassConstant) v;
                        RefType type = (RefType) constant.toSootType();
                        RefType updatedType = type.getSootClass().getType();
                        vb.setValue(ClassConstant.fromType(updatedType));
                    } else if (v instanceof Expr) {
                        if (v instanceof CastExpr) {
                            CastExpr castExpr = (CastExpr) v;
                            updateType(castExpr.getCastType());
                        } else if (v instanceof InstanceOfExpr) {
                            InstanceOfExpr instanceOfExpr = (InstanceOfExpr) v;
                            updateType(instanceOfExpr.getCheckType());
                        }
                    } else if (v instanceof Ref) {
                        updateType(v.getType());
                    }
                }
            }
        }
    }
    Scene.v().releaseActiveHierarchy();
    Scene.v().setFastHierarchy(new FastHierarchy());
}
Also used : SootClass(soot.SootClass) Unit(soot.Unit) InstanceOfExpr(soot.jimple.InstanceOfExpr) RefType(soot.RefType) FastHierarchy(soot.FastHierarchy) Ref(soot.jimple.Ref) Expr(soot.jimple.Expr) InstanceOfExpr(soot.jimple.InstanceOfExpr) CastExpr(soot.jimple.CastExpr) ValueBox(soot.ValueBox) Value(soot.Value) CastExpr(soot.jimple.CastExpr) SootMethod(soot.SootMethod) Body(soot.Body) ClassConstant(soot.jimple.ClassConstant)

Example 97 with SootMethod

use of soot.SootMethod in project soot by Sable.

the class OnFlyCallGraphBuilder method resolveInvoke.

private void resolveInvoke(Collection<InvokeCallSite> list) {
    for (InvokeCallSite ics : list) {
        Set<Type> s = reachingBaseTypes.get(ics.base());
        if (s == null || s.isEmpty()) {
            continue;
        }
        if (ics.reachingTypes() != null) {
            assert ics.nullnessCode() != InvokeCallSite.MUST_BE_NULL;
            resolveStaticTypes(s, ics);
            continue;
        }
        boolean mustNotBeNull = ics.nullnessCode() == InvokeCallSite.MUST_NOT_BE_NULL;
        boolean mustBeNull = ics.nullnessCode() == InvokeCallSite.MUST_BE_NULL;
        // yet, then generate nullary methods
        if (mustBeNull || (ics.nullnessCode() == InvokeCallSite.MAY_BE_NULL && (!invokeArgsToSize.containsKey(ics.argArray()) || !reachingArgTypes.containsKey(ics.argArray())))) {
            for (Type bType : s) {
                assert bType instanceof RefType;
                SootClass baseClass = ((RefType) bType).getSootClass();
                assert !baseClass.isInterface();
                Iterator<SootMethod> mIt = getPublicNullaryMethodIterator(baseClass);
                while (mIt.hasNext()) {
                    SootMethod sm = mIt.next();
                    cm.addVirtualEdge(ics.container(), ics.stmt(), sm, Kind.REFL_INVOKE, null);
                }
            }
        } else {
            /*
				 * In this branch, either the invoke arg must not be null, or may be null and we
				 * have size and type information. Invert the above condition: ~mustBeNull &&
				 * (~mayBeNull || (has-size && has-type)) => (~mustBeNull && ~mayBeNull) ||
				 * (~mustBeNull && has-size && has-type) => mustNotBeNull || (~mustBeNull &&
				 * has-types && has-size) => mustNotBeNull || (mayBeNull && has-types &&
				 * has-size)
				 */
            Set<Type> reachingTypes = reachingArgTypes.get(ics.argArray());
            /*
				 * the path condition allows must-not-be null without type and size info. Do
				 * nothing in this case. THIS IS UNSOUND if default null values in an argument
				 * array are used.
				 */
            if (reachingTypes == null || !invokeArgsToSize.containsKey(ics.argArray())) {
                assert ics.nullnessCode() == InvokeCallSite.MUST_NOT_BE_NULL : ics;
                return;
            }
            assert reachingTypes != null && invokeArgsToSize.containsKey(ics.argArray());
            BitSet methodSizes = invokeArgsToSize.get(ics.argArray());
            for (Type bType : s) {
                assert bType instanceof RefLikeType;
                // we do not handle static methods or array reflection
                if (bType instanceof NullType || bType instanceof ArrayType) {
                    continue;
                } else {
                    SootClass baseClass = ((RefType) bType).getSootClass();
                    Iterator<SootMethod> mIt = getPublicMethodIterator(baseClass, reachingTypes, methodSizes, mustNotBeNull);
                    while (mIt.hasNext()) {
                        SootMethod sm = mIt.next();
                        cm.addVirtualEdge(ics.container(), ics.stmt(), sm, Kind.REFL_INVOKE, null);
                    }
                }
            }
        }
    }
}
Also used : RefType(soot.RefType) RefLikeType(soot.RefLikeType) ArrayType(soot.ArrayType) RefType(soot.RefType) ShortType(soot.ShortType) BooleanType(soot.BooleanType) ByteType(soot.ByteType) Type(soot.Type) DoubleType(soot.DoubleType) FloatType(soot.FloatType) IntType(soot.IntType) CharType(soot.CharType) LongType(soot.LongType) NullType(soot.NullType) RefLikeType(soot.RefLikeType) ArrayType(soot.ArrayType) PrimType(soot.PrimType) BitSet(java.util.BitSet) SootMethod(soot.SootMethod) NullType(soot.NullType) SootClass(soot.SootClass)

Example 98 with SootMethod

use of soot.SootMethod in project soot by Sable.

the class OnFlyCallGraphBuilder method getImplicitTargets.

private void getImplicitTargets(SootMethod source) {
    final SootClass scl = source.getDeclaringClass();
    if (source.isNative() || source.isPhantom())
        return;
    if (source.getSubSignature().indexOf("<init>") >= 0) {
        handleInit(source, scl);
    }
    Body b = source.retrieveActiveBody();
    for (Unit u : b.getUnits()) {
        final Stmt s = (Stmt) u;
        if (s.containsInvokeExpr()) {
            InvokeExpr ie = s.getInvokeExpr();
            SootMethodRef methodRef = ie.getMethodRef();
            switch(methodRef.declaringClass().getName()) {
                case "java.lang.reflect.Method":
                    if (methodRef.getSubSignature().getString().equals("java.lang.Object invoke(java.lang.Object,java.lang.Object[])"))
                        reflectionModel.methodInvoke(source, s);
                    break;
                case "java.lang.Class":
                    if (methodRef.getSubSignature().getString().equals("java.lang.Object newInstance()"))
                        reflectionModel.classNewInstance(source, s);
                    break;
                case "java.lang.reflect.Constructor":
                    if (methodRef.getSubSignature().getString().equals("java.lang.Object newInstance(java.lang.Object[]))"))
                        reflectionModel.contructorNewInstance(source, s);
                    break;
            }
            if (methodRef.getSubSignature() == sigForName) {
                reflectionModel.classForName(source, s);
            }
            if (ie instanceof StaticInvokeExpr) {
                SootClass cl = ie.getMethodRef().declaringClass();
                for (SootMethod clinit : EntryPoints.v().clinitsOf(cl)) {
                    addEdge(source, s, clinit, Kind.CLINIT);
                }
            }
        }
        if (s.containsFieldRef()) {
            FieldRef fr = s.getFieldRef();
            if (fr instanceof StaticFieldRef) {
                SootClass cl = fr.getFieldRef().declaringClass();
                for (SootMethod clinit : EntryPoints.v().clinitsOf(cl)) {
                    addEdge(source, s, clinit, Kind.CLINIT);
                }
            }
        }
        if (s instanceof AssignStmt) {
            Value rhs = ((AssignStmt) s).getRightOp();
            if (rhs instanceof NewExpr) {
                NewExpr r = (NewExpr) rhs;
                SootClass cl = r.getBaseType().getSootClass();
                for (SootMethod clinit : EntryPoints.v().clinitsOf(cl)) {
                    addEdge(source, s, clinit, Kind.CLINIT);
                }
            } else if (rhs instanceof NewArrayExpr || rhs instanceof NewMultiArrayExpr) {
                Type t = rhs.getType();
                if (t instanceof ArrayType)
                    t = ((ArrayType) t).baseType;
                if (t instanceof RefType) {
                    SootClass cl = ((RefType) t).getSootClass();
                    for (SootMethod clinit : EntryPoints.v().clinitsOf(cl)) {
                        addEdge(source, s, clinit, Kind.CLINIT);
                    }
                }
            }
        }
    }
}
Also used : FieldRef(soot.jimple.FieldRef) StaticFieldRef(soot.jimple.StaticFieldRef) SootMethodRef(soot.SootMethodRef) AssignStmt(soot.jimple.AssignStmt) NewMultiArrayExpr(soot.jimple.NewMultiArrayExpr) SootClass(soot.SootClass) Unit(soot.Unit) InvokeStmt(soot.jimple.InvokeStmt) AssignStmt(soot.jimple.AssignStmt) Stmt(soot.jimple.Stmt) StaticFieldRef(soot.jimple.StaticFieldRef) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) ArrayType(soot.ArrayType) RefType(soot.RefType) RefType(soot.RefType) ShortType(soot.ShortType) BooleanType(soot.BooleanType) ByteType(soot.ByteType) Type(soot.Type) DoubleType(soot.DoubleType) FloatType(soot.FloatType) IntType(soot.IntType) CharType(soot.CharType) LongType(soot.LongType) NullType(soot.NullType) RefLikeType(soot.RefLikeType) ArrayType(soot.ArrayType) PrimType(soot.PrimType) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) DynamicInvokeExpr(soot.jimple.DynamicInvokeExpr) VirtualInvokeExpr(soot.jimple.VirtualInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) NewArrayExpr(soot.jimple.NewArrayExpr) Value(soot.Value) NewExpr(soot.jimple.NewExpr) SootMethod(soot.SootMethod) Body(soot.Body)

Example 99 with SootMethod

use of soot.SootMethod 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 100 with SootMethod

use of soot.SootMethod in project soot by Sable.

the class LocalMustAliasAnalysis method trackableFields.

/**
 * Computes the set of {@link EquivalentValue}s of all field references that are used
 * in this method but not set by the method or any method transitively called by this method.
 */
private Set<Value> trackableFields() {
    Set<Value> usedFieldRefs = new HashSet<Value>();
    // add all field references that are in use boxes
    for (Unit unit : this.graph) {
        Stmt s = (Stmt) unit;
        List<ValueBox> useBoxes = s.getUseBoxes();
        for (ValueBox useBox : useBoxes) {
            Value val = useBox.getValue();
            if (val instanceof FieldRef) {
                FieldRef fieldRef = (FieldRef) val;
                if (fieldRef.getType() instanceof RefLikeType)
                    usedFieldRefs.add(new EquivalentValue(fieldRef));
            }
        }
    }
    // prune all fields that are written to
    if (!usedFieldRefs.isEmpty()) {
        if (!Scene.v().hasCallGraph()) {
            throw new IllegalStateException("No call graph found!");
        }
        CallGraph cg = Scene.v().getCallGraph();
        ReachableMethods reachableMethods = new ReachableMethods(cg, Collections.<MethodOrMethodContext>singletonList(container));
        reachableMethods.update();
        for (Iterator<MethodOrMethodContext> iterator = reachableMethods.listener(); iterator.hasNext(); ) {
            SootMethod m = (SootMethod) iterator.next();
            if (m.hasActiveBody() && // exclude static initializer of same class (assume that it has already been executed)
            !(m.getName().equals(SootMethod.staticInitializerName) && m.getDeclaringClass().equals(container.getDeclaringClass()))) {
                for (Unit u : m.getActiveBody().getUnits()) {
                    List<ValueBox> defBoxes = u.getDefBoxes();
                    for (ValueBox defBox : defBoxes) {
                        Value value = defBox.getValue();
                        if (value instanceof FieldRef) {
                            usedFieldRefs.remove(new EquivalentValue(value));
                        }
                    }
                }
            }
        }
    }
    return usedFieldRefs;
}
Also used : EquivalentValue(soot.EquivalentValue) FieldRef(soot.jimple.FieldRef) Unit(soot.Unit) Stmt(soot.jimple.Stmt) DefinitionStmt(soot.jimple.DefinitionStmt) RefLikeType(soot.RefLikeType) ReachableMethods(soot.jimple.toolkits.callgraph.ReachableMethods) CallGraph(soot.jimple.toolkits.callgraph.CallGraph) ValueBox(soot.ValueBox) EquivalentValue(soot.EquivalentValue) Value(soot.Value) SootMethod(soot.SootMethod) MethodOrMethodContext(soot.MethodOrMethodContext) HashSet(java.util.HashSet)

Aggregations

SootMethod (soot.SootMethod)237 SootClass (soot.SootClass)95 RefType (soot.RefType)56 ArrayList (java.util.ArrayList)49 Type (soot.Type)47 Unit (soot.Unit)47 Value (soot.Value)36 Stmt (soot.jimple.Stmt)35 Test (org.junit.Test)34 Local (soot.Local)34 Body (soot.Body)32 VoidType (soot.VoidType)31 PrimType (soot.PrimType)28 SootField (soot.SootField)28 BooleanType (soot.BooleanType)26 Iterator (java.util.Iterator)23 DoubleType (soot.DoubleType)23 FloatType (soot.FloatType)23 LongType (soot.LongType)23 InvokeExpr (soot.jimple.InvokeExpr)23