private void prepareAlarmManagerSet(Body body, InvokeStmt setStmt, SootMethodRef reportRef) { Value oldVal = setStmt.getInvokeExpr().getArg(1); Local longLocal = UtilInstrumenter.generateFreshLocal(body, LongType.v()); SootMethod currentTimeMillis = Scene.v().getMethod("<java.lang.System: long currentTimeMillis()>"); StaticInvokeExpr timeInvoke = Jimple.v().newStaticInvokeExpr(currentTimeMillis.makeRef()); AssignStmt timeInitalize = Jimple.v().newAssignStmt(longLocal, timeInvoke); AddExpr addTime = Jimple.v().newAddExpr(longLocal, LongConstant.v(2000L)); AssignStmt timeAssign = Jimple.v().newAssignStmt(longLocal, addTime); body.getUnits().insertBefore(timeInitalize, setStmt); body.getUnits().insertBefore(timeAssign, setStmt); InvokeExpr expr = setStmt.getInvokeExpr(); expr.setArg(0, IntConstant.v(0)); expr.setArg(1, longLocal); // Report the change InvokeStmt reportStmt = Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr( reportRef, oldVal, longLocal)); reportStmt.addTag(new InstrumentedCodeTag()); body.getUnits().insertAfter(reportStmt, setStmt); }
private ResultSourceInfo findDataFlowPathForSink(Stmt sinkStmt, Local sinkLokal, List<ResultSourceInfo> allDataFlows) { for(ResultSourceInfo singleFlow : allDataFlows){ Stmt[] statements = singleFlow.getPath(); AccessPath[] accessPath = singleFlow.getPathAccessPaths(); for(int i = 0; i < statements.length; i++) { Stmt currentStmt = statements[i]; if(currentStmt == sinkStmt) { if(accessPath[i].getPlainValue() == sinkLokal) return singleFlow; } else if(currentStmt instanceof AssignStmt) { AssignStmt assignStmt = (AssignStmt)currentStmt; Value lhs = assignStmt.getLeftOp(); if(lhs == sinkLokal) return singleFlow; } } } return null; }
private boolean hasConstantIndexAtArrayForSplitDataFlow(Stmt[] dataflow) { Stmt firstAssign = dataflow[0]; if(firstAssign instanceof AssignStmt) { AssignStmt ass = (AssignStmt)firstAssign; Value value = ass.getRightOp(); if(value instanceof ArrayRef) { ArrayRef aRef = (ArrayRef)value; Value index = aRef.getIndex(); if(index instanceof IntConstant) return true; } } else throw new RuntimeException("this should not happen - wrong assumption"); return false; }
private int getConstantArrayIndexForSplitDataFlow(Stmt[] dataflow) { Stmt firstAssign = dataflow[0]; if(firstAssign instanceof AssignStmt) { AssignStmt ass = (AssignStmt)firstAssign; Value value = ass.getRightOp(); if(value instanceof ArrayRef) { ArrayRef aRef = (ArrayRef)value; Value index = aRef.getIndex(); if(index instanceof IntConstant) return ((IntConstant) index).value; } } else throw new RuntimeException("this should not happen - wrong assumption"); return -1; }
@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 AssignStmt) { Set<Pair<AccessGraph, EdgeFunction<TypestateDomainValue>>> out = new HashSet<>(); AssignStmt stmt = (AssignStmt) unit; out.add(new Pair<AccessGraph, EdgeFunction<TypestateDomainValue>>( new AccessGraph((Local) stmt.getLeftOp(), stmt.getLeftOp().getType()), new TransitionFunction(initialTrans))); return out; } return Collections.emptySet(); }
protected Collection<Pair<AccessGraph, EdgeFunction<TypestateDomainValue>>> generateReturnValueOf(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 (!matches) return Collections.emptySet(); if (unit instanceof AssignStmt) { Set<Pair<AccessGraph, EdgeFunction<TypestateDomainValue>>> out = new HashSet<>(); AssignStmt stmt = (AssignStmt) unit; out.add(new Pair<AccessGraph, EdgeFunction<TypestateDomainValue>>( new AccessGraph((Local) stmt.getLeftOp(), stmt.getLeftOp().getType()), new TransitionFunction(initialTrans))); return out; } return Collections.emptySet(); }
private AssignStmt findFieldDef(Body b, FieldRef fr) { AssignStmt fdef = null; for (Unit u : b.getUnits()) { if (u instanceof AssignStmt) { AssignStmt fass = (AssignStmt) u; Value l = fass.getLeftOp(); if (l instanceof FieldRef) { FieldRef ffr = (FieldRef) l; if (ffr.getField().getSignature().toString() .equals(fr.getField().getSignature())) { fdef = fass; break; } } } } return fdef; }
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; }
/** * Finds the last assignment to the given String local by searching upwards * from the given statement * * @param stmt * The statement from which to look backwards * @param local * The variable for which to look for assignments * @return The last value assigned to the given variable */ private String findLastStringAssignment(Stmt stmt, Local local, BiDiInterproceduralCFG<Unit, SootMethod> cfg) { if (stmt instanceof AssignStmt) { AssignStmt assign = (AssignStmt) stmt; if (assign.getLeftOp() == local) { // ok, now find the new value from the right side if (assign.getRightOp() instanceof StringConstant) return ((StringConstant) assign.getRightOp()).value; } } // Continue the search upwards for (Unit pred : cfg.getPredsOf(stmt)) { if (!(pred instanceof Stmt)) continue; String lastAssignment = findLastStringAssignment((Stmt) pred, local, cfg); if (lastAssignment != null) return lastAssignment; } return null; }
/** * Constructs an array of the given type with a single element of this type * in the given method * @param body The body of the method in which to create the array * @param gen The local generator * @param tp The type of which to create the array * @param constructionStack Set of classes currently being built to avoid * constructor loops * @param parentClasses If a requested type is compatible with one of the * types in this list, the already-created object is used instead of * creating a new one. * @return The local referencing the newly created array, or null if the * array generation failed */ private Value buildArrayOfType(Body body, LocalGenerator gen, ArrayType tp, Set<SootClass> constructionStack, Set<SootClass> parentClasses) { Local local = gen.generateLocal(tp); // Generate a new single-element array NewArrayExpr newArrayExpr = Jimple.v().newNewArrayExpr(tp.getElementType(), IntConstant.v(1)); AssignStmt assignArray = Jimple.v().newAssignStmt(local, newArrayExpr); body.getUnits().add(assignArray); // Generate a single element in the array AssignStmt assign = Jimple.v().newAssignStmt (Jimple.v().newArrayRef(local, IntConstant.v(0)), getValueForType(body, gen, tp.getElementType(), constructionStack, parentClasses)); body.getUnits().add(assign); return local; }
/** * Collect all the locals which are assigned a IntConstant(0) or are used * within a zero comparison. * * @param body * the body to analyze */ private Set<Local> getNumCandidates(Body body) { Set<Local> candidates = new HashSet<Local>(); for (Unit u : body.getUnits()) { if (u instanceof AssignStmt) { AssignStmt a = (AssignStmt) u; if (!(a.getLeftOp() instanceof Local)) continue; Local l = (Local) a.getLeftOp(); Value r = a.getRightOp(); if ((r instanceof IntConstant || r instanceof LongConstant)) { candidates.add(l); Debug.printDbg("[add null candidate: ", u); } } } return candidates; }
/** * Check if the field type equals the type of the value that will be stored in the field. A cast expression has to be introduced for the unequal case. * @return assignment statement which hold a cast or not depending on the types of the operation */ protected AssignStmt getAssignStmt(DexBody body, Local sourceValue, ConcreteRef instanceField) { AssignStmt assign; // Type targetType = getTargetType(body); // if(targetType != UnknownType.v() && targetType != sourceValue.getType() && ! (targetType instanceof RefType)) { // CastExpr castExpr = Jimple.v().newCastExpr(sourceValue, targetType); // Local local = body.generateLocal(targetType); // assign = Jimple.v().newAssignStmt(local, castExpr); // body.add(assign); // beginUnit = assign; // assign = Jimple.v().newAssignStmt(instanceField, local); // } // else { assign = Jimple.v().newAssignStmt(instanceField, sourceValue); // } return assign; }
private boolean isObjectArray(Value v, Body body) { for (Unit u : body.getUnits()) { if (u instanceof AssignStmt) { AssignStmt assign = (AssignStmt) u; if (assign.getLeftOp() == v) { if (assign.getRightOp() instanceof NewArrayExpr) { NewArrayExpr nea = (NewArrayExpr) assign.getRightOp(); if (isObject(nea.getBaseType())) return true; } else if (assign.getRightOp() instanceof FieldRef) { FieldRef fr = (FieldRef) assign.getRightOp(); if (fr.getType() instanceof ArrayType) if (isObject(((ArrayType) fr.getType()) .getArrayElementType())) return true; } } } } return false; }
private void convertArrayStoreInsn(InsnNode insn) { int op = insn.getOpcode(); boolean dword = op == LASTORE || op == DASTORE; StackFrame frame = getFrame(insn); if (!units.containsKey(insn)) { Operand valu = dword ? popImmediateDual() : popImmediate(); Operand indx = popImmediate(); Operand base = popLocal(); ArrayRef ar = Jimple.v().newArrayRef( base.stackOrValue(), indx.stackOrValue()); indx.addBox(ar.getIndexBox()); base.addBox(ar.getBaseBox()); AssignStmt as = Jimple.v().newAssignStmt(ar, valu.stackOrValue()); valu.addBox(as.getRightOpBox()); frame.in(valu, indx, base); frame.boxes(as.getRightOpBox(), ar.getIndexBox(), ar.getBaseBox()); setUnit(insn, as); } else { frame.mergeIn(dword ? popDual() : pop(), pop(), pop()); } }
public void instrumentDummyMainMethod(SootMethod mainMethod) { Body body = mainMethod.getActiveBody(); PatchingChain<Unit> units = body.getUnits(); for (Iterator<Unit> iter = units.snapshotIterator(); iter.hasNext(); ) { Stmt stmt = (Stmt) iter.next(); if (stmt instanceof IdentityStmt) { continue; } //For the purpose of confusion dex optimization (because of the strategy of generating dummyMain method) AssignStmt aStmt = (AssignStmt) stmt; SootMethod fuzzyMe = generateFuzzyMethod(mainMethod.getDeclaringClass()); InvokeExpr invokeExpr = Jimple.v().newVirtualInvokeExpr(body.getThisLocal(), fuzzyMe.makeRef()); Unit assignU = Jimple.v().newAssignStmt(aStmt.getLeftOp(), invokeExpr); units.insertAfter(assignU, aStmt); break; } }
public DNF getErrSuf(Unit q) { if (!(q instanceof AssignStmt)) return null; AssignStmt s = (AssignStmt)q; soot.Value lhs = s.getLeftOp(); soot.Value rhs = s.getRightOp(); soot.Value rx; if (rhs instanceof ArrayRef) rx = ((ArrayRef)rhs).getBase(); else if (rhs instanceof InstanceFieldRef) rx = ((InstanceFieldRef)rhs).getBase(); else if (lhs instanceof ArrayRef) rx = ((ArrayRef)lhs).getBase(); else if (lhs instanceof InstanceFieldRef) rx = ((InstanceFieldRef)lhs).getBase(); else throw new RuntimeException("Wrong query + " + q); EscVVariable escv = null; if (rx instanceof Local) { int vidx = this.getDomVIdx((Local)rx); escv = new EscVVariable(vidx,domV); } return new DNF(new ClauseSizeCMP(), escv, Value.E()); }
private void performMapping(SootMethod meth, Map<Integer,String> anonymClasses) { if(!meth.isConcrete()) return; for(Unit u : meth.retrieveActiveBody().getUnits()){ Stmt stmt = (Stmt) u; if(!(stmt instanceof AssignStmt)) continue; Value rightOp = ((AssignStmt) stmt).getRightOp(); if(!(rightOp instanceof NewExpr)) continue; String className = rightOp.getType().toString(); int lineNum = this.sourceInfo.stmtLineNum(stmt); String anonymClassName = anonymClasses.get(lineNum); if(anonymClassName == null) continue; String prevBinding = bcClNameToSrcClName.put(className, anonymClassName); System.out.println("binding " + className + " " + anonymClassName); if(prevBinding != null){ System.out.println("Multiple anonymous classes in the same line " + anonymClassName); bcClNameToSrcClName.put(className, null); } } }
public void add(AssignStmt newStmt) { //get lhs of s Value lhs = newStmt.getLeftOp(); removeLhsDepndencies(lhs); //remove lhsOld values from the map of the disjoint values boolean toAdd = true; //check whether newStmt is of the form i0 = i0 + 1 for(Object box : newStmt.getRightOp().getUseBoxes()){ if(((ImmediateBox)box).getValue().equals(lhs)){ toAdd = false; break; } } if(toAdd){ //adding newStmt to the list of reachedStmt reachedStmt.add(newStmt); //for an assignment stmt it's always rhs List<ValueBox> used = newStmt.getRightOp().getUseBoxes(); addUsedVars(used, newStmt); } }
/** * Constructs an array of the given type with a single element of this type * in the given method * @param body The body of the method in which to create the array * @param gen The local generator * @param tp The type of which to create the array * @param constructionStack Set of classes currently being built to avoid * constructor loops * @param parentClasses If a requested type is compatible with one of the * types in this list, the already-created object is used instead of * creating a new one. * @return The local referencing the newly created array, or null if the * array generation failed */ private Value buildArrayOfType(JimpleBody body, LocalGenerator gen, ArrayType tp, Set<SootClass> constructionStack, Set<SootClass> parentClasses) { Local local = gen.generateLocal(tp); // Generate a new single-element array NewArrayExpr newArrayExpr = Jimple.v().newNewArrayExpr(tp.getElementType(), IntConstant.v(1)); AssignStmt assignArray = Jimple.v().newAssignStmt(local, newArrayExpr); body.getUnits().add(assignArray); // Generate a single element in the array AssignStmt assign = Jimple.v().newAssignStmt (Jimple.v().newArrayRef(local, IntConstant.v(19)), getValueForType(body, gen, tp.getElementType(), constructionStack, parentClasses)); body.getUnits().add(assign); return local; }
/** * Modify the value for an array assignment * @param ast * @param locanalysis * @param cc */ public void treatByteArrayAssign(AssignStmt ast, LocalAnalysis locanalysis, CallContext cc) { if (pag == null) return; ArrayRef left = (ArrayRef) ast.getLeftOp(); Local l = (Local) left.getBase(); PointsToSet pts = pag.reachingObjects(l); int index = getConstantValue(locanalysis, ast, left.getIndex()); int contents = getConstantValue(locanalysis, ast, ast.getRightOp()); AbsValue av = P2SAux.p2sContents(cc.nodeTable,pts); if (!(av instanceof OrValue)) return; List<AbsValue> lv = ((OrValue) av).vals; for (AbsValue ava : lv) { if (! (ava instanceof NodeValue)) continue; int id = ((NodeValue) ava).ref; BAAbstraction abs = get(id); if (index == UNKNOWN_CONTENTS) abs.spoil(); else { if (abs.contents == null || contents == UNKNOWN_CONTENTS) abs.spoil(index); else abs.set(index, (byte) contents); } } }
@Override public KillGenInfo propagateCallFlow(Trackable trackable, Unit callStmt, SootMethod destinationMethod) { Taint taint = (Taint) trackable; if (callStmt instanceof AssignStmt) { AssignStmt assignStmt = (AssignStmt) callStmt; if (taint.value.equals(assignStmt.getLeftOp())) { if (AnalysisUtil.isAssignable(taint.type, destinationMethod.getReturnType())) { for (Unit u : context.icfg.getStartPointsOf(destinationMethod)) { if (u instanceof ReturnStmt) { ReturnStmt returnStmt = (ReturnStmt) u; Value retValue = returnStmt.getOp(); if (retValue instanceof Constant) continue; // There is at least one non constant return stmt return propagate(new ReturnValueTaint(callStmt, trackable, taint.type)); } } } } } return kill(); }
@Override protected KillGenInfo handleMethodCall(Taint taint, Stmt callSite, InvokeExpr ie) { if (ie.getMethodRef().getSignature().equals(VALUE_OF)) { if (callSite instanceof AssignStmt) { AssignStmt definitionStmt = (AssignStmt) callSite; final Value returnValue = definitionStmt.getLeftOp(); if (taint.value.equals(returnValue)) { Value objectArg = ie.getArg(0); if (AnalysisUtil.isAssignable(taint.type, objectArg.getType())) return propagate(new Taint(callSite, taint, objectArg, objectArg.getType())); else return kill(); } } } return identity(); }
@Override public KillGenInfo propagateReturnFlow(Trackable trackable, Unit callSite, SootMethod calleeMethod, Unit exitStmt, Unit returnSite) { Taint taint = (Taint) trackable; if (!(exitStmt instanceof ReturnStmt)) return kill(); if (!(callSite instanceof AssignStmt)) return kill(); ReturnStmt returnStmt = (ReturnStmt) exitStmt; AssignStmt assignStmt = (AssignStmt) callSite; if (!returnStmt.getOp().equivTo(taint.value)) return kill(); Value left = AnalysisUtil.getForwardsBase(assignStmt.getLeftOp()); // return propagate(taint.createAlias(left, callSite)); // return propagate(taint.createAlias(left, exitStmt)); return propagate(new ReturnEdgeTaint(callSite, exitStmt, taint, left, -1, taint.type)); }
public static void changeConstantStringInField(SootField sf, String newConstantString) { SootClass sc = sf.getDeclaringClass(); SootMethod sm = sc.getMethodByName("<clinit>"); boolean hasBeenUpdated = false; for (Unit u: sm.retrieveActiveBody().getUnits()) { if (u instanceof AssignStmt) { AssignStmt ass = (AssignStmt)u; Value lop = ass.getLeftOp(); if (lop.toString().equals(sf.toString())) { System.out.println("previous string: "+ ass); ass.setRightOp(StringConstant.v(newConstantString)); hasBeenUpdated = true; System.out.println("updated string : "+ ass); } } } if (!hasBeenUpdated) throw new RuntimeException("error: no StringConstant found for field "+ sf); }
/** * * @param mainActivityClass * @param mainActivityClass */ public static void updateWaitPDPActivity(String packageName, String mainActivityClass) { if (mainActivityClass.startsWith(".")) { mainActivityClass = packageName + mainActivityClass; } SootClass sc = Scene.v().getSootClass("de.ecspride.javaclasses.WaitPDPActivity"); SootMethod sm = sc.getMethodByName("<init>"); Body b = sm.retrieveActiveBody(); for (Unit u: b.getUnits()) { if (u instanceof AssignStmt) { AssignStmt asg = (AssignStmt)u; if (asg.getRightOp() instanceof StringConstant) { StringConstant cst = (StringConstant)asg.getRightOp(); System.out.println("cst: "+ cst); if (cst.value.equals("")) { asg.setRightOp(StringConstant.v(mainActivityClass)); System.out.println("asg: "+ asg); } } } } }
@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)); } } } }
private int findMaxIndexOfArray(InvokeExpr invokeExpr) { Value array = null; int maxIndex = -1; for(Stmt stmt : stmtVisitor.getJimpleDataFlowStatements()) { if(stmt instanceof AssignStmt) { AssignStmt assign = (AssignStmt)stmt; if(array == null) { if(assign.getRightOp().equals(invokeExpr)) { array = assign.getLeftOp(); } } else{ Value rhs = assign.getRightOp(); if(rhs instanceof ArrayRef) { ArrayRef arrayRef = (ArrayRef)rhs; if(arrayRef.getBase().equals(array)) { Value index = arrayRef.getIndex(); if(index instanceof IntConstant) { IntConstant constant = (IntConstant)index; maxIndex = constant.value; } } } } } } return maxIndex; }
private String getValueOfInterestForSplitDataflow(Stmt[] dataflow) { Stmt firstAssign = dataflow[0]; if(firstAssign instanceof AssignStmt) { AssignStmt ass = (AssignStmt)firstAssign; return ass.getLeftOp().toString(); } else throw new RuntimeException("this should not happen - wrong assumption"); }
public static UnitFormatter createFormatter(Unit u) { if(u instanceof AssignStmt) { return new AssignStmtFormatter(); } else if (u instanceof InvokeStmt) { return new InvokeStmtFormatter(); } // no special formatter found, return the default one return new DefaultFormatter(); }
@Override public String format(Unit u, int maxLength) { AssignStmt assignStmt = (AssignStmt) u; String s = ValueFormatter.format(assignStmt.getLeftOp()) + " = " + ValueFormatter.format(assignStmt.getRightOp()); if(s.length() > maxLength) { s = s.substring(0, maxLength) + "\u2026"; } return s; }
private static List<Value> retrieveArrayInitStmts(Body b, Local arrayLocal) { List<Value> arrayInitValues = new ArrayList<Value>(); for (Unit u: b.getUnits()) { if (u instanceof AssignStmt) { AssignStmt ass = (AssignStmt) u; if (ass.getLeftOp() instanceof ArrayRef) { ArrayRef ar = (ArrayRef)ass.getLeftOp(); if (ar.getBase() == arrayLocal) { arrayInitValues.add(ass.getRightOp()); } } } } return arrayInitValues; }
/** * Collect definitions of l in body including the definitions of aliases of l. * * In this context an alias is a local that propagates its value to l. * * @param l the local whose definitions are to collect * @param localDefs the LocalDefs object * @param body the body that contains the local */ protected List<Unit> collectDefinitionsWithAliases(Local l) { Set<Local> seenLocals = new HashSet<Local>(); Stack<Local> newLocals = new Stack<Local>(); List<Unit> defs = new LinkedList<Unit>(); newLocals.push(l); while (!newLocals.empty()) { Local local = newLocals.pop(); logger.debug("[null local] "+ local); if (seenLocals.contains(local)) continue; for (Unit u : collectDefinitions(local)) { if (u instanceof AssignStmt) { Value r = (Value) ((AssignStmt) u).getRightOp(); if (r instanceof Local && ! seenLocals.contains((Local) r)) newLocals.push((Local) r); } defs.add(u); // @SuppressWarnings("unchecked") List<UnitValueBoxPair> usesOf = (List<UnitValueBoxPair>) localUses.getUsesOf(u); for (UnitValueBoxPair pair : usesOf) { Unit unit = pair.getUnit(); if (unit instanceof AssignStmt) { Value right = (Value) ((AssignStmt) unit).getRightOp(); Value left = (Value) ((AssignStmt) unit).getLeftOp(); if (right == local && left instanceof Local && ! seenLocals.contains((Local) left)) newLocals.push((Local) left); } } // } seenLocals.add(local); } return defs; }
private void redirectToContext(Body b, Unit u) { SootClass servicesInitClass = Scene.v().getSootClass( GenerateServiceInit.servicesInitClassName); SootField sf = servicesInitClass.getFieldByName("androidcontentContext"); Value newR = Jimple.v().newStaticFieldRef(sf.makeRef()); logger.debug("replaced context '" + u + " by "); AssignStmt ass = (AssignStmt) u; ass.setRightOp(newR); logger.debug(" " + u); }
private String findUriDef(Body b, Unit u, Local l) { final UnitGraph g = new ExceptionalUnitGraph(b); final SmartLocalDefs localDefs = new SmartLocalDefs(g, new SimpleLiveLocals(g)); final SimpleLocalUses localUses = new SimpleLocalUses(g, localDefs); List<Unit> defs = localDefs.getDefsOfAt((Local) l, u); if (defs.size() == 0) { System.out.println("warning: uri def empty!"); return null; } Unit def = defs.get(0); logger.debug("uri def: " + def); if (def instanceof IdentityStmt) { System.out.println("warning: do not handle uri from identity stmt"); return null; } else if (def instanceof AssignStmt) { AssignStmt ass = (AssignStmt) def; Value r = ass.getRightOp(); if (r instanceof FieldRef) { FieldRef fr = (FieldRef) r; SootField sf = fr.getField(); if (sf.getName().contains("URI")) { String auth = getFieldFromClass(sf); return auth; } } else { System.out.println("warning: uri: do not handle def '" + def + "'"); return null; } } return null; }
private void constructNewObject(Body b, Type localType, SootMethod constructor) { // "new" statement Value lvalue = getLocalWithName(b, makeLocalName(localType), localType); Value rvalue = Jimple.v().newNewExpr( constructor.getDeclaringClass().getType()); AssignStmt ass = Jimple.v().newAssignStmt(lvalue, rvalue); b.getUnits().add(ass); // <init> invocation statement List<Value> args = new ArrayList<Value>(); for (Type argt : (List<Type>) constructor.getParameterTypes()) { if (argt instanceof PrimType) { args.add(IntConstant.v(0)); } else { args.add(getLocalWithName(b, makeLocalName(argt), argt)); } } Value invokeExpr = null; Unit u = null; if (constructor.isStatic()) { invokeExpr = Jimple.v().newStaticInvokeExpr(constructor.makeRef(), args); u = Jimple.v().newAssignStmt(lvalue, invokeExpr); } else { invokeExpr = Jimple.v().newSpecialInvokeExpr((Local) lvalue, constructor.makeRef(), args); u = Jimple.v().newInvokeStmt(invokeExpr); } b.getUnits().add(u); }
private Type getSystemFetcherReturnType(Body b) { ExceptionalUnitGraph g = new ExceptionalUnitGraph(b); SmartLocalDefs localDefs = new SmartLocalDefs(g, new SimpleLiveLocals(g)); SimpleLocalUses localUses = new SimpleLocalUses(g, localDefs); for (Unit u : b.getUnits()) { if (u instanceof JReturnStmt) { JReturnStmt ret = (JReturnStmt) u; Local l = (Local) ret.getOp(); List<Unit> defs = localDefs.getDefsOfAt(l, u); for (Unit d : defs) { if (d instanceof AssignStmt) { AssignStmt ass = (AssignStmt) d; Type t = ass.getRightOp().getType(); if (t instanceof NullType) { System.out.println("warning: null type! " + ass); } else { System.out.println("ok: found return type: " + t); return t; } } } } } System.out.println("warning: no return type found returning void!"); return VoidType.v(); }
public void redirectGetSystemServiceCalls(Body b, List<Unit> getSSStmt, List<String> sSNames, SootClass servicesInitClass) { if (getSSStmt.size() != sSNames.size()) { int callNbr = getSSStmt.size(); int namesNbr = sSNames.size(); throw new RuntimeException("[Error] System Services get calls units should all correspond to a service name! calls: "+ callNbr +" names: "+ namesNbr); } PatchingChain<Unit> units = b.getUnits(); int i = 0; for (Unit u: getSSStmt) { // must be an assignment of the type: r = c.getSystemService("serviceName") if (!(u instanceof AssignStmt)) { throw new RuntimeException("[Error] must be assign statement! Current statement is: "+ u); } // current assignment statement AssignStmt ass = (AssignStmt)u; // create new assignment statement: replacement of call to getSystemService by a reference to // the static field ref to the service (which is created in a custom class called ServicesInit.java) //RefType rt = RefType.v("ServicesInit"); Unit newU = null; if (!servicesInitClass.declaresFieldByName(sSNames.get(i))) { System.out.println("[Warning] servicesInit class does not contain field '"+ sSNames.get(i) +"' replacing statement by nop."); newU = Jimple.v().newAssignStmt(ass.getLeftOp(), NullConstant.v());//Jimple.v().newNopStmt(); } else { SootField sf = servicesInitClass.getFieldByName(sSNames.get(i)); //new SootField(sSNames.get(i), rt, Modifier.STATIC); Value rvalue = Jimple.v().newStaticFieldRef(sf.makeRef()); AssignStmt newAss = Jimple.v().newAssignStmt(ass.getLeftOp(), rvalue); newU = (Unit) newAss; } System.out.println("swapping "+ u +" with "+ newU); units.swapWith(u, newU); i++; } }
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); } }
private boolean isArrayAlloc(Unit sourceStmt) { if (sourceStmt instanceof AssignStmt) { AssignStmt as = (AssignStmt) sourceStmt; if (as.getRightOp() instanceof NewArrayExpr) return true; } return false; }