@Override protected void internalTransform(Body body, String phaseName, Map<String, String> options) { // Do not instrument methods in framework classes if (!canInstrumentMethod(body.getMethod())) return; instrumentInfoAboutNonAPICall(body); //important to use snapshotIterator here Iterator<Unit> iterator = body.getUnits().snapshotIterator(); while(iterator.hasNext()){ Unit unit = iterator.next(); if(unit instanceof ReturnStmt || unit instanceof ReturnVoidStmt) instrumentInfoAboutReturnStmt(body, unit); else if(unit instanceof DefinitionStmt || unit instanceof InvokeStmt) instrumentInfoAboutNonApiCaller(body, unit); else if(unit instanceof IfStmt) instrumentEachBranchAccess(body, (IfStmt)unit); } }
@Override protected void internalTransform(Body body, String phaseName, Map<String, String> options) { // Do not instrument methods in framework classes if (!canInstrumentMethod(body.getMethod())) return; //important to use snapshotIterator here Iterator<Unit> iterator = body.getUnits().snapshotIterator(); while(iterator.hasNext()){ Unit unit = iterator.next(); if(unit instanceof IfStmt && !unit.hasTag(InstrumentedCodeTag.name)) { instrumentEachBranchAccess(body, unit); } } }
public void jimplify(DexBody body) { // check if target instruction has been jimplified if (getTargetInstruction(body).getUnit() != null) { IfStmt s = ifStatement(body); body.add(s); setUnit(s); } else { // set marker unit to swap real gotostmt with otherwise body.addDeferredJimplification(this); markerUnit = Jimple.v().newNopStmt(); unit = markerUnit; // beginUnit = markerUnit; // endUnit = markerUnit; // beginUnit = markerUnit; body.add(markerUnit); // Unit end = Jimple.v().newNopStmt(); // body.add(end); // endUnit = end; } }
protected IfStmt ifStatement(DexBody body) { Instruction22t i = (Instruction22t) instruction; Local one = body.getRegisterLocal(i.getRegisterA()); Local other = body.getRegisterLocal(i.getRegisterB()); BinopExpr condition = getComparisonExpr(one, other); jif = (JIfStmt)Jimple.v().newIfStmt(condition, targetInstruction.getUnit()); // setUnit() is called in ConditionalJumpInstruction if (IDalvikTyper.ENABLE_DVKTYPER) { Debug.printDbg(IDalvikTyper.DEBUG, "constraint if: "+ jif +" condition: "+ condition); DalvikTyper.v().addConstraint(condition.getOp1Box(), condition.getOp2Box()); } return jif; }
/** * Collect all the if statements comparing two locals with an Eq or Ne * expression * * @param body * the body to analyze */ private Set<IfStmt> getNullIfCandidates(Body body) { Set<IfStmt> candidates = new HashSet<IfStmt>(); Iterator<Unit> i = body.getUnits().iterator(); while (i.hasNext()) { Unit u = i.next(); if (u instanceof IfStmt) { ConditionExpr expr = (ConditionExpr) ((IfStmt) u).getCondition(); boolean isTargetIf = false; if (((expr instanceof EqExpr) || (expr instanceof NeExpr))) { if (expr.getOp1() instanceof Local && expr.getOp2() instanceof Local) { isTargetIf = true; } } if (isTargetIf) { candidates.add((IfStmt) u); Debug.printDbg("[add if candidate: ", u); } } } return candidates; }
@Override protected void flowThrough(ConstrainInfo in, Unit s, List<ConstrainInfo> fallOut, List<ConstrainInfo> branchOuts) { //System.out.println("flow through: " + s); //System.out.println("in: "+in); ConstrainInfo out = new ConstrainInfo(in); ConstrainInfo outBranch = new ConstrainInfo(in); if (s instanceof IfStmt) { IfStmt stmt = (IfStmt)s; out.intersect(stmt, false); outBranch.intersect(stmt,true); } for( Iterator<ConstrainInfo> it = fallOut.iterator(); it.hasNext(); ) { //System.out.println("copying to fallout in flowthrough"); copy(out, it.next()); } for( Iterator<ConstrainInfo> it = branchOuts.iterator(); it.hasNext(); ) { //System.out.println("copying to branchout in flowthrough"); copy( outBranch, it.next() ); } }
@Override public String toString(){ String ret = "("; Object[] listStmt = reachedStmt.toArray(); int size = listStmt.length; int i = 0; while(i < size -1){ Object stmt = listStmt[i]; ret +=stmt; if(stmt instanceof IfStmt){ ret += "{" + condToExpr.get(stmt) + "}, "; } else { ret +=", "; } i++; } //last element if any if(size > 0){ ret +=listStmt[i]; if(listStmt[i] instanceof IfStmt){ ret += "{" + condToExpr.get(listStmt[i]) + "}"; } } ret += ")"; return ret; }
private void instrumentEachBranchAccess(Body body, Unit unit){ SootClass sootClass = Scene.v().getSootClass( UtilInstrumenter.JAVA_CLASS_FOR_PATH_INSTRUMENTATION); // Create the method invocation SootMethod createAndAdd = sootClass.getMethod("reportConditionOutcomeSynchronous", Collections.<Type>singletonList(BooleanType.v())); StaticInvokeExpr sieThen = Jimple.v().newStaticInvokeExpr( createAndAdd.makeRef(), IntConstant.v(1)); StaticInvokeExpr sieElse = Jimple.v().newStaticInvokeExpr( createAndAdd.makeRef(), IntConstant.v(0)); Unit sieThenUnit = Jimple.v().newInvokeStmt(sieThen); sieThenUnit.addTag(new InstrumentedCodeTag()); Unit sieElseUnit = Jimple.v().newInvokeStmt(sieElse); sieElseUnit.addTag(new InstrumentedCodeTag()); //treatment of target statement ("true"-branch) IfStmt ifStmt = (IfStmt)unit; Stmt targetStmt = ifStmt.getTarget(); if(!branchTargetStmt.contains(targetStmt.toString())) { branchTargetStmt.add(sieThenUnit.toString()); body.getUnits().insertBefore(sieThenUnit, targetStmt); NopStmt nop = Jimple.v().newNopStmt(); GotoStmt gotoNop = Jimple.v().newGotoStmt(nop); body.getUnits().insertBeforeNoRedirect(nop, targetStmt); body.getUnits().insertBeforeNoRedirect(gotoNop, sieThenUnit); } //treatment of "else"-branch body.getUnits().insertAfter(sieElseUnit, unit); }
private void instrumentEachBranchAccess(Body body, IfStmt ifStmt){ String methodSignature = body.getMethod().getSignature(); String condition = ifStmt.getCondition().toString(); Unit generatedJimpleCodeForBranch = UtilInstrumenter.makeJimpleStaticCallForPathExecution("logInfoAboutBranchAccess", RefType.v("java.lang.String"), StringConstant.v(methodSignature), RefType.v("java.lang.String"), StringConstant.v(condition), RefType.v("java.lang.String"), NullConstant.v() ); generatedJimpleCodeForBranch.addTag(new InstrumentedCodeTag()); Unit generatedJimpleCodeThenBranch = UtilInstrumenter.makeJimpleStaticCallForPathExecution("logInfoAboutBranchAccess", RefType.v("java.lang.String"), StringConstant.v(methodSignature), RefType.v("java.lang.String"), NullConstant.v(), RefType.v("java.lang.String"), StringConstant.v("then branch") ); generatedJimpleCodeThenBranch.addTag(new InstrumentedCodeTag()); Unit generatedJimpleCodeElseBranch = UtilInstrumenter.makeJimpleStaticCallForPathExecution("logInfoAboutBranchAccess", RefType.v("java.lang.String"), StringConstant.v(methodSignature), RefType.v("java.lang.String"), NullConstant.v(), RefType.v("java.lang.String"), StringConstant.v("else branch") ); generatedJimpleCodeElseBranch.addTag(new InstrumentedCodeTag()); body.getUnits().insertBefore(generatedJimpleCodeForBranch, ifStmt); //treatment of target statement ("true"-branch) Stmt targetStmt = ifStmt.getTarget(); if(!branchTargetStmt.contains(targetStmt.toString())) { branchTargetStmt.add(generatedJimpleCodeThenBranch.toString()); body.getUnits().insertBefore(generatedJimpleCodeThenBranch, targetStmt); } //treatment of "else"-branch body.getUnits().insertAfter(generatedJimpleCodeElseBranch, ifStmt); }
private static IfStmt findConditionalStatementForBooleanUnit(IInfoflowCFG cfg, Unit booleanUnit) { Stack<Unit> worklist = new Stack<Unit>(); Set<Unit> processedUnits = new HashSet<Unit>(); worklist.add(booleanUnit); while(!worklist.isEmpty()) { Unit currentUnit = worklist.pop(); //in case of a loop or recursion if(processedUnits.contains(currentUnit)) continue; processedUnits.add(currentUnit); //skip our own instrumented code if(currentUnit.hasTag(InstrumentedCodeTag.name)) continue; //we reached the condition if(currentUnit instanceof IfStmt) { return (IfStmt)currentUnit; } SootMethod methodOfBooleanUnit = cfg.getMethodOf(booleanUnit); DirectedGraph<Unit> graph = cfg.getOrCreateUnitGraph(methodOfBooleanUnit); //Comment: Steven said it should always be a UnitGraph + he will implement a more convenient way in the near future :-) UnitGraph unitGraph = (UnitGraph)graph; SimpleLocalDefs defs = new SimpleLocalDefs(unitGraph); SimpleLocalUses uses = new SimpleLocalUses(unitGraph, defs); List<UnitValueBoxPair> usesOfCurrentUnit = uses.getUsesOf(booleanUnit); for(UnitValueBoxPair valueBoxPair : usesOfCurrentUnit) worklist.add(valueBoxPair.getUnit()); } return null; }
/** * Eliminates all loops of length 0 (if a goto <if a>) * @param body The body from which to eliminate the self-loops */ protected void eliminateSelfLoops(Body body) { // Get rid of self-loops for (Iterator<Unit> unitIt = body.getUnits().iterator(); unitIt.hasNext(); ) { Unit u = unitIt.next(); if (u instanceof IfStmt) { IfStmt ifStmt = (IfStmt) u; if (ifStmt.getTarget() == ifStmt) unitIt.remove(); } } }
public void caseIfStmt(IfStmt stmt) { String varName = printValueAssignment(stmt.getCondition(), "condition"); Unit target = stmt.getTarget(); vtp.suggestVariableName("target"); String targetName = vtp.getLastAssignedVarName(); p.println("Unit "+targetName+"=" + nameOfJumpTarget(target) + ";"); printStmt(stmt,varName,targetName); }
public void internalTransform(Body body, String phaseName, Map<String,String> options) { // really, the analysis should be able to use its own results to determine // that some branches are dead, but since it doesn't we just iterate. boolean changed; do { changed=false; NullnessAnalysis analysis=analysisFactory.newAnalysis(new ExceptionalUnitGraph(body)); Chain<Unit> units=body.getUnits(); Stmt s; for(s=(Stmt) units.getFirst();s!=null;s=(Stmt) units.getSuccOf(s)) { if(!(s instanceof IfStmt)) continue; IfStmt is=(IfStmt) s; Value c=is.getCondition(); if(!(c instanceof EqExpr || c instanceof NeExpr)) continue; BinopExpr e=(BinopExpr) c; Immediate i=null; if(e.getOp1() instanceof NullConstant) i=(Immediate) e.getOp2(); if(e.getOp2() instanceof NullConstant) i=(Immediate) e.getOp1(); if(i==null) continue; boolean alwaysNull = analysis.isAlwaysNullBefore(s, i); boolean alwaysNonNull = analysis.isAlwaysNonNullBefore(s, i); int elim=0; // -1 => condition is false, 1 => condition is true if(alwaysNonNull) elim=c instanceof EqExpr ? -1 : 1; if(alwaysNull) elim=c instanceof EqExpr ? 1 : -1; Stmt newstmt=null; if(elim==-1) newstmt=Jimple.v().newNopStmt(); if(elim==1) newstmt=Jimple.v().newGotoStmt(is.getTarget()); if(newstmt!=null) { units.swapWith(s,newstmt); s=newstmt; changed=true; } } } while(changed); }
@Override public void caseIfStmt(IfStmt stmt) { Stmt target = stmt.getTarget(); exprV.setOrigStmt(stmt); exprV.setTargetForOffset(target); stmt.getCondition().apply(exprV); }
protected IfStmt ifStatement(DexBody body) { Instruction21t i = (Instruction21t) instruction; BinopExpr condition = getComparisonExpr(body, i.getRegisterA()); jif = (JIfStmt) Jimple.v().newIfStmt(condition, targetInstruction.getUnit()); // setUnit() is called in ConditionalJumpInstruction if (IDalvikTyper.ENABLE_DVKTYPER) { Debug.printDbg(IDalvikTyper.DEBUG, "constraint: "+ jif); int op = instruction.getOpcode().value; switch (op) { case 0x38: case 0x39: //DalvikTyper.v().addConstraint(condition.getOp1Box(), condition.getOp2Box()); break; case 0x3a: case 0x3b: case 0x3c: case 0x3d: DalvikTyper.v().setType(condition.getOp1Box(), BooleanType.v(), true); break; default: throw new RuntimeException("error: unknown op: 0x"+ Integer.toHexString(op)); } } return jif; }
/** * 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> getNullCandidates(Body body) { Set<Local> candidates = null; 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 && ((IntConstant) r).value == 0) || (r instanceof LongConstant && ((LongConstant) r).value == 0)) { if (candidates == null) candidates = new HashSet<Local>(); candidates.add(l); Debug.printDbg("[add null candidate: ", u); } } else if (u instanceof IfStmt) { ConditionExpr expr = (ConditionExpr) ((IfStmt) u) .getCondition(); if (isZeroComparison(expr) && expr.getOp1() instanceof Local) { if (candidates == null) candidates = new HashSet<Local>(); candidates.add((Local) expr.getOp1()); Debug.printDbg("[add null candidate if: ", u); } } } return candidates == null ? Collections.<Local>emptySet() : candidates; }
@Test public void testJIfStmt() { IfStmt s = Jimple.v().newIfStmt(Jimple.v().newEqExpr(IntConstant.v(1), IntConstant.v(1)), (Unit) null); s.setTarget(s); // A very tight infinite loop. assertTrue(ExceptionTestUtility.sameMembers(utility.VM_ERRORS, Collections.EMPTY_SET, unitAnalysis.mightThrow(s))); assertEquals(utility.VM_ERRORS_PLUS_SUPERTYPES, utility.catchableSubset(unitAnalysis.mightThrow(s))); }
@Test public void testGIfStmt() { IfStmt s = Grimp.v().newIfStmt(Grimp.v().newEqExpr(IntConstant.v(1), IntConstant.v(1)), (Unit) null); s.setTarget(s); // A very tight infinite loop. assertTrue(ExceptionTestUtility.sameMembers(utility.VM_ERRORS, Collections.EMPTY_SET, unitAnalysis.mightThrow(s))); assertEquals(utility.VM_ERRORS_PLUS_SUPERTYPES, utility.catchableSubset(unitAnalysis.mightThrow(s))); }
public void intersect(IfStmt stmt, boolean bool ) { if (mapping.get(stmt) == null) { mapping.put(stmt, IDX); ++IDX; } Expression<IfStmt> variable = bool?Variable.of(stmt):Not.of(Variable.of(stmt)); expression = And.of(expression, variable); //expression = RuleSet.simplify(expression); }
public static boolean isBranch(Unit u){ if(u instanceof IfStmt || u instanceof GotoStmt || u instanceof SwitchStmt || u instanceof ThrowStmt || u instanceof ReturnStmt || u instanceof ReturnVoidStmt) return true; return false; }
public void removeLhsDepndencies(Value lhs){ Set<Stmt> toRemove = new HashSet<Stmt>(); //remove all statement where lhs has been used if(usedVars.containsKey(lhs)){ toRemove.addAll(usedVars.get(lhs)); } //determine whether exits reachedStmt of AssignStmt with the same lhs for(Stmt stmt : reachedStmt){ if(stmt instanceof AssignStmt){ Value lhsOld = ((AssignStmt) stmt).getLeftOp(); if(lhs.equals(lhsOld)){ //need to remove that statement toRemove.add(stmt); break; } } //conditional stmts are the case of use } // end for loop //remove the statement from the list reachedStmt.removeAll(toRemove); //remove those statements from the key/value set of //usedVars to save memory for(Set<Stmt> es : usedVars.values()){ es.removeAll(toRemove); } //remove from the condToExpr map -- to keep it clean for(Stmt rm : toRemove){ if(rm instanceof IfStmt){ condToExpr.remove(rm); } } }
public void add(IfStmt newStmt, BinopExpr expr) { reachedStmt.add(newStmt); //get Values from rhs and lhs List<ValueBox> used = newStmt.getCondition().getUseBoxes(); addUsedVars(used, newStmt); //add to map condToExpr.put(newStmt, expr); }
@Override protected void flowThrough(AbstractState in, Unit u, List<AbstractState> fallIn, List<AbstractState> branchOut) { Stmt s = (Stmt) u; AbstractState inState = in; AbstractState ifStmtTrue = inState.copy(); //instantiated in ifStmt only; outBranch AbstractState ifStmtFalse = inState.copy();//fallIn; out //only do the computation for a feasible inState //check only for integers? if(in.isFeasible()){ if(s instanceof AssignStmt){ processAssignStmt((AssignStmt)s,inState, ifStmtFalse); } else if (s instanceof IfStmt){ processIfStmt((IfStmt) s, inState, ifStmtFalse, ifStmtTrue); } //other statement modify nothing } for(Iterator<AbstractState> it = fallIn.iterator(); it.hasNext();){ copy(ifStmtFalse, it.next()); } for(Iterator<AbstractState> it = branchOut.iterator(); it.hasNext();){ copy(ifStmtTrue, it.next()); } }
/** * Adds the given collection of {@link LevelLocal}s as well as the given * <em>program counter</em> map to the {@link LocalsMap}. If an * {@link LevelLocal} of the given collection doesn't has an * <em>security level</em> the default <em>security level</em> for local * variables will be taken for this local variable. * * @param locals * The collection of {@link LevelLocal} which should be added. * @param programCounter * The <em>program counter</em> map which should be added. * @see LevelLocal */ public void addAll(Collection<LevelLocal> locals, Map<IfStmt, ILevel> programCounter) { if (programCounter != null) this.programCounter = programCounter; for (LevelLocal extendedLocal : locals) { if (extendedLocal.getLevel() == null) { localMap.put(extendedLocal.getLocal(), mediator.getDefaultVariableSecurityLevel()); } else { localMap.put(extendedLocal.getLocal(), extendedLocal.getLevel()); } } }
@Override public void caseIfStmt(IfStmt stmt) { logger.fine("\n > > > If statement identified < < <"); logger.finest("Use and def boxes of IfStmt: " + stmt.getUseAndDefBoxes().toString()); // Check for all values in the condition if they are a constant value // or if they are stored in a local. In the second case the local is // added // to a list for the locals. List<ValueBox> valueList = stmt.getUseBoxes(); ArrayList<Local> localList = new ArrayList<Local>(); for (ValueBox v : valueList) { Value val = v.getValue(); if (val instanceof Local) { localList.add((Local) val); logger.fine("New local added to local-list of IfStmt: " + val); } } int localListLength = localList.size(); Local[] arguments = new Local[localListLength]; for (int i = 0; i < localListLength; i++) { arguments[i] = localList.get(i); } JimpleInjector.checkCondition(stmt, arguments); }
Set<Constraint<Level>> constraintsForBranches(Unit s, final Environment env, final TypeVar oldPc, final TypeVar newPc) throws TypingException { AbstractStmtSwitch g = new AbstractStmtSwitch() { @Override public void defaultCase(Object obj) { throw new NotImplemented(String.format("Branching statement %s not supported yet.", obj)); } @Override public void caseIfStmt(IfStmt stmt) { Set<Constraint<Level>> cs = new HashSet<>(); // add new pc as upper bound to old pc cs.add(Constraints.<Level>le(CTypes.<Level>variable(oldPc), CTypes.<Level>variable(newPc))); for (Var<?> v : ((List<Var<?>>)seqAsJavaListConverter(Vars.getAllFromValueBoxes(stmt.getUseBoxes()).toSeq()).asJava())) { cs.add(Constraints.le(CTypes.<Level>variable(env.get(v)), CTypes.<Level>variable(newPc))); } setResult(cs); } }; s.apply(g); //noinspection unchecked return (Set<Constraint<Level>>) g.getResult(); }
@Override public void caseIfStmt(IfStmt stmt) { throw new RuntimeException("todo"); }
private void fixExceptions(SootMethod caller, Unit callSite, Set<SootClass> doneSet) { ThrowAnalysis ta = Options.v().src_prec() == Options.src_prec_apk ? DalvikThrowAnalysis.v() : UnitThrowAnalysis.v(); ThrowableSet throwSet = ta.mightThrow(callSite); for (final Trap t : caller.getActiveBody().getTraps()) if (doneSet.add(t.getException()) && throwSet.catchableAs(t.getException().getType())) { SootMethod thrower = exceptionThrowers.get(t.getException()); if (thrower == null) { if (exceptionClass == null) { exceptionClass = new SootClass("FLOWDROID_EXCEPTIONS", Modifier.PUBLIC); Scene.v().addClass(exceptionClass); } // Create the new method thrower = new SootMethod("throw" + exceptionThrowers.size(), Collections.<Type>emptyList(), VoidType.v()); thrower.setModifiers(Modifier.PUBLIC | Modifier.STATIC); final Body body = Jimple.v().newBody(thrower); thrower.setActiveBody(body); final SootMethod meth = thrower; IEntryPointCreator epc = new BaseEntryPointCreator() { @Override public Collection<String> getRequiredClasses() { return Collections.emptySet(); } @Override protected SootMethod createDummyMainInternal(SootMethod emptySootMethod) { LocalGenerator generator = new LocalGenerator(body); // Create the counter used for the opaque predicate int conditionCounter = 0; Value intCounter = generator.generateLocal(IntType.v()); AssignStmt assignStmt = new JAssignStmt(intCounter, IntConstant.v(conditionCounter)); body.getUnits().add(assignStmt); Stmt afterEx = Jimple.v().newNopStmt(); IfStmt ifStmt = Jimple.v().newIfStmt(Jimple.v().newEqExpr(intCounter, IntConstant.v(conditionCounter)), afterEx); body.getUnits().add(ifStmt); conditionCounter++; Local lcEx = generator.generateLocal(t.getException().getType()); AssignStmt assignNewEx = Jimple.v().newAssignStmt(lcEx, Jimple.v().newNewExpr(t.getException().getType())); body.getUnits().add(assignNewEx); InvokeStmt consNewEx = Jimple.v().newInvokeStmt(Jimple.v().newVirtualInvokeExpr(lcEx, Scene.v().makeConstructorRef(exceptionClass, Collections.<Type>emptyList()))); body.getUnits().add(consNewEx); ThrowStmt throwNewEx = Jimple.v().newThrowStmt(lcEx); body.getUnits().add(throwNewEx); body.getUnits().add(afterEx); return meth; } }; epc.createDummyMain(thrower); exceptionThrowers.put(t.getException(), thrower); exceptionClass.addMethod(thrower); } // Call the exception thrower after the old call site Stmt throwCall = Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(thrower.makeRef())); caller.getActiveBody().getUnits().insertBefore(throwCall, callSite); } }
private void getGenAndKillSet(Body body, HashMap<Stmt, HashSet<Value>> absgen, HashMap<Stmt, HashSet<Object>> gen, HashMap<Stmt, HashSet<Value>> kill, HashMap<Stmt, HashSet<Value>> condition) { for (Unit u : body.getUnits()) { Stmt stmt = (Stmt)u; HashSet<Object> genset = new HashSet<Object>(); HashSet<Value> absgenset = new HashSet<Value>(); HashSet<Value> killset = new HashSet<Value>(); HashSet<Value> condset = new HashSet<Value>(); if (stmt instanceof DefinitionStmt) { getGenAndKillSetForDefnStmt((DefinitionStmt)stmt, absgen, genset, absgenset, killset, condset); } else if (stmt instanceof IfStmt) { /* if one of condition is living, than other one is live. */ Value cmpcond = ((IfStmt)stmt).getCondition(); if (cmpcond instanceof ConditionExpr) { Value op1 = ((ConditionExpr)cmpcond).getOp1(); Value op2 = ((ConditionExpr)cmpcond).getOp2(); if (fullSet.contains(op1) && fullSet.contains(op2)) { condset.add(op1); condset.add(op2); genset.add(op1); genset.add(op2); } } } if (genset.size() != 0) gen.put(stmt, genset); if (absgenset.size() != 0) absgen.put(stmt, absgenset); if (killset.size() != 0) kill.put(stmt, killset); if (condset.size() != 0) condition.put(stmt, condset); } }
public void caseIfStmt(IfStmt stmt) { this.handleBinopExpr((BinopExpr)stmt.getCondition(), stmt, BooleanType.v()); }
public void caseIfStmt(IfStmt stmt) { if (uses) { ConditionExpr cond = (ConditionExpr) stmt.getCondition(); BinopExpr expr = cond; Value lv = expr.getOp1(); Value rv = expr.getOp2(); TypeVariable lop; TypeVariable rop; // ******** LEFT ******** if (lv instanceof Local) { lop = resolver.typeVariable((Local) lv); } else if (lv instanceof DoubleConstant) { lop = resolver.typeVariable(DoubleType.v()); } else if (lv instanceof FloatConstant) { lop = resolver.typeVariable(FloatType.v()); } else if (lv instanceof IntConstant) { lop = resolver.typeVariable(IntType.v()); } else if (lv instanceof LongConstant) { lop = resolver.typeVariable(LongType.v()); } else if (lv instanceof NullConstant) { lop = resolver.typeVariable(NullType.v()); } else if (lv instanceof StringConstant) { lop = resolver.typeVariable(RefType.v("java.lang.String")); } else if (lv instanceof ClassConstant) { lop = resolver.typeVariable(RefType.v("java.lang.Class")); } else { throw new RuntimeException("Unhandled binary expression left operand type: " + lv.getClass()); } // ******** RIGHT ******** if (rv instanceof Local) { rop = resolver.typeVariable((Local) rv); } else if (rv instanceof DoubleConstant) { rop = resolver.typeVariable(DoubleType.v()); } else if (rv instanceof FloatConstant) { rop = resolver.typeVariable(FloatType.v()); } else if (rv instanceof IntConstant) { rop = resolver.typeVariable(IntType.v()); } else if (rv instanceof LongConstant) { rop = resolver.typeVariable(LongType.v()); } else if (rv instanceof NullConstant) { rop = resolver.typeVariable(NullType.v()); } else if (rv instanceof StringConstant) { rop = resolver.typeVariable(RefType.v("java.lang.String")); } else if (rv instanceof ClassConstant) { rop = resolver.typeVariable(RefType.v("java.lang.Class")); } else { throw new RuntimeException("Unhandled binary expression right operand type: " + rv.getClass()); } TypeVariable common = resolver.typeVariable(); rop.addParent(common); lop.addParent(common); } }
public void deferredJimplify(DexBody body) { IfStmt s = ifStatement(body); body.getBody().getUnits().swapWith(markerUnit, s); //insertAfter(s, markerUnit); setUnit(s); }
@Override public void caseIfStmt(IfStmt s) { result = result.add(mightThrow(s.getCondition())); }
@Override public void caseIfStmt(IfStmt arg0) { injectLabelStatements(arg0); boolean forceCloneAttibute = false; if (TranslationHelpers.clonedFinallyBlocks.contains(arg0)) { forceCloneAttibute = true; } else if (this.procInfo.duplicatedIfStatement.contains(arg0)) { forceCloneAttibute = true; } Statement[] thenPart = { TranslationHelpers.mkLocationAssertion(arg0, forceCloneAttibute, "thenblock"), this.pf.mkGotoStatement(GlobalsCache.v().getUnitLabel( arg0.getTarget())) }; Statement[] elsePart = {TranslationHelpers.mkLocationAssertion(arg0, forceCloneAttibute, "elseblock")}; // now check if we can find a source location for the else block. // Stmt else_loc = findSuccessorStatement(arg0); // if (else_loc != null) { // // elsePart = new Statement[] { TranslationHelpers // // .mkLocationAssertion(else_loc, forceCloneAttibute) }; // // elsePart = new Statement[] {}; // TODO: test // } arg0.getCondition().apply(this.valueswitch); Expression cond = TranslationHelpers.castBoogieTypes( this.valueswitch.getExpression(), this.pf.getBoolType()); if (isTrivialNullCheck(arg0.getCondition())) { Log.debug("Ignore trivial check "+arg0); for (Statement s : thenPart) { this.boogieStatements.add(s); } } else { this.boogieStatements.add(this.pf.mkIfStatement(cond, thenPart, elsePart)); } // this.boogieStatements.add(TranslationHelpers.mkLocationAssertion(arg0.getTarget(), // forceCloneAttibute, "elseblock")); }
@Override public State merge(State state) { SymbolicState ret = null; if(state instanceof SymbolicState){ SymbolicState other = (SymbolicState)state; Set<Stmt> newSet = new HashSet<Stmt>(); newSet.addAll(reachedStmt); newSet.retainAll(other.getStaments()); // intersection of statements Map<Stmt,BinopExpr> newCond = new HashMap<Stmt, BinopExpr>(); Set<Stmt> removeStmt = new HashSet<Stmt>(); //go through condstmt that must be in both for(Stmt stmt : newSet){ if(stmt instanceof IfStmt){ //get the map values from both states BinopExpr thisExpr = condToExpr.get(stmt); BinopExpr otherExpr = other.getBinop(stmt); //if one of them is null //it means that its INFLOW to while loop //both of them cannot be null if(thisExpr == null && otherExpr == null){ System.err.println("BinopExpr cannot be both null!"); System.exit(2); } if(thisExpr == null){ //override with other newCond.put(stmt, otherExpr); } else if (otherExpr == null){ //override with this newCond.put(stmt, thisExpr); } else if (thisExpr.equals(otherExpr)){ //add one of them newCond.put(stmt, thisExpr); } else { //they are not equals and not null //means merging flows from different //cond branches -- remove the stmt itself removeStmt.add(stmt); //should be only one at a time removed //since soot never merges several flows //at a time } } }//end iterating over cond stmts //remove condStmt of jointed flows newSet.removeAll(removeStmt); Map<Value, Set<Stmt>> newUsed = new HashMap<Value, Set<Stmt>>(); for (Entry<Value, Set<Stmt>> es : usedVars.entrySet()) { // it can happen that other might not have // statements for that variable // if so we don't have to add this variable // to the newUsed map Set<Stmt> otherUsed = other.getUsed(es.getKey()); if (otherUsed != null) { Set<Stmt> newStmtSet = new HashSet<Stmt>(); newStmtSet.addAll(es.getValue()); // remove those that for merged condStmt newStmtSet.removeAll(removeStmt); newStmtSet.retainAll(otherUsed); newUsed.put(es.getKey(), newStmtSet); } } ret = new SymbolicState(newSet, newUsed, newCond); } return ret; }
private void processIfStmt(IfStmt s, AbstractState inState, AbstractState ifStmtFalse, AbstractState ifStmtTrue) { ConditionExpr condExpr = (ConditionExpr)s.getCondition(); Value lhs = condExpr.getOp1(); Value rhs = condExpr.getOp2(); //make sure this is an integer conditional stmt if(isAnyIntType(lhs)){ //add it to the tracked states outputStmt.add(s); //create the set of variables to be tracked Set<Value> track = new HashSet<Value>(); changedVariables.put(s, track); //precondition of the IfStmt Set<Expr> precond = new HashSet<Expr>(); Set<Value> valuesToEval = new HashSet<Value>();//there should be one value only addNotNull(findLocal(lhs), valuesToEval); addNotNull(findLocal(rhs), valuesToEval); //need to make a special case when valuesToEval is empty //it means that both sides are concrete values //hence no need call for the solver for(Value v : valuesToEval){ precond.addAll(evaluateStates(inState, v)); } precond.addAll(evaluateStates(inState, null));//to evaluate symbolic state only //otherwise symbolic state can be evaluated twice -- equality of BinOp has not been implemented //it looks like in Jimple only statement of the same object are equal, but not //if they have the same semantics, assuming that locals are of the same object //do for true branch //add the current expression BinopExpr symbState = condExpr; BinopExpr symbNotState = negate(condExpr); for(Expr be : precond){ symbState = new GAndExpr(symbState, be); symbNotState = new GAndExpr(symbNotState,be); } //at this point we have precondition set //make sure lhs is not a constant if(lhs instanceof JimpleLocal){ //find new values for lhs updateStateCond(lhs,symbState, condExpr, ifStmtTrue, s);//s is only used for the symbolic state updateStateCond(lhs, symbNotState,negate(condExpr), ifStmtFalse, s); condExpr = null; //so no need to update the symbolic state twice track.add(lhs); } //make sure rhs is not a constant if(rhs instanceof JimpleLocal){ updateStateCond(rhs, symbState, condExpr, ifStmtTrue, s); updateStateCond(rhs, symbNotState, negate(condExpr), ifStmtFalse,s ); track.add(rhs); } //created the negated one } // end if this is an integer conditional stmt }
@Override public void caseIfStmt(IfStmt stmt) { handleBranch(stmt.getCondition(), new IfProgramCounterTrigger(stmt)); }
public IfProgramCounterTrigger(IfStmt stmt) { this.stmt = stmt; }