protected void addMethod(List<SootMethod> set, SootClass cls, NumberedString methodSubSig) { SootMethod sm = cls.getMethodUnsafe(methodSubSig); if (sm != null) { set.add(sm); } }
/** * Attempts to retrieve the method with the given name, parameters and return type. If no matching method can be found, an * exception is thrown. */ public SootMethod getMethod(String name, List<Type> parameterTypes, Type returnType) { SootMethod sm = getMethodUnsafe(name, parameterTypes, returnType); if (sm != null) { return sm; } throw new RuntimeException( "Class " + getName() + " doesn't have method " + name + "(" + parameterTypes + ")" + " : " + returnType); }
private void addEdge(SootMethod src, Stmt stmt, SootClass cls, NumberedString methodSubSig, Kind kind) { SootMethod sm = cls.getMethodUnsafe(methodSubSig); if (sm != null) { addEdge(src, stmt, sm, kind); } }
/** * Returns the method of this class with the given subsignature. If no method with the given subsignature can be found, an * exception is thrown. */ public SootMethod getMethod(NumberedString subsignature) { SootMethod ret = getMethodUnsafe(subsignature); if (ret == null) { throw new RuntimeException("No method " + subsignature + " in class " + getName()); } else { return ret; } }
final SootMethod initStart = cl.getMethodUnsafe(sigClinit); if (initStart == null) { return Collections.emptyList();
public SootMethod getMainMethod() { if (!hasMainClass()) { throw new RuntimeException("There is no main class set!"); } SootMethod mainMethod = mainClass.getMethodUnsafe("main", Collections.<Type>singletonList(ArrayType.v(RefType.v("java.lang.String"), 1)), VoidType.v()); if (mainMethod == null) { throw new RuntimeException("Main class declares no main method!"); } return mainMethod; }
private SootMethod getFirstMethod(SootClass sc) { ArrayList paramTypes = new ArrayList(); paramTypes.add(soot.ArrayType.v(soot.RefType.v("java.lang.String"), 1)); SootMethod sm = sc.getMethodUnsafe("main", paramTypes, soot.VoidType.v()); if (sm != null) { return sm; } else { return (SootMethod) sc.getMethods().get(0); } }
/** * Returns a list of all concrete main(String[]) methods of all application classes. */ public List<SootMethod> mainsOfApplicationClasses() { List<SootMethod> ret = new ArrayList<SootMethod>(); for (Iterator<SootClass> clIt = Scene.v().getApplicationClasses().iterator(); clIt.hasNext();) { final SootClass cl = clIt.next(); SootMethod m = cl.getMethodUnsafe("void main(java.lang.String[])"); if (m != null) { if (m.isConcrete()) { ret.add(m); } } } return ret; }
private List<SootClass> getExceptionSpec(SootClass intrface, NumberedString sig) { SootMethod sm = intrface.getMethodUnsafe(sig); if (sm != null) { return sm.getExceptions(); } List<SootClass> result = null; SootClass obj = Scene.v().getSootClass("java.lang.Object"); sm = obj.getMethodUnsafe(sig); if (sm.getExceptionsUnsafe() == null) { return Collections.emptyList(); } if (sm != null) { result = new Vector<SootClass>(sm.getExceptions()); } for (SootClass suprintr : intrface.getInterfaces()) { List<SootClass> other = getExceptionSpec(suprintr, sig); if (other != null) { if (result == null) { result = other; } else { result.retainAll(other); } } } return result; }
/** * Adds an edge to the constructor of the target class from this call to {@link Class#newInstance()}. */ @Override public void classNewInstance(SootMethod container, Stmt newInstanceInvokeStmt) { Set<String> classNames = reflectionInfo.classNewInstanceClassNames(container); if (classNames == null || classNames.isEmpty()) { registerGuard(container, newInstanceInvokeStmt, "Class.newInstance() call site; Soot did not expect this site to be reached"); } else { for (String clsName : classNames) { SootClass cls = Scene.v().getSootClass(clsName); SootMethod constructor = cls.getMethodUnsafe(sigInit); if (constructor != null) { addEdge(container, newInstanceInvokeStmt, constructor, Kind.REFL_CLASS_NEWINSTANCE); } } } }
public SootMethod getMethodUnsafe(String subsignature) { checkLevel(SIGNATURES); NumberedString numberedString = Scene.v().getSubSigNumberer().find(subsignature); return numberedString == null ? null : getMethodUnsafe(numberedString); }
public SootMethod grabMethod(String methodSignature) { String cname = signatureToClass(methodSignature); String mname = signatureToSubsignature(methodSignature); if (!containsClass(cname)) { return null; } SootClass c = getSootClass(cname); return c.getMethodUnsafe(mname); }
@Override public void classNewInstance(SootMethod source, Stmt s) { if (options.safe_newinstance()) { for (SootMethod tgt : EntryPoints.v().inits()) { addEdge(source, s, tgt, Kind.NEWINSTANCE); } } else { for (SootClass cls : Scene.v().dynamicClasses()) { SootMethod sm = cls.getMethodUnsafe(sigInit); if (sm != null) { addEdge(source, s, sm, Kind.NEWINSTANCE); } } if (options.verbose()) { logger.warn("Method " + source + " is reachable, and calls Class.newInstance;" + " graph will be incomplete!" + " Use safe-newinstance option for a conservative result."); } } }
/** * Given an object of actual type C (o = new C()), returns the method which will be called on an o.f() invocation. */ public SootMethod resolveConcreteDispatch(SootClass concreteType, SootMethod m) { concreteType.checkLevel(SootClass.HIERARCHY); if (concreteType.isInterface()) { throw new RuntimeException("A concrete type cannot be an interface: " + concreteType); } String methodSig = m.getSubSignature(); while (true) { SootMethod method = concreteType.getMethodUnsafe(methodSig); if (method != null) { if (isVisible(concreteType, m)) { if (method.isAbstract()) { throw new RuntimeException("Error: Method call resolves to abstract method!"); } return method; } } concreteType = concreteType.getSuperclassUnsafe(); if (concreteType == null) { break; } } // When there is no proper dispatch found, we simply return null to let // the caller decide what to do return null; // throw new RuntimeException("could not resolve concrete // dispatch!\nType: "+concreteType+"\nMethod: "+m); }
/** * Given an object of actual type C (o = new C()), returns the method which will be called on an o.f() invocation. */ public SootMethod resolveConcreteDispatch(SootClass concreteType, SootMethod m) { concreteType.checkLevel(SootClass.HIERARCHY); m.getDeclaringClass().checkLevel(SootClass.HIERARCHY); checkState(); if (concreteType.isInterface()) { throw new RuntimeException("class needed!"); } String methodSig = m.getSubSignature(); for (SootClass c : getSuperclassesOfIncluding(concreteType)) { SootMethod sm = c.getMethodUnsafe(methodSig); if (sm != null && isVisible(c, m)) { return sm; } } throw new RuntimeException("could not resolve concrete dispatch!\nType: " + concreteType + "\nMethod: " + m); }
SootMethod sm = mSootClass.getMethodUnsafe(SootMethod.getSubSignature(name, parameterList, type)); if (sm != null) { if (Options.v().verbose()) {
final SootMethod method = selectedClass.getMethodUnsafe(name, parameterTypes, returnType); if (method != null) { checkStatic(method); final SootMethod method = iface.getMethodUnsafe(name, parameterTypes, returnType); if (method != null) { checkStatic(method);
/** * Returns true if this method itself is visible to the client and overwriteable or if the same holds for any of the * methods in the library that overwrite the argument method. * * @see #clientOverwriteable(SootMethod) */ private static boolean clientOverwriteableOverwrites(SootMethod m) { if (clientOverwriteable(m)) { return true; } SootClass c = m.getDeclaringClass(); // TODO could use PTA and call graph to filter subclasses further for (SootClass cPrime : Scene.v().getFastHierarchy().getSubclassesOf(c)) { SootMethod mPrime = cPrime.getMethodUnsafe(m.getSubSignature()); if (mPrime != null) { if (clientOverwriteable(mPrime)) { return true; } } } return false; }
public SootMethod resolveNonSpecial(RefType t, NumberedString subSig, boolean appOnly) { SmallNumberedMap<SootMethod> vtbl = typeToVtbl.get(t); if (vtbl == null) { typeToVtbl.put(t, vtbl = new SmallNumberedMap<SootMethod>()); } SootMethod ret = vtbl.get(subSig); if (ret != null) { return ret; } SootClass cls = t.getSootClass(); if (appOnly && cls.isLibraryClass()) { return null; } SootMethod m = cls.getMethodUnsafe(subSig); if (m != null) { if (!m.isAbstract()) { ret = m; } } else { SootClass c = cls.getSuperclassUnsafe(); if (c != null) { ret = resolveNonSpecial(c.getType(), subSig); } } vtbl.put(subSig, ret); return ret; }
/** * Retrieve the SootMethod equivalent of this method * * @return the SootMethod of this method */ public SootMethod makeSootMethod(final Method method) { int accessFlags = method.getAccessFlags(); // get the name of the method String name = method.getName(); List<SootClass> thrownExceptions = getThrownExceptions(method); List<Type> parameterTypes = getParameterTypes(method); // retrieve the return type of this method Type returnType = DexType.toSoot(method.getReturnType()); // Build soot method by all available parameters SootMethod sm = declaringClass.getMethodUnsafe(name, parameterTypes, returnType); if (sm == null) { sm = Scene.v().makeSootMethod(name, parameterTypes, returnType, accessFlags, thrownExceptions); } // if the method is abstract or native, no code needs to be transformed int flags = method.getAccessFlags(); if (Modifier.isAbstract(flags) || Modifier.isNative(flags)) { return sm; } if (Options.v().oaat() && declaringClass.resolvingLevel() <= SootClass.SIGNATURES) { return sm; } // sets the method source by adding its body as the active body sm.setSource(createMethodSource(method)); return sm; }