public void caseParameterRef(ParameterRef v) { String oldName = varName; Type paramType= v.getType(); suggestVariableName("paramType"); String paramTypeName = this.varName; ttp.setVariableName(paramTypeName); paramType.apply(ttp); int number = v.getIndex(); suggestVariableName("number"); p.println("int "+varName+"=" + number+ ";"); p.println("Value "+oldName+" = Jimple.v().newParameterRef("+paramTypeName+", "+varName+");"); varName = oldName; }
@Override public void caseIdentityStmt(IdentityStmt stmt) { Value lhs = stmt.getLeftOp(); Value rhs = stmt.getRightOp(); if (rhs instanceof CaughtExceptionRef) { // save the caught exception with move-exception Register localReg = regAlloc.asLocal(lhs); addInsn(new Insn11x(Opcode.MOVE_EXCEPTION, localReg), stmt); this.insnRegisterMap.put(insns.get(insns.size() - 1), LocalRegisterAssignmentInformation.v(localReg, (Local)lhs)); } else if (rhs instanceof ThisRef || rhs instanceof ParameterRef) { /* * do not save the ThisRef or ParameterRef in a local, because it always has a parameter register already. * at least use the local for further reference in the statements */ Local localForThis = (Local) lhs; regAlloc.asParameter(belongingMethod, localForThis); parameterInstructionsList.add(LocalRegisterAssignmentInformation.v(regAlloc.asLocal(localForThis).clone(), localForThis)); } else { throw new Error("unknown Value as right-hand side of IdentityStmt: " + rhs); } }
/** Return LHS of the first identity stmt assigning from \@parameter i. **/ public Local getParameterLocal(int i) { for (Unit s : getUnits()) { if (s instanceof IdentityStmt && ((IdentityStmt)s).getRightOp() instanceof ParameterRef) { IdentityStmt is = (IdentityStmt)s; ParameterRef pr = (ParameterRef)is.getRightOp(); if (pr.getIndex() == i) return (Local)is.getLeftOp(); } } throw new RuntimeException("couldn't find parameterref" + i +"! in "+getMethod()); }
/** * Get all the LHS of the identity statements assigning from parameter references. * * @return a list of size as per <code>getMethod().getParameterCount()</code> with all elements ordered as per the parameter index. * @throws RuntimeException if a parameterref is missing */ public List<Local> getParameterLocals(){ final int numParams = getMethod().getParameterCount(); final List<Local> retVal = new ArrayList<Local>(numParams); //Parameters are zero-indexed, so the keeping of the index is safe for (Unit u : getUnits()){ if (u instanceof IdentityStmt){ IdentityStmt is = ((IdentityStmt)u); if (is.getRightOp() instanceof ParameterRef){ ParameterRef pr = (ParameterRef) is.getRightOp(); retVal.add(pr.getIndex(), (Local) is.getLeftOp()); } } } if (retVal.size() != numParams){ //FLANKER FIX BEGIN //throw new RuntimeException("couldn't find parameterref! in " + getMethod()); return retVal; //FLANKER FIX END } return retVal; }
void getIntConstantsFromLocal(SimpleLocalDefs sld, Local l, Unit u, List<String> whats) throws IOException { Iterator<Unit> iter = sld.getDefsOfAt(l, u).iterator(); while (iter.hasNext()) { Unit def = iter.next(); if (! (def instanceof DefinitionStmt)) continue; DefinitionStmt assign = (DefinitionStmt) def; Value rightOp = assign.getRightOp(); if (rightOp instanceof IntConstant) { whats.add(rightOp.toString()); } else if (rightOp instanceof ParameterRef){ whats.add(rightOp.toString()); } else if (rightOp instanceof Local) { getIntConstantsFromLocal(sld, (Local)rightOp, def, whats); print("getIntConstantsFromLocal -> local"); } else { print("???"+def.toString()); } } }
private AbsValue analyzeParameterRef(ParameterRef r, Unit u, Set <Unit> seen ) { ProgramSpy.debug("************ PARAMETER ********"); ArrayList<Integer> args = new ArrayList<Integer> (); int pos = ((ParameterRef) r).getIndex() + 1; args.add (Integer.valueOf(pos)); String tailname = method.getDeclaringClass().getName() + "_" + method.getName() + "_" + pos; if (acf.treatSpyParameter()) { if (!cc.doublon.containsKey(tailname)) { String name = "AP" + cc.count++ + "_" + tailname; ProgramSpy.debug("Registering " + method.getName() + "," + pos + " under " + name); SpyMethodArgs spy = new SpyMethodArgs(name,method,args,null); cc.doublon.put(tailname,spy); cc.register (name, spy); return new MarkValue(tailname, spy.getAbsValue()); } else { AbsValue av = ((SpyMethodArgs) cc.doublon.get(tailname)).getAbsValue(); return new MarkValue(tailname, av); } } else { return new UnknownValue(r.toString()); } }
@Override public KillGenInfo propagateNormalFlow(Trackable taint, Unit curr, Unit succ) { if (!(curr instanceof IdentityStmt)) return identity(); IdentityStmt idStmt = (IdentityStmt) curr; Value left = AnalysisUtil.getBackwardsBase(idStmt.getLeftOp()); Taint t = (Taint) taint; if (!AnalysisUtil.maybeSameLocation(t.value, left)) return identity(); if (idStmt.getRightOp() instanceof ParameterRef) { if (t.value instanceof Local) { SootMethod m = context.icfg.getMethodOf(idStmt); if (AnalysisUtil.methodMayBeCallableFromApplication(m) && transitiveSinkCaller.isTransitiveCallerOfAnySink(m)) { context.reporter.reportTrackable(new Report(context, taint, curr)); } } } return identity(); }
private Value[] getParameterValues(SootMethod destinationMethod) { int paramsFound = 0; Value[] result = new Value[destinationMethod.getParameterCount()]; for (Unit unit : destinationMethod.getActiveBody().getUnits()) { if (!(unit instanceof IdentityStmt)) continue; Value rightOp = ((IdentityStmt) unit).getRightOp(); if (!(rightOp instanceof ParameterRef)) continue; ParameterRef paramRef = (ParameterRef) rightOp; result[paramRef.getIndex()] = paramRef; paramsFound++; if (paramsFound == result.length) break; } return result; }
@Override public void caseIdentityStmt(IdentityStmt stmt) { AnnotationValueSwitch valueSwitch = new AnnotationValueSwitch(stmt, StmtContext.IDENTITY); logger.fine("\n > > > Identity statement identified < < <"); // for all statements i = parameter[0] if (stmt.getRightOp() instanceof ParameterRef) { if (!body.getMethod().isMain()) { int posInArgList = ((ParameterRef) stmt.getRightOp()) .getIndex(); JimpleInjector.assignArgumentToLocal(posInArgList, (Local) stmt.getLeftOp()); } } else if (stmt.getRightOp() instanceof ThisRef) { // TODO im Grunde nicht nötig... } else if (stmt.getRightOp() instanceof CaughtExceptionRef) { logger.fine("Right operand in IdentityStmt is a CaughtException"); throw new InternalAnalyzerException("Catching exceptions is not supported"); } else { throw new InternalAnalyzerException( "Unexpected type of right value " + stmt.getRightOp().toString() + " in IdentityStmt"); } }
/** * Checks whether the given method is a library stub method * @param method The method to check * @return True if the given method is an Android library stub, false * otherwise */ private boolean methodIsAndroidStub(SootMethod method) { if (!(Options.v().src_prec() == Options.src_prec_apk && method.getDeclaringClass().isLibraryClass() && SystemClassHandler.isClassInSystemPackage( method.getDeclaringClass().getName()))) return false; // Check whether there is only a single throw statement for (Unit u : method.getActiveBody().getUnits()) { if (u instanceof DefinitionStmt) { DefinitionStmt defStmt = (DefinitionStmt) u; if (!(defStmt.getRightOp() instanceof ThisRef) && !(defStmt.getRightOp() instanceof ParameterRef) && !(defStmt.getRightOp() instanceof NewExpr)) return false; } else if (u instanceof InvokeStmt) { InvokeStmt stmt = (InvokeStmt) u; // Check for exception constructor invocations SootMethod callee = stmt.getInvokeExpr().getMethod(); if (!callee.getSubSignature().equals("void <init>(java.lang.String)")) // Check for super class constructor invocation if (!(method.getDeclaringClass().hasSuperclass() && callee.getDeclaringClass() == method.getDeclaringClass().getSuperclass() && callee.getName().equals("<init>"))) return false; } else if (!(u instanceof ThrowStmt)) return false; } return true; }
/** * Gets the first statement in the body of the given method that does not * assign the "this" local or a parameter local * @param sm The method in whose body to look * @return The first non-identity statement in the body of the given method. */ private Unit getFirstNonIdentityStmt(SootMethod sm) { for (Unit u : sm.getActiveBody().getUnits()) { if (!(u instanceof IdentityStmt)) return u; IdentityStmt id = (IdentityStmt) u; if (!(id.getRightOp() instanceof ThisRef) && !(id.getRightOp() instanceof ParameterRef)) return u; } return null; }
private boolean isDexInstruction(Unit unit) { if (unit instanceof IdentityStmt) { IdentityStmt is = (IdentityStmt) unit; return !(is.getRightOp() instanceof ThisRef || is.getRightOp() instanceof ParameterRef); } return true; }
/** * Returns the list of parameter references used in this body. The list is as long as * the number of parameters declared in the associated method's signature. * The list may have <code>null</code> entries for parameters not referenced in the body. * The returned list is of fixed size. */ public List<Value> getParameterRefs() { Value[] res = new Value[getMethod().getParameterCount()]; for (Unit s : getUnits()) { if (s instanceof IdentityStmt) { Value rightOp = ((IdentityStmt)s).getRightOp(); if (rightOp instanceof ParameterRef) { ParameterRef parameterRef = (ParameterRef) rightOp; res[parameterRef.getIndex()] = parameterRef; } } } return Arrays.asList(res); }
@Override public boolean isApplicable(UnitGraph graph, Set<Unit> input, Unit node, Set<Unit> output, Set<Value> taintedValues, Queue<MethodAnalysis> queue, Set<MethodAnalysis> processed) { return !input.isEmpty() && node instanceof IdentityStmt && ((IdentityStmt)node).getRightOp() instanceof ParameterRef; }
/** * Return all possible values for an integer local variable. * * @param start The statement where the analysis should start. * @param local The local variable whose values we are looking for. * @param visitedStmts The set of visited statement. * @return The set of possible values for the local variable. */ private Set<Object> findIntAssignmentsForLocal(Stmt start, Local local, Set<Stmt> visitedStmts) { List<DefinitionStmt> assignStmts = findAssignmentsForLocal(start, local, true, new HashSet<Pair<Unit, Local>>()); Set<Object> result = new HashSet<>(assignStmts.size()); for (DefinitionStmt assignStmt : assignStmts) { Value rhsValue = assignStmt.getRightOp(); if (rhsValue instanceof IntConstant) { result.add(((IntConstant) rhsValue).value); } else if (rhsValue instanceof LongConstant) { result.add(((LongConstant) rhsValue).value); } else if (rhsValue instanceof ParameterRef) { ParameterRef parameterRef = (ParameterRef) rhsValue; Iterator<Edge> edges = Scene.v().getCallGraph() .edgesInto(AnalysisParameters.v().getIcfg().getMethodOf(assignStmt)); while (edges.hasNext()) { Edge edge = edges.next(); InvokeExpr invokeExpr = edge.srcStmt().getInvokeExpr(); Value argValue = invokeExpr.getArg(parameterRef.getIndex()); if (argValue instanceof IntConstant) { result.add(((IntConstant) argValue).value); } else if (argValue instanceof LongConstant) { result.add(((LongConstant) argValue).value); } else if (argValue instanceof Local) { Set<Object> newResults = findIntAssignmentsForLocal(edge.srcStmt(), (Local) argValue, visitedStmts); result.addAll(newResults); } else { result.add(TOP_VALUE); } } } else { return Collections.singleton((Object) TOP_VALUE); } } return result; }
@Override public boolean isSource(Stmt sCallSite, InterproceduralCFG<Unit, SootMethod> cfg) { if (super.isSource(sCallSite, cfg)) return true; if (sCallSite instanceof IdentityStmt) { IdentityStmt is = (IdentityStmt) sCallSite; if (is.getRightOp() instanceof ParameterRef) if (this.parameterTaintMethods != null && this.parameterTaintMethods.contains (cfg.getMethodOf(sCallSite).getSignature())) return true; } return false; }
/** * Analyze an expression (a value) and computes an abstract value representing its contents. * @param r the expression to analyse. * @param u The unit that encapsulate the value. * @param seen What has already be seen (avoid loops). * @return */ public AbsValue analyze_expr(Value r, Unit u, Set<Unit> seen) { AbsValue result; if (r instanceof Local) { result = analyzeLocal((Local) r, u, seen); } else if (r instanceof StringConstant) result = new StringValue(((StringConstant) r).value); else if (r instanceof Constant) result = new ConstantValue((Constant) r,((Constant) r).getType()); else if (r instanceof InvokeExpr) { result = analyzeInvoke((InvokeExpr) r,u,seen); } else if (r instanceof CastExpr) { result = analyze_expr(((CastExpr) r).getOp(),u,seen); } else if (r instanceof ParameterRef) { result = analyzeParameterRef((ParameterRef) r, u, seen); } else if (r instanceof ConditionExpr) { result = analyzeConditionExpr((ConditionExpr) r, u, seen); } else if (r instanceof InstanceOfExpr) { result = analyzeInstanceOfExpr((InstanceOfExpr) r, u, seen); } else if (r instanceof StaticFieldRef) { result = analyzeStaticFieldRef((StaticFieldRef) r,u,seen); } else if (r instanceof InstanceFieldRef) { result = analyzeInstanceFieldRef((InstanceFieldRef) r,u,seen); } else if (r instanceof ArrayRef) { result = analyzeArrayRef((ArrayRef) r,u,seen); } else if (r instanceof NewExpr) { result = analyzeNewExpr((NewExpr) r, u, seen); } else { result = new UnknownValue(r.toString()); } return solve_init(result,u,seen); }
public Value getParameter(SootMethod destinationMethod, int i) { Iterator<Unit> unitsIt = destinationMethod.getActiveBody().getUnits().iterator(); while (unitsIt.hasNext()) { Unit s = unitsIt.next(); if (s instanceof IdentityStmt) { Value rightOp = ((IdentityStmt) s).getRightOp(); if (rightOp instanceof ParameterRef && ((ParameterRef) rightOp).getIndex() == i) { return rightOp; } } } throw new RuntimeException("couldn't find parameterref for index " + i + " in " + destinationMethod); }
@Override public void caseParameterRef(ParameterRef v) { ComponentParameterRef paramRef = new ComponentParameterRef(v.getIndex(), getAnalyzedSignature()); addReadComponent(paramRef); handleDimension(v.getType(), paramRef); }
@Override public void caseIdentityStmt(IdentityStmt stmt) { valueSwitch.callingStmt = stmt; valueSwitch.actualContext = StmtContext.IDENTITY; logger.fine("\n > > > Identity statement identified < < <"); if (stmt.getRightOp() instanceof ParameterRef) { if (!body.getMethod().isMain()) { int posInArgList = ((ParameterRef) stmt.getRightOp()) .getIndex(); JimpleInjector.assignArgumentToLocal(posInArgList, (Local) stmt.getLeftOp(), stmt); } } else if (stmt.getRightOp() instanceof ThisRef) { // TODO im Grunde nicht nötig... } else if (stmt.getRightOp() instanceof CaughtExceptionRef) { logger.fine("Right operand in IdentityStmt is a CaughtException"); } else { throw new InternalAnalyzerException( "Unexpected type of right value " + stmt.getRightOp().toString() + " in IdentityStmt"); } valueSwitch.actualContext = StmtContext.UNDEF; }
@Override public void caseInvokeStmt(InvokeStmt stmt) { InvokeExpr invokeExpr = stmt.getInvokeExpr(); SootClass declaringClass = invokeExpr.getMethod().getDeclaringClass(); if(exprVisitor.isExpressionThatNeedsToBeConvertedToSMT(invokeExpr)) exprVisitor.convertSpecialExpressionsToSMT(invokeExpr, stmt); else if(UtilInstrumenter.isAppDeveloperCode(declaringClass)) { SootMethod method = invokeExpr.getMethod(); Body body = method.retrieveActiveBody(); SMTBinding newRhs = getBindingForTaintedValue(stmt); //if there is no taint-tracking involved (newRhs == null), we do not have to do anything here if(newRhs == null) return; int indexOfInterest = -1; for(int i = 0; i < invokeExpr.getArgCount(); i++) { if(newRhs.getVariableName().equals(invokeExpr.getArg(i).toString())) { indexOfInterest = i; break; } } if(indexOfInterest == -1) return; for(Unit unit : body.getUnits()) { if(unit instanceof IdentityStmt) { IdentityStmt identity = (IdentityStmt)unit; Value rhs = identity.getRightOp(); if(rhs instanceof ParameterRef) { ParameterRef param = (ParameterRef)rhs; if(param.getIndex() == indexOfInterest) { Value lhs = identity.getLeftOp(); SMTBinding newLhs = createNewBindingForValue(lhs); addValueBindingToVariableDeclaration(lhs, newLhs); SMTSimpleAssignment simpleAssignment = new SMTSimpleAssignment(newLhs, new SMTBindingValue(newRhs)); SMTAssertStatement assignmentAssert = new SMTAssertStatement(simpleAssignment); addAssertStmtToAllPrograms(assignmentAssert); } } } } } else { System.err.println(String.format("Double-Check if the following method contains useful information which can be extracted: \n%s", stmt)); } }
/** * Get the definition of the Array starting from an ArrayRef. * Two possibilities: * 1) array = IdentityStmt in which case the previous method in the stack is analyzed * 2) array = newarray in which case all statements array[i] = r are analyzed * @param stack * @param curDepth * @param ar * @param mpSet */ private static void getArrayFromMethod (Stack<SootMethod> stack, int curDepth, ArrayRef ar, Set<String> mpSet) { SootMethod targetM = stack.elementAt(curDepth); logger.info("getArrayFromMethod target: "+ targetM); Body b = targetM.getActiveBody(); System.out.println("body: "+ b); // TODO: change to logger.debug UnitGraph eug = new ExceptionalUnitGraph( b ); LocalDefinition ld = new LocalDefinition(b); Local l = (Local)ar.getBase(); List<Unit> arrayDefs = ld.collectDefinitionsWithAliases(l); for (Unit arrayDef: arrayDefs) { if (arrayDef instanceof IdentityStmt) { logger.info("array: right is IdentityStmt"); IdentityStmt ids = (IdentityStmt)arrayDef; ParameterRef pref = (ParameterRef)ids.getRightOp(); int paramPos = pref.getIndex(); logger.info("index of array parameter: "+ paramPos); // TODO: should be debug // List<MethodCall> methodCallsList = getStringParameterInCall(stack.elementAt(curDepth - 1), targetM, paramPos, mpSet); // getArrayFromMethod (stack, stack.size()-1, ar, mpSet); getStringFromMethod (stack, curDepth-1, targetM, paramPos, mpSet); } else if (arrayDef instanceof AssignStmt) { AssignStmt ass = (AssignStmt) arrayDef; Value right = ass.getRightOp(); if (right instanceof NewArrayExpr) { logger.info("array: right is NewArray"); // get the unit array[i] = str // TODO: Limitation: we suppose the array is initialized in the body where it is created // and that it is not aliased Local arrayLocal = (Local)ass.getLeftOp(); List<Value> arrayInitValues = retrieveArrayInitStmts (b, arrayLocal); for (Value v: arrayInitValues) { if (v instanceof StringConstant) { StringConstant sc = (StringConstant)v; String p = sc.value; mpSet.add(p); logger.info("add perm from array inif: "+ p); } else { logger.warn("not handling this value for array init: "+ v); } } } else if (right instanceof Local){ logger.info("alias "+ ass); // definitions *and* aliases are collected, so no need to handle them separately } else { throw new RuntimeException("error: right not instance of NewArrayExpr nor Local! "+ ass); } } } }
public void caseParameterRef(ParameterRef expr) { st.addStatement(new Nop()); }
public static int parameterRefNumber(ParameterRef r) { //unique number for ParameterRef[i] (must be <0) return -1 - r.getIndex(); }
public void caseParameterRef(ParameterRef v) { }
@Override public void caseParameterRef(ParameterRef arg0) { this.expressionStack.push(this.procInfo.lookupParameterVariable(arg0)); }
public IdentifierExpression lookupParameterVariable(ParameterRef param) { return this.inParameters.get(param.getIndex() + ((this.sootMethod.isStatic()) ? 0 : 1)); }
private boolean isSourceInfoParameter(ResultSourceInfo sInfo) { return sInfo.getSource() instanceof IdentityStmt && ((IdentityStmt) sInfo.getSource()).getRightOp() instanceof ParameterRef; }
@Override public void caseParameterRef(ParameterRef v) { throwInvalidWriteException(v); }
@Override public void caseParameterRef(ParameterRef v) { logger.finest("Parameter reference identified " + v.toString()); throw new NotSupportedStmtException("ParameterRef"); }
/** * Updates the <em>security level</em> of the given value to the level which * is given by the {@link SecurityLevelSwitch#analyzedMethodEnvironment} and * the {@link ParameterRef}. Occurring exceptions are logged. * * @param value * Value for which the <em>security level</em> should be updated * to the level of the given parameter reference. * @param parameterRef * The parameter reference for which the <em>security level</em> * can be looked up in the * {@link SecurityLevelSwitch#analyzedMethodEnvironment}. */ protected void updateParameterLevel(Value value, ParameterRef parameterRef) { MethodParameter methodParameter = getAnalyzedEnvironment().getMethodParameterAt(parameterRef.getIndex()); SecurityLevelValueWriteSwitch updateSwitch = new SecurityLevelValueWriteSwitch(getAnalyzedEnvironment(), getStore(), getIn(), getOut(), methodParameter.getLevel()); executeUpdateLevel(value, updateSwitch, parameterRef.toString()); }
/** * The method should look up the <em>security level</em> of a * {@link ParameterRef}, but the look up of the level of a this reference is * implemented in the {@link SecurityLevelValueWriteSwitch}. * * @param v * The this reference for which the <em>security level</em> * should be looked up. * @see soot.jimple.RefSwitch#caseParameterRef(ParameterRef) * @throws UnimplementedSwitchException * Method throws always this exception, because this method may * not be invoked. */ @Override public void caseParameterRef(ParameterRef v) { throw new SwitchException(getMsg("exception.analysis.switch.not_implemented", v.toString(), getSourceLine(), v.getClass().getSimpleName(), this.getClass().getSimpleName())); }
/** * If {@link SecurityLevelValueWriteSwitch#value} is set and the * {@link SecurityLevelValueWriteSwitch#level} is {@code null}, then the * <em>security level</em> of the contained value will be updated to the * level of the given parameter level. Also it will be checked whether the * handle assignment is valid, i.e. whether the name and the type of the * local variable that is assigned corresponds to the name and type of the * parameter. * * @param v * Parameter reference that is assigned to the contained value * {@link SecurityLevelValueWriteSwitch#value} for which the * <em>security level</em> should be updated to the level of the * parameter. * @see soot.jimple.RefSwitch#caseParameterRef(soot.jimple.ParameterRef) * @throws UnimplementedSwitchException * If {@link SecurityLevelValueWriteSwitch#value} is not set and * the {@link SecurityLevelValueWriteSwitch#level} is not * {@code null}, because the contained value requires * information of the given parameter reference for updating the * <em>security level</em>. */ @Override public void caseParameterRef(ParameterRef v) { if (level == null && value != null) { updateParameterLevel(value, v); } else { throw new SwitchException(getMsg("exception.analysis.switch.not_implemented", v.toString(), getSourceLine(), v.getClass().getSimpleName(), this.getClass().getSimpleName())); } }
/** * DOC * * @see soot.jimple.RefSwitch#caseParameterRef(soot.jimple.ParameterRef) */ @Override public void caseParameterRef(ParameterRef v) { }