/** * Returns the parameters part of the signature in the format in which it appears in bytecode. */ public String getBytecodeParms() { StringBuffer buffer = new StringBuffer(); for (Iterator<Type> typeIt = getParameterTypes().iterator(); typeIt.hasNext();) { final Type type = typeIt.next(); buffer.append(AbstractJasminClass.jasminDescriptorOf(type)); } return buffer.toString().intern(); }
@Override protected boolean acceptMethod(SootMethod n) { int nParams = n.getParameterCount(); if (methodSizes != null) { // if the arg array can be null we have to still allow for // nullary methods boolean compatibleSize = methodSizes.get(nParams) || (!mustNotBeNull && nParams == 0); if (!compatibleSize) { return false; } } List<Type> t = n.getParameterTypes(); for (Type pTy : t) { if (!isReflectionCompatible(pTy, reachingTypes)) { return false; } } return true; }
/** * Does this class declare a method with the given name and parameter types? */ public boolean declaresMethod(String name, List<Type> parameterTypes) { checkLevel(SIGNATURES); if (methodList == null) { return false; } for (SootMethod method : methodList) { if (method.getName().equals(name) && method.getParameterTypes().equals(parameterTypes)) { return true; } } return false; }
private Set<SootClass> getDeclaringClasses(SootClass applicationClass, SootMethod method) { return getTree(applicationClass).stream() .filter(sootClass -> isDeclared(sootClass, method.getName(), method.getParameterTypes())).collect(toSet()); }
/** * Attempts to retrieve the method with the given name and parameters. This method may throw an AmbiguousMethodException if * there is more than one method with the given name and parameter. */ public SootMethod getMethod(String name, List<Type> parameterTypes) { checkLevel(SIGNATURES); SootMethod foundMethod = null; if (methodList == null) { return null; } for (SootMethod method : methodList) { if (method.getName().equals(name) && parameterTypes.equals(method.getParameterTypes())) { if (foundMethod == null) { foundMethod = method; } else { throw new RuntimeException("ambiguous method"); } } } if (foundMethod == null) { throw new RuntimeException("couldn't find method " + name + "(" + parameterTypes + ") in " + this); } return foundMethod; }
/** * Does this class declare a method with the given name, parameter types, and return type? */ public boolean declaresMethod(String name, List<Type> parameterTypes, Type returnType) { checkLevel(SIGNATURES); if (methodList == null) { return false; } for (SootMethod method : methodList) { if (method.getName().equals(name) && method.getParameterTypes().equals(parameterTypes) && method.getReturnType().equals(returnType)) { return true; } } return false; }
/** * Attempts to retrieve the method with the given name, parameters and return type. If no matching method can be found, * null is returned. */ public SootMethod getMethodUnsafe(String name, List<Type> parameterTypes, Type returnType) { checkLevel(SIGNATURES); if (methodList == null) { return null; } for (SootMethod method : methodList) { if (method.getName().equals(name) && parameterTypes.equals(method.getParameterTypes()) && returnType.equals(method.getReturnType())) { return method; } } return null; }
private void addQualifierRefToInit(polyglot.types.Type type) { soot.Type sootType = Util.getSootType(type); Iterator it = sootClass.getMethods().iterator(); while (it.hasNext()) { soot.SootMethod meth = (soot.SootMethod) it.next(); if (meth.getName().equals("<init>")) { List newParams = new ArrayList(); newParams.add(sootType); newParams.addAll(meth.getParameterTypes()); meth.setParameterTypes(newParams); meth.addTag(new soot.tagkit.QualifyingTag()); } } }
public void caseDynamicInvokeInst(DynamicInvokeInst i) { SootMethod m = i.getMethod(); Object args[] = m.getParameterTypes().toArray(); remove_types = new Type[args.length]; for (int ii = 0; ii < args.length; ii++) { remove_types[ii] = (Type) args[ii]; } if (m.getReturnType() instanceof VoidType) { add_types = null; } else { add_types = new Type[] { m.getReturnType() }; } }
public void caseStaticInvokeInst(StaticInvokeInst i) { SootMethod m = i.getMethod(); Object args[] = m.getParameterTypes().toArray(); remove_types = new Type[args.length]; for (int ii = 0; ii < args.length; ii++) { remove_types[ii] = (Type) args[ii]; } if (m.getReturnType() instanceof VoidType) { add_types = null; } else { add_types = new Type[] { m.getReturnType() }; } }
private void instanceinvoke(MethodArgInst i) { SootMethod m = i.getMethod(); int length = m.getParameterCount(); remove_types = new Type[length + 1]; remove_types[0] = RefType.v(); System.arraycopy(m.getParameterTypes().toArray(), 0, remove_types, 1, length); if (m.getReturnType() instanceof VoidType) { add_types = null; } else { add_types = new Type[] { m.getReturnType() }; } }
/** * Returns the Soot subsignature of this method. Used to refer to methods unambiguously. */ public String getSubSignature() { if (subSig == null) { synchronized (this) { if (subSig == null) { subSig = getSubSignatureImpl(getName(), getParameterTypes(), getReturnType()); } } } return subSig; }
@Override public void validate(SootClass sc, List<ValidationException> exceptions) { if (sc.isConcrete()) { for (SootMethod sm : sc.getMethods()) { for (Type tp : sm.getParameterTypes()) { if (tp == null) { exceptions.add(new ValidationException(sm, "Null parameter types are invalid")); } if (tp instanceof VoidType) { exceptions.add(new ValidationException(sm, "Void parameter types are invalid")); } if (!tp.isAllowedInFinalCode()) { exceptions.add(new ValidationException(sm, "Parameter type not allowed in final code")); } } } } }
private void addOuterClassThisRefToInit(polyglot.types.Type outerType) { soot.Type outerSootType = Util.getSootType(outerType); Iterator it = sootClass.getMethods().iterator(); while (it.hasNext()) { soot.SootMethod meth = (soot.SootMethod) it.next(); if (meth.getName().equals("<init>")) { List newParams = new ArrayList(); newParams.add(outerSootType); newParams.addAll(meth.getParameterTypes()); meth.setParameterTypes(newParams); meth.addTag(new soot.tagkit.EnclosingTag()); if (InitialResolver.v().getHasOuterRefInInit() == null) { InitialResolver.v().setHasOuterRefInInit(new ArrayList()); } InitialResolver.v().getHasOuterRefInInit().add(meth.getDeclaringClass().getType()); } } }
@SuppressWarnings("unchecked") public static boolean noRefTypeParameters(SootMethod method) { if (!method.isStatic()) { return false; } Predicate<Type> notRefTypePred = new Predicate<Type>() { @Override public boolean test(Type obj_) { return !(obj_ instanceof RefType) && !(obj_ instanceof ArrayType); } }; return notRefTypePred.test(method.getReturnType()) && soot.jimple.spark.ondemand.genericutil.Util.forAll(method.getParameterTypes(), notRefTypePred); }
private void addFinals(polyglot.types.LocalInstance li, ArrayList<SootField> finalFields) { // add as param for init for (SootMethod meth : sootClass.getMethods()) { if (meth.getName().equals("<init>")) { List<soot.Type> newParams = new ArrayList<soot.Type>(); newParams.addAll(meth.getParameterTypes()); newParams.add(Util.getSootType(li.type())); meth.setParameterTypes(newParams); } } // add field soot.SootField sf = Scene.v().makeSootField("val$" + li.name(), Util.getSootType(li.type()), soot.Modifier.FINAL | soot.Modifier.PRIVATE); sootClass.addField(sf); finalFields.add(sf); sf.addTag(new soot.tagkit.SyntheticTag()); }
@Override public void validate(Body body, List<ValidationException> exceptions) { SootMethod method = body.getMethod(); if (method != null) { if (!method.getReturnType().isAllowedInFinalCode()) { exceptions.add(new ValidationException(method, "Return type not allowed in final code: " + method.getReturnType(), "return type not allowed in final code:" + method.getReturnType() + "\n method: " + method)); } for (Type t : method.getParameterTypes()) { if (!t.isAllowedInFinalCode()) { exceptions.add(new ValidationException(method, "Parameter type not allowed in final code: " + t, "parameter type not allowed in final code:" + t + "\n method: " + method)); } } } for (Local l : body.getLocals()) { Type t = l.getType(); if (!t.isAllowedInFinalCode()) { exceptions.add(new ValidationException(l, "Local type not allowed in final code: " + t, "(" + method + ") local type not allowed in final code: " + t + " local: " + l)); } } }
/** * Loads a single method from a dex file * * @param method * The method to load * @param declaringClass * The class that declares the method to load * @param annotations * The worker object for handling annotations * @param dexMethodFactory * The factory method for creating dex methods */ protected void loadMethod(Method method, SootClass declaringClass, DexAnnotation annotations, DexMethod dexMethodFactory) { SootMethod sm = dexMethodFactory.makeSootMethod(method); if (declaringClass.declaresMethod(sm.getName(), sm.getParameterTypes(), sm.getReturnType())) { return; } declaringClass.addMethod(sm); annotations.handleMethodAnnotation(sm, method); }
private void emitLocals() { JimpleBody jb = body; SootMethod m = jb.getMethod(); Collection<Local> jbl = jb.getLocals(); Collection<Unit> jbu = jb.getUnits(); int iloc = 0; if (!m.isStatic()) { Local l = getLocal(iloc++); jbu.add(Jimple.v().newIdentityStmt(l, Jimple.v().newThisRef(m.getDeclaringClass().getType()))); } int nrp = 0; for (Object ot : m.getParameterTypes()) { Type t = (Type) ot; Local l = getLocal(iloc); jbu.add(Jimple.v().newIdentityStmt(l, Jimple.v().newParameterRef(t, nrp++))); if (AsmUtil.isDWord(t)) { iloc += 2; } else { iloc++; } } for (Local l : locals.values()) { jbl.add(l); } }
protected void bringToSignaturesUnchecked(SootClass sc) { for (SootField f : sc.getFields()) { addToResolveWorklist(f.getType(), SootClass.HIERARCHY); } for (SootMethod m : sc.getMethods()) { addToResolveWorklist(m.getReturnType(), SootClass.HIERARCHY); for (Type ptype : m.getParameterTypes()) { addToResolveWorklist(ptype, SootClass.HIERARCHY); } List<SootClass> exceptions = m.getExceptionsUnsafe(); if (exceptions != null) { for (SootClass exception : exceptions) { addToResolveWorklist(exception, SootClass.HIERARCHY); } } } // Bring superclasses to signatures reResolveHierarchy(sc, SootClass.SIGNATURES); }