/** * 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 public ConditionExpr instantitate(Value var) { ConditionExpr ret = null; IntConstant valInt = IntConstant.v(Integer.parseInt(val)); switch(op){ case "=": ret = new GEqExpr(var,valInt); break; case ">=" : ret = new GGeExpr(var, valInt); break; case ">" : ret = new GGtExpr(var, valInt); break; case "<=" : ret = new GLeExpr(var, valInt); break; case "<" : ret = new GLtExpr(var, valInt); break; case "!=" : ret = new GNeExpr(var, valInt); break; } if(ret == null){ System.out.println("Cannot initialize interval predicate"); System.exit(2); } return ret; }
/** * Examine expr if it is a comparison with 0. * * @param expr * the ConditionExpr to examine */ protected boolean isZeroComparison(ConditionExpr expr) { if (expr instanceof EqExpr || expr instanceof NeExpr) { if (expr.getOp2() instanceof IntConstant && ((IntConstant) expr.getOp2()).value == 0) return true; if (expr.getOp2() instanceof LongConstant && ((LongConstant) expr.getOp2()).value == 0) return true; } return false; }
/** * Get comparison expression depending on opcode between two immediates * * @param one first immediate * @param other second immediate * @throws RuntimeException if this is not a IfTest or IfTestz instruction. */ protected ConditionExpr getComparisonExpr(Immediate one, Immediate other) { Opcode opcode = instruction.getOpcode(); switch(opcode) { case IF_EQ: case IF_EQZ: return Jimple.v().newEqExpr(one, other); case IF_NE: case IF_NEZ: return Jimple.v().newNeExpr(one, other); case IF_LT: case IF_LTZ: return Jimple.v().newLtExpr(one, other); case IF_GE: case IF_GEZ: return Jimple.v().newGeExpr(one, other); case IF_GT: case IF_GTZ: return Jimple.v().newGtExpr(one, other); case IF_LE: case IF_LEZ: return Jimple.v().newLeExpr(one, other); default: throw new RuntimeException("Instruction is not an IfTest(z) instruction."); } }
/** * 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; }
private void javafy_binop_expr(ValueBox vb) { BinopExpr boe = (BinopExpr) vb.getValue(); ValueBox leftOpBox = boe.getOp1Box(), rightOpBox = boe.getOp2Box(); Value leftOp = leftOpBox.getValue(), rightOp = rightOpBox.getValue(); if (rightOp instanceof IntConstant) { if ((leftOp instanceof IntConstant) == false) { javafy(leftOpBox); leftOp = leftOpBox.getValue(); if (boe instanceof ConditionExpr) rightOpBox.setValue(DIntConstant.v( ((IntConstant) rightOp).value, leftOp.getType())); else rightOpBox.setValue(DIntConstant.v( ((IntConstant) rightOp).value, null)); } } else if (leftOp instanceof IntConstant) { javafy(rightOpBox); rightOp = rightOpBox.getValue(); if (boe instanceof ConditionExpr) leftOpBox.setValue(DIntConstant.v(((IntConstant) leftOp).value, rightOp.getType())); else leftOpBox.setValue(DIntConstant.v(((IntConstant) leftOp).value, null)); } else { javafy(rightOpBox); rightOp = rightOpBox.getValue(); javafy(leftOpBox); leftOp = leftOpBox.getValue(); } if (boe instanceof CmpExpr) vb.setValue(new DCmpExpr(leftOp, rightOp)); else if (boe instanceof CmplExpr) vb.setValue(new DCmplExpr(leftOp, rightOp)); else if (boe instanceof CmpgExpr) vb.setValue(new DCmpgExpr(leftOp, rightOp)); }
/** * 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); }
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) { 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); } }
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 }
private AbsValue analyzeConditionExpr(ConditionExpr rc, Unit u, Set<Unit> seen) { AbsValue av1 = analyze_expr(rc.getOp1(),u,seen); AbsValue av2 = analyze_expr(rc.getOp2(),u,seen); return new MethValue(rc.getSymbol().trim(), av1,av2); }
/** * Get comparison expression depending on opcode against zero or null. * * If the register is used as an object this will create a comparison with * null, not zero. * * @param body the containing DexBody * @param reg the register to compare against zero. */ protected ConditionExpr getComparisonExpr(DexBody body, int reg) { Local one = body.getRegisterLocal(reg); return getComparisonExpr(one, IntConstant.v(0)); }
public abstract ConditionExpr instantitate(Value var);