/** * Gets the points-to-set for the given value * @param targetValue The value for which to get the points-to-set * @return The points-to-set for the given value */ private PointsToSet getPointsToSet(Value targetValue) { PointsToAnalysis pta = Scene.v().getPointsToAnalysis(); synchronized (pta) { if (targetValue instanceof Local) return pta.reachingObjects((Local) targetValue); else if (targetValue instanceof InstanceFieldRef) { InstanceFieldRef iref = (InstanceFieldRef) targetValue; return pta.reachingObjects((Local) iref.getBase(), iref.getField()); } else if (targetValue instanceof StaticFieldRef) { StaticFieldRef sref = (StaticFieldRef) targetValue; return pta.reachingObjects(sref.getField()); } else if (targetValue instanceof ArrayRef) { ArrayRef aref = (ArrayRef) targetValue; return pta.reachingObjects((Local) aref.getBase()); } else throw new RuntimeException("Unexpected value type for aliasing: " + targetValue.getClass()); } }
/** * Checks whether the given base value matches the base of the given * taint abstraction * @param baseValue The value to check * @param source The taint abstraction to check * @return True if the given value has the same base value as the given * taint abstraction, otherwise false */ protected boolean baseMatches(final Value baseValue, Abstraction source) { if (baseValue instanceof Local) { if (baseValue.equals(source.getAccessPath().getPlainValue())) return true; } else if (baseValue instanceof InstanceFieldRef) { InstanceFieldRef ifr = (InstanceFieldRef) baseValue; if (ifr.getBase().equals(source.getAccessPath().getPlainValue()) && source.getAccessPath().firstFieldMatches(ifr.getField())) return true; } else if (baseValue instanceof StaticFieldRef) { StaticFieldRef sfr = (StaticFieldRef) baseValue; if (source.getAccessPath().firstFieldMatches(sfr.getField())) return true; } return false; }
public void jimplify (DexBody body) { int source = ((OneRegisterInstruction)instruction).getRegisterA(); FieldReference f = (FieldReference)((ReferenceInstruction)instruction).getReference(); StaticFieldRef instanceField = Jimple.v().newStaticFieldRef(getStaticSootFieldRef(f)); Local sourceValue = body.getRegisterLocal(source); assign = getAssignStmt(body, sourceValue, instanceField); setUnit(assign); addTags(assign); body.add(assign); if (IDalvikTyper.ENABLE_DVKTYPER) { Debug.printDbg(IDalvikTyper.DEBUG, "constraint: "+ assign); int op = (int)instruction.getOpcode().value; DalvikTyper.v().setType(assign.getRightOpBox(), instanceField.getType(), true); } }
@Override public void isParamVulnAndStore(SootMethod originMethod, Stmt originStmt, Value reachedValue) { //avoid sideeffect //constant already guaranteed by caller System.out.println(originStmt); String funcSig = originStmt.getInvokeExpr().getMethod().getSignature(); String valueString = reachedValue.toString(); if (evaluateResult(funcSig, valueString)) { if(DEBUG) { System.out.println("result found"); System.out.println("originstmt: " + originStmt + " reachedValue: " + reachedValue); } this.results.add(new Pair<>(originMethod, new Pair<>(originStmt, valueString))); } if(DEBUG) { if (reachedValue instanceof Constant || reachedValue instanceof StaticFieldRef) { System.out.println("originstmt: " + originStmt + " reachedValue: " + reachedValue); } } }
private void checkAccessStmt(Stmt sootStmt, SootMethod currentMethod) { if(sootStmt.containsFieldRef()) { SootField accessField = sootStmt.getFieldRef().getField(); boolean isWrite = (((DefinitionStmt)sootStmt).getLeftOp() instanceof FieldRef); boolean isStatic = (sootStmt.getFieldRef() instanceof StaticFieldRef); Value object = isStatic ? NullConstant.v() : ((InstanceFieldRef)sootStmt.getFieldRef()).getBase(); String methodSig = currentMethod.getSignature(); List<Value> currentLocks = new ArrayList<Value>(lockStack); System.out.println(isWrite+" access on "+isStatic+" field "+accessField+" of "+object+" in "+methodSig+" with "+currentLocks.size()+" locks"); if(!variableAccesses.containsKey(methodSig)) { variableAccesses.put(methodSig, new HashSet<VariableAccess>()); } variableAccesses.get(currentMethod.getSignature()).add( new VariableAccess(accessField, sootStmt, currentMethod, isWrite, isStatic, currentLocks)); } }
@Override public void caseStaticFieldRef(StaticFieldRef arg0) { // TODO: we are checking if this is a @NonNull field // if so, we add an assume to ensure that it actually is // not null here. May be better ways to do this. checkFieldAnnotations( GlobalsCache.v().lookupSootField(arg0.getField()), arg0); Expression field = GlobalsCache.v().lookupSootField(arg0.getField()); // check if the field may be modified by another thread. // (unless it is a lhs expression. In that case we don't care. if (!this.isLeftHandSide && checkSharedField(arg0, field)) { havocField(field, null); } this.expressionStack.push(field); }
/** * Gets the points-to-set for the given value * @param targetValue The value for which to get the points-to-set * @return The points-to-set for the given value */ private PointsToSet getPointsToSet(Value targetValue) { if (targetValue instanceof Local) return Scene.v().getPointsToAnalysis().reachingObjects((Local) targetValue); else if (targetValue instanceof InstanceFieldRef) { InstanceFieldRef iref = (InstanceFieldRef) targetValue; return Scene.v().getPointsToAnalysis().reachingObjects((Local) iref.getBase(), iref.getField()); } else if (targetValue instanceof StaticFieldRef) { StaticFieldRef sref = (StaticFieldRef) targetValue; return Scene.v().getPointsToAnalysis().reachingObjects(sref.getField()); } else if (targetValue instanceof ArrayRef) { ArrayRef aref = (ArrayRef) targetValue; return Scene.v().getPointsToAnalysis().reachingObjects((Local) aref.getBase()); } else throw new RuntimeException("Unexpected value type for aliasing: " + targetValue.getClass()); }
public void addStaticFieldAV(StaticFieldRef sfr, AliasValue av){ Set<AliasValue> avSet = this.staticFieldAVs.get(sfr); if(avSet == null){ avSet = new HashSet<AliasValue>(); avSet.add(av); this.staticFieldAVs.put(sfr, avSet); }else{ boolean isExisted = false; for(AliasValue item : avSet){ if(item.myEquals(av)){ isExisted = true; break; } } if(!isExisted){ avSet.add(av); } } }
private void addStaticFieldAV(StaticFieldRef sfr, AliasValue av){ Set<AliasValue> avSet = this.staticFieldAVs.get(sfr); if(avSet == null){ avSet = new HashSet<AliasValue>(); avSet.add(av); this.staticFieldAVs.put(sfr, avSet); }else{ boolean isExisted = false; for(AliasValue item : avSet){ if(item.myEquals(av)){ isExisted = true; break; } } if(!isExisted){ avSet.add(av); } } }
private void foundNewTaint(Unit currUnit, Value lv){ if(spa.getPathSummary().alreadyInTaintsSet(currUnit, lv)){ return; } if(lv instanceof StaticFieldRef){ spa.getPathSummary().addStaticFieldRefTV((StaticFieldRef) lv); } //first add the left value to taints set TaintValue tv = new TaintValue(currUnit, lv); spa.getPathSummary().addTaintValue(tv); //then, whether the left value is a FieldRef (only instance field can have alias) TODO if(lv instanceof InstanceFieldRef){ tv.setHeapAssignment(true); BackwardAnalysis ba = new BackwardAnalysis(currUnit, tv, spa); ba.startBackward(); } }
private void assignServiceToField(Body b, SootClass initClass, SootClass sc) { Value l = getLocalWithName(b, makeLocalName(sc.getType()), sc.getType()); SootField f = initClass.getFieldByName(makeFieldName(sc.getType())); StaticFieldRef sfr = Jimple.v().newStaticFieldRef(f.makeRef()); Unit u = Jimple.v().newAssignStmt(sfr, l); b.getUnits().add(u); }
public boolean hasPrefix(Value v) { // if this has prefix v if (v instanceof Local) { if (local == null) return false; else return (local.equals(v)); } else if (v instanceof InstanceFieldRef) { InstanceFieldRef ifr = (InstanceFieldRef) v; if (local == null) { if (ifr.getBase() != null) return false; } else if (!local.equals(ifr.getBase())) return false; if (fields.length > 0 && ifr.getField() == fields[0]) return true; return false; } else if (v instanceof StaticFieldRef) { StaticFieldRef sfr = (StaticFieldRef) v; if (local != null) return false; if (fields.length > 0 && sfr.getField() == fields[0]) return true; return false; } else if (v instanceof ArrayRef) { ArrayRef ar = (ArrayRef) v; if (local == null) return false; else return (local.equals(ar.getBase())); } else if (v instanceof Constant) { return false; } else throw new RuntimeException("Unexpected left side " + v.getClass()); }
public SootField[] getPostfix(Value v) { // this is longer than v if (v instanceof InstanceFieldRef || v instanceof StaticFieldRef) { if (fields.length > 0) return Arrays.copyOfRange(fields, 1, fields.length); return new SootField[] {}; } else if (v instanceof ArrayRef) { return new SootField[] {}; } else throw new RuntimeException("Unexpected left side " + v.getClass()); }
/***** Aliases *****/ private Set<FlowAbstraction> taintAliases(FlowAbstraction fa) { // System.out.println(icfg.getMethodOf(fa.getUnit()).getActiveBody()); Set<FlowAbstraction> ret = new HashSet<FlowAbstraction>(); // Should not consider other cases... if (fa.getLocal() != null) { Set<Value> mayAliases = icfg.mayAlias(fa.getLocal(), fa.getUnit()); mayAliases.remove(fa.getLocal()); for (Value alias : mayAliases) { if (alias instanceof Local || alias instanceof ArrayRef || alias instanceof StaticFieldRef || alias instanceof InstanceFieldRef) { FlowAbstraction faT = getTaint(fa.getLocal(), alias, fa, fa.getUnit()); if (faT != null) ret.add(faT); } } if (DEBUG_ALIAS) { if (!ret.isEmpty()) { LOGGER.debug("At " + fa.getUnit()); LOGGER.debug("\tAliases of " + fa.getLocal() + " are: " + mayAliases); LOGGER.debug("\tAlias tainting " + ret); } } } return ret; }
/***** Taints *****/ private FlowAbstraction getTaint(Value right, Value left, FlowAbstraction source, Unit src) { FlowAbstraction fa = null; if (right instanceof CastExpr) right = ((CastExpr) right).getOp(); if (right instanceof Local && source.getLocal() == right) { fa = FlowAbstraction.v(source.getSource(), left, src, icfg.getMethodOf(src), source); fa = fa.append(source.getFields()); } else if (right instanceof InstanceFieldRef) { InstanceFieldRef ifr = (InstanceFieldRef) right; if (source.hasPrefix(ifr)) { fa = FlowAbstraction.v(source.getSource(), left, src, icfg.getMethodOf(src), source); fa = fa.append(source.getPostfix(ifr)); } } else if (right instanceof StaticFieldRef) { StaticFieldRef sfr = (StaticFieldRef) right; if (source.hasPrefix(sfr)) { fa = FlowAbstraction.v(source.getSource(), left, src, icfg.getMethodOf(src), source); fa = fa.append(source.getPostfix(sfr)); } } else if (right instanceof ArrayRef) { ArrayRef ar = (ArrayRef) right; if (ar.getBase() == source.getLocal()) fa = FlowAbstraction.v(source.getSource(), left, src, icfg.getMethodOf(src), source); } return fa; }
/** * Checks whether the given base value matches the base of the given * taint abstraction and ends there. So a will match a, but not a.x. * Not that this function will still match a to a.*. * @param baseValue The value to check * @param source The taint abstraction to check * @return True if the given value has the same base value as the given * taint abstraction and no further elements, otherwise false */ protected boolean baseMatchesStrict(final Value baseValue, Abstraction source) { if (!baseMatches(baseValue, source)) return false; if (baseValue instanceof Local) return source.getAccessPath().isLocal(); else if (baseValue instanceof InstanceFieldRef || baseValue instanceof StaticFieldRef) return source.getAccessPath().getFieldCount() == 1; throw new RuntimeException("Unexpected left side"); }
private Insn buildGetInsn(ConcreteRef sourceRef, Register destinationReg) { if (sourceRef instanceof StaticFieldRef) { return buildStaticFieldGetInsn(destinationReg, (StaticFieldRef) sourceRef); } else if (sourceRef instanceof InstanceFieldRef) { return buildInstanceFieldGetInsn(destinationReg, (InstanceFieldRef) sourceRef); } else if (sourceRef instanceof ArrayRef) { return buildArrayGetInsn(destinationReg, (ArrayRef) sourceRef); } else { throw new RuntimeException("unsupported type of ConcreteRef: " + sourceRef.getClass()); } }
private Insn buildPutInsn(ConcreteRef destRef, Value source) { if (destRef instanceof StaticFieldRef) { return buildStaticFieldPutInsn((StaticFieldRef) destRef, source); } else if (destRef instanceof InstanceFieldRef) { return buildInstanceFieldPutInsn((InstanceFieldRef) destRef, source); } else if (destRef instanceof ArrayRef) { return buildArrayPutInsn((ArrayRef) destRef, source); } else { throw new RuntimeException("unsupported type of ConcreteRef: " + destRef.getClass()); } }
private Insn buildStaticFieldPutInsn(StaticFieldRef destRef, Value source) { SootField destSootField = destRef.getField(); Register sourceReg = regAlloc.asImmediate(source, constantV); BuilderFieldReference destField = DexPrinter.toFieldReference(destSootField, belongingFile); Opcode opc = getPutGetOpcodeWithTypeSuffix("sput", destField.getType()); return new Insn21c(opc, sourceReg, destField); }
public void jimplify (DexBody body) { int dest = ((OneRegisterInstruction)instruction).getRegisterA(); FieldReference f = (FieldReference)((ReferenceInstruction)instruction).getReference(); StaticFieldRef r = Jimple.v().newStaticFieldRef(getStaticSootFieldRef(f)); assign = Jimple.v().newAssignStmt(body.getRegisterLocal(dest), r); setUnit(assign); addTags(assign); body.add(assign); if (IDalvikTyper.ENABLE_DVKTYPER) { Debug.printDbg(IDalvikTyper.DEBUG, "constraint: "+ assign); int op = (int)instruction.getOpcode().value; DalvikTyper.v().setType(assign.getLeftOpBox(), r.getType(), false); } }
protected void addSceneTransformer(Map<SootMethod, Set<String>> entryPointMap) { Ic3ResultBuilder resultBuilder = new Ic3ResultBuilder(); resultBuilder.setEntryPointMap(entryPointMap); DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss"); String debugDirPath = System.getProperty("user.home") + File.separator + "debug"; File debugDir = new File(debugDirPath); if (!debugDir.exists()) { debugDir.mkdir(); } String fileName = dateFormat.format(new Date()) + ".txt"; String debugFilename = debugDirPath + File.separator + fileName; String pack = AnalysisParameters.v().useShimple() ? "wstp" : "wjtp"; Transform transform = new Transform(pack + ".ifds", new PropagationSceneTransformer(resultBuilder, new PropagationSceneTransformerFilePrinter(debugFilename, new SymbolFilter() { @Override public boolean filterOut(Value symbol) { return symbol instanceof StaticFieldRef && ((StaticFieldRef) symbol).getField() .getDeclaringClass().getName().startsWith("android.provider"); } }))); if (PackManager.v().getPack(pack).get(pack + ".ifds") == null) { PackManager.v().getPack(pack).add(transform); } else { Iterator<?> it = PackManager.v().getPack(pack).iterator(); while (it.hasNext()) { Object current = it.next(); if (current instanceof Transform && ((Transform) current).getPhaseName().equals(pack + ".ifds")) { it.remove(); break; } } PackManager.v().getPack(pack).add(transform); } }
/** * Returns a normal edge function. * * @param curr The current statement. * @param currNode The current variable. * @param succNode The variable the current variable is propagated to after the statement. * @param zeroValue The zero value, which represents the absence of a data flow fact. * @param pointsToAnalysis The pointer analysis. * @return A normal edge function. */ public EdgeFunction<BasePropagationValue> getNormalEdgeFunction(Unit curr, Value currNode, Value succNode, Value zeroValue, PointsToAnalysis pointsToAnalysis) { if (curr instanceof AssignStmt) { if (logger.isDebugEnabled()) { logger.debug("Normal edge: " + curr); logger.debug(currNode + " " + succNode); } AssignStmt assignStmt = (AssignStmt) curr; final Value left = assignStmt.getLeftOp(); final String type = left.getType().toString(); final Value right = assignStmt.getRightOp(); if (Model.v().isModeledType(type)) { if (currNode.equivTo(zeroValue) && succNode.equivTo(left)) { if (right instanceof StaticFieldRef) { StaticFieldRef staticFieldRef = (StaticFieldRef) right; Argument[] arguments = Model.v().getArgumentsForStaticField(staticFieldRef.getField().getSignature()); EdgeFunction<BasePropagationValue> result = PropagationTransformerFactory.makeTransformer(null, arguments, false); if (arguments != null) { if (logger.isDebugEnabled()) { logger.debug("Returning " + result); } return PropagationTransformerFactory.makeTransformer(null, arguments, false); } } else if (right instanceof NullConstant) { return PropagationTransformerFactory.makeTransformer(null, null, false); } } } } return EdgeIdentity.v(); }
@Override public boolean isCallStmt(Unit unit) { Stmt stmt = (Stmt) unit; if (stmt.containsInvokeExpr()) { return true; } else if (stmt instanceof AssignStmt) { Value right = ((AssignStmt) stmt).getRightOp(); return right instanceof StaticFieldRef && AnalysisParameters.v().isAnalysisClass( ((StaticFieldRef) right).getField().getDeclaringClass().getName()); } else { return false; } }
@Override public void visit(Value e) { if (e instanceof StaticFieldRef) { StaticFieldRef sfe = (StaticFieldRef) e; add(e, sfe.getField()); } }
public MethodInitState(MethodSummary ms){ this.staticFieldTVs = new ArrayList<StaticFieldRef>(); this.staticFieldAVs = new HashMap<StaticFieldRef, Set<AliasValue>>(); this.thisTV = null; this.thisAVs = new ArrayList<AliasValue>(); this.argTVs = new ArrayList<TaintValue>(); this.argAVs = new ArrayList<ArrayList<AliasValue>>(); this.ms = ms; }
public void addAllStaticFieldTVs(ArrayList<StaticFieldRef> sfrs){ for(StaticFieldRef sfr : sfrs){ if(!this.staticFieldTVs.contains(sfr)){ this.staticFieldTVs.add(sfr); } } }
public void addAllStaticFieldAVs(HashMap<StaticFieldRef, Set<AliasValue>> sfAVMap){ Iterator iter = sfAVMap.entrySet().iterator(); while(iter.hasNext()){ Entry<StaticFieldRef, Set<AliasValue>> entry = (Entry<StaticFieldRef, Set<AliasValue>>) iter.next(); StaticFieldRef sfr = entry.getKey(); Set<AliasValue> avs = entry.getValue(); for(AliasValue av : avs){ addStaticFieldAV(sfr, av); } } }
public PathSummary(ArrayList<Unit> allUnits){ this.invokeExprs = new ArrayList<InvokeExpr>(); this.taintsSet = new HashSet<TaintValue>(); this.aliasSet = new HashSet<AliasValue>(); this.allUnits = allUnits; this.initMethodSummary = null; this.spes = new SinglePathExitState(this); this.staticFieldTVs = new ArrayList<StaticFieldRef>(); this.staticFieldAVs = new HashMap<StaticFieldRef, Set<AliasValue>>(); }
public StaticFieldRef isStaticFieldTainted(StaticFieldRef sfr){ StaticFieldRef result = null; for(StaticFieldRef item : this.staticFieldTVs){ if(item.toString().equals(sfr.toString()) || item.getField().toString().equals(sfr.getField().toString())){ result = item; break; } } return result; }
public Set<AliasValue> getStaticFieldAVs(StaticFieldRef sfr){ Set<AliasValue> result = null; Iterator iter = this.staticFieldAVs.entrySet().iterator(); while(iter.hasNext()){ Entry<StaticFieldRef, Set<AliasValue>> entry = (Entry<StaticFieldRef, Set<AliasValue>>) iter.next(); StaticFieldRef key = entry.getKey(); Set<AliasValue> avSet = entry.getValue(); if(key.toString().equals(sfr.toString())){ result = avSet; break; } } return result; }
public MergedExitState(){ this.mergedExitArgTVs = null; this.mergedExitThisAVs = new ArrayList<AliasValue>(); this.staticFieldTVs = new ArrayList<StaticFieldRef>(); this.staticFieldAVs = new HashMap<StaticFieldRef, Set<AliasValue>>(); this.mergedRetTV = null; this.mergedRetAVs = new ArrayList<AliasValue>(); }
private AbsValue analyzeStaticFieldRef(StaticFieldRef r, Unit u, Set <Unit> seen ) { ProgramSpy.debug("************ STATIC FIELD REF ********"); StaticFieldRef fr = (StaticFieldRef) r; SootField field = fr.getField(); PointsToSet fdefs =pag.reachingObjects(fr.getField()); // ((pag instanceof DemandCSPointsTo) ? ((DemandCSPointsTo) pag).getPAG() : pag).reachingObjects(fr.getField()); if (P2SAux.is_simple(field.getType())) { ProgramSpy.debug("Simple field"); AbsValue sb = possibleStringConstantsValue(str(fr),fdefs); String tailname = field.getDeclaringClass().getName() + "_" + field.getName(); // This is bogus but it seems that Soot incorectly ignores some clinit if (unresolved(sb)) { if (!cc.doublon_field.containsKey(tailname)) { String name = "AF" + cc.count++ + "_" + tailname; ProgramSpy.debug("Registering field " + name); SpyField spy = new SpyField(name,fr.getField(),null); cc.doublon_field.put(tailname,spy); cc.registerField (fr.getField(), spy); return new MarkValue(tailname, spy.getAbsValue()); } else { AbsValue av = ((SpyField) cc.doublon_field.get(tailname)).getAbsValue(); return new MarkValue(tailname, av); } } else { return sb; } } else return P2SAux.p2sContents(cc.nodeTable, fdefs); }