@Override public Collection<Pair<AccessGraph, EdgeFunction<TypestateDomainValue>>> generate(Unit unit, Collection<SootMethod> calledMethod) { boolean matches = false; for (SootMethod method : calledMethod) { if (initialTrans.matches(method)) { matches = true; } } if (!matches) return Collections.emptySet(); if (unit instanceof Stmt && ((Stmt) unit).getInvokeExpr() instanceof InstanceInvokeExpr) { InstanceInvokeExpr iie = (InstanceInvokeExpr) ((Stmt) unit).getInvokeExpr(); Set<Pair<AccessGraph, EdgeFunction<TypestateDomainValue>>> out = new HashSet<>(); out.add(new Pair<AccessGraph, EdgeFunction<TypestateDomainValue>>( new AccessGraph((Local) iie.getBase(), iie.getBase().getType()), new TransitionFunction(initialTrans))); return out; } return Collections.emptySet(); }
protected Collection<Pair<AccessGraph, EdgeFunction<TypestateDomainValue>>> generateAtConstructor(Unit unit, Collection<SootMethod> calledMethod, MatcherTransition initialTrans) { boolean matches = false; for (SootMethod method : calledMethod) { if (initialTrans.matches(method)) { matches = true; } } if (!matches) return Collections.emptySet(); if (unit instanceof Stmt) { Stmt stmt = (Stmt) unit; if (stmt.containsInvokeExpr()) if (stmt.getInvokeExpr() instanceof InstanceInvokeExpr) { InstanceInvokeExpr iie = (InstanceInvokeExpr) stmt.getInvokeExpr(); if (iie.getBase() instanceof Local) { Local l = (Local) iie.getBase(); Set<Pair<AccessGraph, EdgeFunction<TypestateDomainValue>>> out = new HashSet<>(); out.add(new Pair<AccessGraph, EdgeFunction<TypestateDomainValue>>( new AccessGraph(l, l.getType()), new TransitionFunction(initialTrans))); return out; } } } return Collections.emptySet(); }
protected Collection<Pair<AccessGraph, EdgeFunction<TypestateDomainValue>>> generateThisAtAnyCallSitesOf(Unit unit, Collection<SootMethod> calledMethod, Set<SootMethod> hasToCall, MatcherTransition initialTrans) { for (SootMethod callee : calledMethod) { if (hasToCall.contains(callee)) { if (unit instanceof Stmt) { if (((Stmt) unit).getInvokeExpr() instanceof InstanceInvokeExpr) { InstanceInvokeExpr iie = (InstanceInvokeExpr) ((Stmt) unit).getInvokeExpr(); Local thisLocal = (Local) iie.getBase(); Set<Pair<AccessGraph, EdgeFunction<TypestateDomainValue>>> out = new HashSet<>(); out.add(new Pair<AccessGraph, EdgeFunction<TypestateDomainValue>>( new AccessGraph(thisLocal, thisLocal.getType()), new TransitionFunction(initialTrans))); return out; } } } } return Collections.emptySet(); }
static String formatInstanceInvoke(InstanceInvokeExpr v) { StringBuilder sb = new StringBuilder(); sb.append(v.getBase().toString()).append(".<") .append(shorten(v.getBase().getType().toString())) .append(": ").append(shorten(v.getMethod().getReturnType().toString())) .append(' ').append(v.getMethod().getName()).append('('); for (int i = 0; i < v.getArgCount(); i++) { if (i != 0) { sb.append(", "); } sb.append(shorten(v.getArg(i).getType().toString())); } sb.append(")>("); for (int i = 0; i < v.getArgCount(); i++) { if (i != 0) { sb.append(", "); } sb.append(format(v.getArg(i))); } sb.append(')'); return sb.toString(); }
private Set<FlowAbstraction> taintApiDefault(Unit call, FlowAbstraction source, Stmt stmt, Set<FlowAbstraction> outSet) { final List<Value> args = stmt.getInvokeExpr().getArgs(); final Local baseLocal = stmt.getInvokeExpr() instanceof InstanceInvokeExpr ? (Local) ((InstanceInvokeExpr) stmt.getInvokeExpr()).getBase() : null; Local receiver = null; if (stmt instanceof AssignStmt) receiver = (Local) ((AssignStmt) stmt).getLeftOp(); Set<FlowAbstraction> ret = new HashSet<FlowAbstraction>(); // If a parameter is tainted, we taint the base local and the receiver if (source.getLocal() != null && args.contains(source.getLocal())) { if (baseLocal != null && !baseLocal.toString().equals("this")) ret.add(FlowAbstraction.v(source.getSource(), baseLocal, call, icfg.getMethodOf(call), source)); if (receiver != null) ret.add(FlowAbstraction.v(source.getSource(), receiver, call, icfg.getMethodOf(call), source)); } // If the base local is tainted, we taint the receiver if (baseLocal != null && source.getLocal() == baseLocal && receiver != null) ret.add(FlowAbstraction.v(source.getSource(), receiver, call, icfg.getMethodOf(call), source)); return ret; }
@Override public boolean isExclusiveInternal(Stmt stmt, AccessPath taintedPath) { SootMethod method = stmt.getInvokeExpr().getMethod(); // Do we have an entry for at least one entry in the given class? if (hasWrappedMethodsForClass(method.getDeclaringClass(), true, true, true)) return true; // In aggressive mode, we always taint the return value if the base // object is tainted. if (aggressiveMode && stmt.getInvokeExpr() instanceof InstanceInvokeExpr) { InstanceInvokeExpr iiExpr = (InstanceInvokeExpr) stmt.getInvokeExpr(); if (iiExpr.getBase().equals(taintedPath.getPlainValue())) return true; } final MethodWrapType wrapType = methodWrapCache.getUnchecked(method); return wrapType != MethodWrapType.NotRegistered; }
@Override public boolean supportsCallee(Stmt callSite) { // We need an invocation expression if (!callSite.containsInvokeExpr()) return false; SootMethod method = callSite.getInvokeExpr().getMethod(); if (!supportsCallee(method)) return false; // We need a method that can create a taint if (!aggressiveMode) { // Check for a cached wrap type final MethodWrapType wrapType = methodWrapCache.getUnchecked(method); if (wrapType != MethodWrapType.CreateTaint) return false; } // We need at least one non-constant argument or a tainted base if (callSite.getInvokeExpr() instanceof InstanceInvokeExpr) return true; for (Value val : callSite.getInvokeExpr().getArgs()) if (!(val instanceof Constant)) return true; return false; }
boolean handleSpecialCall(InstanceInvokeExpr expr, SootMethod target) { String mn = target.getName(); int np = target.getParameterCount(); SootClass dc = target.getDeclaringClass(); // Is it a method in a Foo object? if (isFoo(dc)) { if (mn.equals("foo") && np == 1){ Variable lvar = new Variable(Variable.Type.FOO); Method foo = new Method("foo", new Variable[0]); FooMethodCall fmc = new FooMethodCall(foo); fmc.setAssignmentTarget(lvar); st.addStatement(fmc); return true; } // Unknown Foo method return false; } // Not a special call return false; }
/** * Obtain the set of possible call targets at given @param callsite. */ private void getCallTargets(IVarAbstraction pn, SootMethod src, Stmt callsite, ChunkedQueue<SootMethod> targetsQueue) { InstanceInvokeExpr iie = (InstanceInvokeExpr)callsite.getInvokeExpr(); Local receiver = (Local)iie.getBase(); NumberedString subSig = iie.getMethodRef().getSubSignature(); // We first build the set of possible call targets for (AllocNode an : pn.get_all_points_to_objects()) { Type type = an.getType(); if (type == null) continue; VirtualCalls.v().resolve(type, receiver.getType(), subSig, src, targetsQueue); } }
/** * Determines if an instance field should be propagated through a method call. This method only * checks propagation rule for the field base. It does not check if the field points to an * argument, which should be done outside this method. * * @param instanceFieldRef An instance field reference. * @param invokeExpr An invoke expression for the called method. * @return True if the field should be propagated. */ public static boolean shouldPropagateInstanceField(InstanceFieldRef instanceFieldRef, InvokeExpr invokeExpr) { Value fieldBase = instanceFieldRef.getBase(); List<Value> argList = invokeExpr.getArgs(); // A field reference should be propagated if the base of the field points to a method argument. for (int i = 0; i < argList.size(); ++i) { if (sourcePointsToArgument(fieldBase, argList.get(i))) { return true; } } // A field reference should be propagated if the base of the field points to the base of the // method call for an instance call. if (invokeExpr instanceof InstanceInvokeExpr) { Value invokeExprBase = ((InstanceInvokeExpr) invokeExpr).getBase(); if (sourcePointsToArgument(fieldBase, invokeExprBase)) { return true; } } return false; }
/** * Registers default method return value analyses. */ public void registerDefaultMethodReturnValueAnalyses() { registerMethodReturnValueAnalysis("java.lang.String getName()", new MethodReturnValueAnalysis() { @Override public Set<Object> computeMethodReturnValues(Call call) { InvokeExpr invokeExpr = call.stmt.getInvokeExpr(); if (invokeExpr instanceof InstanceInvokeExpr) { InstanceInvokeExpr instanceInvokeExpr = (InstanceInvokeExpr) invokeExpr; if (invokeExpr.getMethod().getDeclaringClass().getName().equals("java.lang.Class")) { return ArgumentValueManager.v() .getArgumentValueAnalysis(Constants.DefaultArgumentTypes.Scalar.CLASS) .computeVariableValues(instanceInvokeExpr.getBase(), call.stmt); } } return null; } }); }
@Override public Set<AccessPath> getTaintsForMethod(Stmt stmt, AccessPath taintedPath) { // method add + added element is tainted -> whole list is tainted if(stmt.getInvokeExpr().getMethod().getSubSignature().equals("boolean add(java.lang.Object)")) if (taintedPath.getPlainValue().equals(stmt.getInvokeExpr().getArg(0))) return Collections.singleton(new AccessPath(((InstanceInvokeExpr) stmt.getInvokeExprBox().getValue()).getBase())); // method get + whole list is tainted -> returned element is tainted if(stmt.getInvokeExpr().getMethod().getSubSignature().equals("java.lang.Object get(int)")) if (stmt.getInvokeExpr() instanceof InstanceInvokeExpr) { InstanceInvokeExpr iiExpr = (InstanceInvokeExpr) stmt.getInvokeExpr(); if (taintedPath.getPlainValue().equals(iiExpr.getBase())) if(stmt instanceof JAssignStmt) return Collections.singleton(new AccessPath(((JAssignStmt)stmt).getLeftOp())); } // For the moment, we don't implement static taints on wrappers. Pass it on // not to break anything if(taintedPath.isStaticFieldRef()) return Collections.singleton(taintedPath); return Collections.emptySet(); }
/** * Gives the type of all the broadcast receiver that may be aborted. It looks at all the calls to abortBroadcast and through the Points-to analysis at the * actual class of the base arguments of the calls. * @return a set of soot type that may be empty. */ private Set<String> abortedBroadcastsTypes() { Set <String> result = new HashSet<String>(); try { SootClass receiverClass = scene.getSootClass(ANDROID_CONTENT_BROADCASTRECEIVER); SootMethod abortMethod = receiverClass.getMethod(BROADCAST_ABORT_SIGNATURE); Iterator<Edge> edges = cg.edgesInto(abortMethod); while(edges.hasNext()) { Edge edge = edges.next(); InvokeExpr ie = edge.srcStmt().getInvokeExpr(); if (ie == null || ! (ie instanceof InstanceInvokeExpr)) continue; Value base = ((InstanceInvokeExpr) ie).getBase(); if (!(base instanceof Local)) continue; PointsToSet basePTS = pag.reachingObjects((Local) base); addAll(result,basePTS.possibleTypes()); } } catch (RuntimeException e) { Out.getLog().println("Error while computing aborted broadcast " + e.getMessage()); } return result; }
@Override public KillGenInfo processBackwardCallToReturn(Trackable taint, Stmt callSite, InvokeExpr ie) { SootMethod method = ie.getMethod(); List<Taint> taints = Lists.newLinkedList(); if (ie instanceof InstanceInvokeExpr) { Value receiver = ((InstanceInvokeExpr) ie).getBase(); taints.add(new Taint(callSite, taint, receiver, receiver.getType())); } for (int i = 0; i < method.getParameterCount(); i++) { Type parameterType = method.getParameterType(i); if (!(parameterType instanceof PrimType) && !(ie.getArg(i) instanceof Constant)) { taints.add(new Taint(callSite, taint, ie.getArg(i), parameterType)); } } if (taints.isEmpty()) return kill(); else return propagate(taints.toArray(new Taint[taints.size()])); }
@Override public Map<Local, SignAnalysis.Sign> callEntryFlowFunction( Context<SootMethod, Unit, Map<Local, SignAnalysis.Sign>> context, SootMethod calledMethod, Unit unit, Map<Local, SignAnalysis.Sign> inValue) { // Initialise result to empty map Map<Local, SignAnalysis.Sign> entryValue = topValue(); // Map arguments to parameters InvokeExpr ie = ((Stmt) unit).getInvokeExpr(); for (int i = 0; i < ie.getArgCount(); i++) { Value arg = ie.getArg(i); Local param = calledMethod.getActiveBody().getParameterLocal(i); assign(param, arg, inValue, entryValue); } // And instance of the this local if (ie instanceof InstanceInvokeExpr) { Value instance = ((InstanceInvokeExpr) ie).getBase(); Local thisLocal = calledMethod.getActiveBody().getThisLocal(); assign(thisLocal, instance, inValue, entryValue); } // Return the entry value at the called method return entryValue; }
@Override public Map<Local, Constant> callEntryFlowFunction(Context<SootMethod, Unit, Map<Local, Constant>> context, SootMethod calledMethod, Unit unit, Map<Local, Constant> inValue) { // Initialise result to empty map Map<Local, Constant> entryValue = topValue(); // Map arguments to parameters InvokeExpr ie = ((Stmt) unit).getInvokeExpr(); for (int i = 0; i < ie.getArgCount(); i++) { Value arg = ie.getArg(i); Local param = calledMethod.getActiveBody().getParameterLocal(i); assign(param, arg, inValue, entryValue); } // And instance of the this local if (ie instanceof InstanceInvokeExpr) { Value instance = ((InstanceInvokeExpr) ie).getBase(); Local thisLocal = calledMethod.getActiveBody().getThisLocal(); assign(thisLocal, instance, inValue, entryValue); } // Return the entry value at the called method return entryValue; }
@Override protected void internalTransform(Body b, String phaseName, Map<String, String> options) { // Do not instrument methods in framework classes if (!canInstrumentMethod(b.getMethod())) return; // Check for calls to DexFile.loadClass for (Iterator<Unit> unitIt = b.getUnits().snapshotIterator(); unitIt.hasNext(); ) { Stmt stmt = (Stmt) unitIt.next(); if (stmt.hasTag(InstrumentedCodeTag.name)) continue; if (!(stmt instanceof AssignStmt)) continue; AssignStmt assignStmt = (AssignStmt) stmt; if (stmt.containsInvokeExpr()) { InvokeExpr iexpr = stmt.getInvokeExpr(); if (iexpr.getMethod() == methodDexFileLoadClass) { List<Value> args = new ArrayList<>(); args.add(((InstanceInvokeExpr) iexpr).getBase()); args.addAll(iexpr.getArgs()); InvokeExpr newLoadExpr = Jimple.v().newStaticInvokeExpr(methodOwnLoader.makeRef(), args); b.getUnits().swapWith(stmt, Jimple.v().newAssignStmt(assignStmt.getLeftOp(), newLoadExpr)); } } } }
@Override public FlowFunction<WrappedAccessGraph> getCallToReturnFlowFunction(WrappedAccessGraph sourceFact, final Unit callStmt, Unit returnSite, boolean hasCallees) { if (!hasCallees) { return Identity.v(); } if (!(callStmt instanceof Stmt)) { return Identity.v(); } Stmt callSite = (Stmt) callStmt; if (!callSite.containsInvokeExpr()) { return Identity.v(); } final InvokeExpr invokeExpr = callSite.getInvokeExpr(); final SootMethod callee = invokeExpr.getMethod(); return new FlowFunction<WrappedAccessGraph>() { @Override public Set<WrappedAccessGraph> computeTargets(WrappedAccessGraph source) { for (int i = 0; i < invokeExpr.getArgCount(); i++) { if (source.baseMatches(invokeExpr.getArg(i))) { return Collections.emptySet(); } } if (invokeExpr instanceof InstanceInvokeExpr) { InstanceInvokeExpr iie = (InstanceInvokeExpr) invokeExpr; Value base = iie.getBase(); if (source.baseMatches(base)) { return Collections.emptySet(); } } return Collections.singleton(source); } }; }
@Override public Collection<Pair<AccessGraph, EdgeFunction<TypestateDomainValue>>> generate(Unit unit, Collection<SootMethod> calledMethod) { boolean matches = false; for (SootMethod method : calledMethod) { if (initialTrans.matches(method) && !initialTrans.matches(icfg.getMethodOf(unit))) { matches = true; } } if (!matches || icfg.getMethodOf(unit).getSignature().equals("<java.lang.ClassLoader: void <clinit>()>")) return Collections.emptySet(); if (unit instanceof Stmt) { Stmt stmt = (Stmt) unit; if (stmt.containsInvokeExpr()) if (stmt.getInvokeExpr() instanceof InstanceInvokeExpr) { InstanceInvokeExpr iie = (InstanceInvokeExpr) stmt.getInvokeExpr(); if (iie.getBase() instanceof Local) { Local l = (Local) iie.getBase(); Set<Pair<AccessGraph, EdgeFunction<TypestateDomainValue>>> out = new HashSet<>(); out.add(new Pair<AccessGraph, EdgeFunction<TypestateDomainValue>>( new AccessGraph(l, l.getType()), new TransitionFunction(initialTrans))); return out; } } } return Collections.emptySet(); }
static String formatInvoke(Value v) { if(v instanceof InstanceInvokeExpr) { return formatInstanceInvoke((InstanceInvokeExpr) v); } String s = v.toString(); s = s.replaceAll("virtualinvoke ", ""); s = s.replaceAll("specialinvoke ", ""); s = s.replaceAll("staticinvoke ", ""); s = shortenClassNames(s); return s; }
private void checkUri(Body b, Unit u) { // check if an argument is an Uri Value pUri = null; Stmt s = (Stmt) u; InvokeExpr ie = s.getInvokeExpr(); InstanceInvokeExpr iie = (InstanceInvokeExpr) ie; logger.debug("same base for init..."); int i = 0; for (Type pt : iie.getMethod().getParameterTypes()) { logger.debug("type: ", pt); if (pt.toString().equals("android.net.Uri")) { pUri = iie.getArg(i); break; } i++; } if (pUri == null) { System.out.println("warning: no Uri parameter"); } if (pUri instanceof Local) { logger.debug("uri is local..."); String auth = findUriDef(b, u, (Local) pUri); if (auth != null) { Provider.createJimple(b, u, ie.getMethod(), auth); } } else { throw new RuntimeException("error: not local referencing uri!"); } }
private void replaceStart(Body b, Unit unit) { System.out.println("replace start: " + unit); // Suppose we have r1.<Thread start()> // The first step is to find parameter p in // r1.<Thread <init>(p)> Stmt stmt = (Stmt) unit; InvokeExpr iexpr = stmt.getInvokeExpr(); InstanceInvokeExpr iiexpr = (InstanceInvokeExpr) iexpr; Value base = iiexpr.getBase(); Type bType = getTypeOfBase(b, (Local) base, unit); if (bType == null) { System.out.println("warning: null thread type, just removing start()."); } Util.removeUnit(b, unit); return; // if (bType.toString().equals("java.lang.Thread")) { // System.out.println("find runnable type:"); // // findRunnableType(); // } // // // // // p is of type runnable, so the second step // // is to find the real type of p }
private void findRunnableType(Body b, Unit newThread) { AssignStmt ass = (AssignStmt) newThread; Local base = (Local) ass.getLeftOp(); Unit tu = null; Value runnableArg = null; for (Unit u : b.getUnits()) { Stmt s = (Stmt) u; if (s.containsInvokeExpr()) { InvokeExpr ie = s.getInvokeExpr(); String ieSig = ie.getMethodRef().getSignature(); if (ieSig.startsWith(threadInitSSig)) { InstanceInvokeExpr iie = (InstanceInvokeExpr) ie; if (iie.getBase() == base) { System.out.println("same base for init..."); int i = 0; for (Type pt : iie.getMethod().getParameterTypes()) { System.out.println("type: " + pt); if (pt.toString().equals("java.lang.Runnable")) { tu = u; runnableArg = iie.getArg(i); break; } i++; } } } } } // we do this outside the loop so we can add units if (tu != null && runnableArg != null && runnableArg instanceof Local) { findRunnableDef(b, (Local) runnableArg, tu); } }
/** * Explicitly handles String.getChars() which does not really fit our * declarative model * @param invokeExpr The invocation of String.getChars() * @param taintedPath The tainted access path * @return The set of new taints to pass on in the taint propagation */ private Set<AccessPath> handleStringGetChars(InvokeExpr invokeExpr, AccessPath taintedPath) { // If the base object is tainted, the third argument gets tainted as // well if (((InstanceInvokeExpr) invokeExpr).getBase() == taintedPath.getPlainValue()) return new TwoElementSet<AccessPath>(taintedPath, new AccessPath( invokeExpr.getArg(2), true)); return Collections.singleton(taintedPath); }
void caseInstanceInvokeExpr(InstanceInvokeExpr expr) { List<SootMethod> targets = jt.getTargetsOf(expr); if (targets.isEmpty()) { // This is a call to an interface method or abstract method // with no available implementations. // You could use instruction target as target. jt.notSupported("We don't support abstract methods"); } for (SootMethod target: targets) { boolean special = handleSpecialCall(expr, target); if (!special) { handleCall(expr, target); } } }
public List<SootMethod> getTargetsOf(InvokeExpr expr) { if (expr instanceof InstanceInvokeExpr) { return getTargetsOf(((InstanceInvokeExpr)expr).getBase(), expr.getMethod()); } List<SootMethod> targets = new ArrayList(1); targets.add(expr.getMethod()); return targets; }
private void printInvokeExpr(InvokeExpr v) { p.openBlock(); String oldName = varName; SootMethodRef method = v.getMethodRef(); SootMethod m = method.resolve(); if(!m.isStatic()) { Local base= (Local)((InstanceInvokeExpr)v).getBase(); p.println("Local base = localByName(b,\"" + base.getName()+ "\");"); } p.println("List<Type> parameterTypes = new LinkedList<Type>();"); int i=0; for(Type t: (List<Type>)m.getParameterTypes()) { ttp.setVariableName("type"+i); t.apply(ttp); p.println("parameterTypes.add(type"+i+");"); i++; } ttp.setVariableName("returnType"); m.getReturnType().apply(ttp); p.print("SootMethodRef methodRef = "); p.printNoIndent("Scene.v().makeMethodRef("); String className = m.getDeclaringClass().getName(); p.printNoIndent("Scene.v().getSootClass(\""+className+"\"),"); p.printNoIndent("\""+m.getName()+"\","); p.printNoIndent("parameterTypes,"); p.printNoIndent("returnType,"); p.printlnNoIndent(m.isStatic()+");"); printExpr(v, "base", "methodRef"); varName = oldName; p.closeBlock(); }
public void defaultFeedPtsRoutines() { switch (Parameters.seedPts) { case Constants.seedPts_allUser: setAllUserCodeVariablesUseful(); break; case Constants.seedPts_all: // All pointers will be processed for (int i = 0; i < n_var; ++i) { IVarAbstraction pn = int2var.get(i); if ( pn != null && pn.getRepresentative() == pn ) pn.willUpdate = true; } return; } // We always refine the callsites that have multiple call targets Set<Node> multiBaseptrs = new HashSet<Node>(); for (Stmt callsite : geomPTA.multiCallsites) { InstanceInvokeExpr iie = (InstanceInvokeExpr) callsite.getInvokeExpr(); VarNode vn = geomPTA.findLocalVarNode(iie.getBase()); multiBaseptrs.add(vn); } addUserDefPts(multiBaseptrs); }
private void handleInvokeExpr(InvokeExpr invokeExpr,AnalysisInfo out) { if(invokeExpr instanceof InstanceInvokeExpr) { InstanceInvokeExpr instanceInvokeExpr = (InstanceInvokeExpr) invokeExpr; //here we know that the receiver must point to an object Value base = instanceInvokeExpr.getBase(); out.put(base,NON_NULL); } //but the returned object might point to everything // out.put(invokeExpr, TOP); }
private void handleInvokeExpr(InvokeExpr invokeExpr,AnalysisInfo out) { if(invokeExpr instanceof InstanceInvokeExpr) { InstanceInvokeExpr instanceInvokeExpr = (InstanceInvokeExpr) invokeExpr; //here we know that the receiver must point to an object Value base = instanceInvokeExpr.getBase(); out.put(base,NON_NULL); } }
private void handleInvokeExpr(InvokeExpr ie, Stmt stmt) { SootMethodRef m = ie.getMethodRef(); if ( ie instanceof InstanceInvokeExpr ) { InstanceInvokeExpr iie = (InstanceInvokeExpr)ie; iie.setBase(this.uv.visit( iie.getBase(),m.declaringClass().getType(), stmt)); } for ( int i = 0; i < ie.getArgCount(); i++ ) ie.setArg(i, this.uv.visit( ie.getArg(i), m.parameterType(i), stmt)); }
@Override public Set<SootMethod> load(Unit u) throws Exception { Stmt stmt = (Stmt)u; InvokeExpr ie = stmt.getInvokeExpr(); FastHierarchy fastHierarchy = Scene.v().getFastHierarchy(); //FIXME Handle Thread.start etc. if(ie instanceof InstanceInvokeExpr) { if(ie instanceof SpecialInvokeExpr) { //special return Collections.singleton(ie.getMethod()); } else { //virtual and interface InstanceInvokeExpr iie = (InstanceInvokeExpr) ie; Local base = (Local) iie.getBase(); RefType concreteType = bodyToLMNAA.getUnchecked(unitToOwner.get(u)).concreteType(base, stmt); if(concreteType!=null) { //the base variable definitely points to a single concrete type SootMethod singleTargetMethod = fastHierarchy.resolveConcreteDispatch(concreteType.getSootClass(), iie.getMethod()); return Collections.singleton(singleTargetMethod); } else { SootClass baseTypeClass; if(base.getType() instanceof RefType) { RefType refType = (RefType) base.getType(); baseTypeClass = refType.getSootClass(); } else if(base.getType() instanceof ArrayType) { baseTypeClass = Scene.v().getSootClass("java.lang.Object"); } else if(base.getType() instanceof NullType) { //if the base is definitely null then there is no call target return Collections.emptySet(); } else { throw new InternalError("Unexpected base type:"+base.getType()); } return fastHierarchy.resolveAbstractDispatch(baseTypeClass, iie.getMethod()); } } } else { //static return Collections.singleton(ie.getMethod()); } }
private List<Register> getInstanceInvokeArgumentRegs(InstanceInvokeExpr iie) { constantV.setOrigStmt(origStmt); List<Register> argumentRegs = getInvokeArgumentRegs(iie); // always add reference to callee as first parameter (instance != static) Value callee = iie.getBase(); Register calleeRegister = regAlloc.asLocal(callee); argumentRegs.add(0, calleeRegister); return argumentRegs; }
public void finalize(DexBody body, DexlibAbstractInstruction successor) { // defer final jimplification to move result if (successor instanceof MoveResultInstruction) { // MoveResultInstruction i = (MoveResultInstruction)successor; // i.setExpr(invocation); // if (lineNumber != -1) // i.setTag(new SourceLineNumberTag(lineNumber)); assign = Jimple.v().newAssignStmt(body.getStoreResultLocal(), invocation); setUnit(assign); addTags(assign); body.add(assign); unit = assign; // this is a invoke statement (the MoveResult had to be the direct successor for an expression) } else { InvokeStmt invoke = Jimple.v().newInvokeStmt(invocation); setUnit(invoke); addTags(invoke); body.add(invoke); unit = invoke; } if (IDalvikTyper.ENABLE_DVKTYPER) { Debug.printDbg(IDalvikTyper.DEBUG, "constraint special invoke: "+ assign); if (invocation instanceof InstanceInvokeExpr) { Type t = invocation.getMethodRef().declaringClass().getType(); DalvikTyper.v().setType(((InstanceInvokeExpr) invocation).getBaseBox(), t, true); //DalvikTyper.v().setObjectType(assign.getLeftOpBox()); } int i = 0; for (Type pt: (List<Type>)invocation.getMethodRef().parameterTypes()) { DalvikTyper.v().setType(invocation.getArgBox(i++), pt, true); } int op = (int)instruction.getOpcode().value; if (assign != null) { DalvikTyper.v().setType(assign.getLeftOpBox(), invocation.getType(), false); } } }
private void caseInstanceInvokeExpr(InstanceInvokeExpr expr) { result = result.add(mgr.RESOLVE_METHOD_ERRORS); result = result.add(mgr.NULL_POINTER_EXCEPTION); for (int i = 0; i < expr.getArgCount(); i++) { result = result.add(mightThrow(expr.getArg(i))); } result = result.add(mightThrow(expr.getBase())); result = result.add(mightThrow(expr.getMethodRef())); }
static private void resolveBaseIfNecessary(InvokeExpr ivk) { if (ivk instanceof InstanceInvokeExpr) { InstanceInvokeExpr iivk = (InstanceInvokeExpr)ivk; soot.Type t = iivk.getBase().getType(); if (t instanceof RefType) { RefType rt = (RefType)t; if (rt.getSootClass().resolvingLevel()<SootClass.SIGNATURES) { Scene.v().forceResolve(rt.getSootClass().getName(), SootClass.SIGNATURES); } } } }
/** * Returns the arguments associated with a method descriptor. * * @param signatureToMethodDescriptionMap A map from signatures to method descriptors. * @param invokeExpr An invoke expression. * @return An array of arguments if arguments are found for the method descriptor, null otherwise. */ private Argument[] getArgumentsFromMethodDescription( Map<String, MethodDescription> signatureToMethodDescriptionMap, InvokeExpr invokeExpr) { SootMethod method = invokeExpr.getMethod(); String signature = method.getSignature(); MethodDescription methodDescription = signatureToMethodDescriptionMap.get(signature); if (methodDescription != null) { return methodDescription.getArguments(); } signature = method.getSubSignature(); methodDescription = signatureToMethodDescriptionMap.get(signature); if (methodDescription == null) { return null; } String superclassName = methodDescription.getBaseClass(); if (superclassName == null || !Scene.v().containsClass(superclassName) || invokeExpr instanceof InterfaceInvokeExpr) { return null; } SootClass superclass = Scene.v().getSootClass(superclassName); String baseType; if (invokeExpr instanceof InstanceInvokeExpr) { Value baseValue = ((InstanceInvokeExpr) invokeExpr).getBase(); baseType = baseValue.getType().toString(); } else { baseType = invokeExpr.getMethod().getDeclaringClass().getName(); } if (Scene.v().containsClass(baseType) && Scene.v().getActiveHierarchy() .isClassSubclassOfIncluding(Scene.v().getSootClass(baseType), superclass)) { return methodDescription.getArguments(); } else { return null; } }
@Override public Set<Object> computeMethodReturnValues(Call call) { Stmt stmt = call.stmt; if (!stmt.containsInvokeExpr() || !(stmt.getInvokeExpr() instanceof InstanceInvokeExpr)) { return Collections.singleton((Object) "(.*)"); } else { return Collections.singleton((Object) new SourceDescriptor(((InstanceInvokeExpr) stmt .getInvokeExpr()).getBase(), stmt)); } }