public static Pair<Value, List<Unit>> generateParameterArray(List<Value> parameterList, Body body){ List<Unit> generated = new ArrayList<Unit>(); NewArrayExpr arrayExpr = Jimple.v().newNewArrayExpr(RefType.v("java.lang.Object"), IntConstant.v(parameterList.size())); Value newArrayLocal = generateFreshLocal(body, getParameterArrayType()); Unit newAssignStmt = Jimple.v().newAssignStmt(newArrayLocal, arrayExpr); generated.add(newAssignStmt); for(int i = 0; i < parameterList.size(); i++){ Value index = IntConstant.v(i); ArrayRef leftSide = Jimple.v().newArrayRef(newArrayLocal, index); Value rightSide = generateCorrectObject(body, parameterList.get(i), generated); Unit parameterInArray = Jimple.v().newAssignStmt(leftSide, rightSide); generated.add(parameterInArray); } return new Pair<Value, List<Unit>>(newArrayLocal, generated); }
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; }
/** * 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()); } }
/** * the operations that are not relevant for analysis like "not" or casts * are removed - array refs are only removed if explicitly stated * @param val the value which should be pruned * @param keepArrayRef if false then array refs are pruned to the base array object * @return the value (possibly pruned to base object) */ //we want to keep ArrayRef for objects on the right side of the assignment public static Value selectBase(Value val, boolean keepArrayRef){ //we taint base of array instead of array elements if (val instanceof ArrayRef && !keepArrayRef) { return selectBase(((ArrayRef) val).getBase(), keepArrayRef); } if (val instanceof CastExpr) { return selectBase(((CastExpr) val).getOp(), keepArrayRef); } // Check for unary operators like "not" or "length" if (val instanceof UnopExpr) return selectBase(((UnopExpr) val).getOp(), keepArrayRef); return val; }
void handleAssign(DefinitionStmt stmt) { Value lval = stmt.getLeftOp(); Value rval = stmt.getRightOp(); Variable rvar; if (lval instanceof Local) { rvar = getLocalVariable((Local)lval); } else { rvar = jt.makeVariable(rval); } et.translateExpr(rvar, stmt.getRightOpBox()); if (lval instanceof ArrayRef) { notSupported("We do not support arrays"); } else if (lval instanceof FieldRef) { notSupported("We do not support field references"); } }
public void caseArrayRef(ArrayRef v) { String oldName = varName; Value base = v.getBase(); suggestVariableName("base"); String baseName = varName; base.apply(this); Value index = v.getIndex(); suggestVariableName("index"); String indexName = varName; index.apply(this); p.println("Value "+oldName+" = Jimple.v().newArrayRef("+baseName+", "+indexName+");"); varName = oldName; }
public void jimplify (DexBody body) { if(!(instruction instanceof Instruction23x)) throw new IllegalArgumentException("Expected Instruction23x but got: "+instruction.getClass()); Instruction23x aPutInstr = (Instruction23x)instruction; int source = aPutInstr.getRegisterA(); Local arrayBase = body.getRegisterLocal(aPutInstr.getRegisterB()); Local index = body.getRegisterLocal(aPutInstr.getRegisterC()); ArrayRef arrayRef = Jimple.v().newArrayRef(arrayBase, index); Local sourceValue = body.getRegisterLocal(source); assign = getAssignStmt(body, sourceValue, arrayRef); if (aPutInstr.getOpcode().value == Opcode.APUT_OBJECT.value) assign.addTag(new ObjectOpTag()); setUnit(assign); addTags(assign); body.add(assign); if (IDalvikTyper.ENABLE_DVKTYPER) { Debug.printDbg(IDalvikTyper.DEBUG, "constraint: "+ assign); DalvikTyper.v().addConstraint(assign.getLeftOpBox(), assign.getRightOpBox()); DalvikTyper.v().setType(arrayRef.getIndexBox(), IntType.v(), true); } }
private void convertArrayLoadInsn(InsnNode insn) { StackFrame frame = getFrame(insn); Operand[] out = frame.out(); Operand opr; if (out == null) { Operand indx = popImmediate(); Operand base = popImmediate(); ArrayRef ar = Jimple.v().newArrayRef( base.stackOrValue(), indx.stackOrValue()); indx.addBox(ar.getIndexBox()); base.addBox(ar.getBaseBox()); opr = new Operand(insn, ar); frame.in(indx, base); frame.boxes(ar.getIndexBox(), ar.getBaseBox()); frame.out(opr); } else { opr = out[0]; frame.mergeIn(pop(), pop()); } int op = insn.getOpcode(); if (op == DALOAD || op == LALOAD) pushDual(opr); else push(opr); }
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()); } }
@Test public void testJArrayRef() { ArrayRef arrayRef = Jimple.v().newArrayRef( Jimple.v().newLocal("local1", ArrayType.v(RefType.v("java.lang.Object"), 1)), IntConstant.v(0)); Set expectedRep = new ExceptionHashSet(utility.VM_ERRORS); expectedRep.add(utility.NULL_POINTER_EXCEPTION); expectedRep.add(utility.ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION); assertTrue(ExceptionTestUtility.sameMembers(expectedRep, Collections.EMPTY_SET, unitAnalysis.mightThrow(arrayRef))); Set expectedCatch = new ExceptionHashSet(utility.VM_ERRORS_PLUS_SUPERTYPES); expectedCatch.add(utility.NULL_POINTER_EXCEPTION); expectedCatch.add(utility.ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION); expectedCatch.add(utility.INDEX_OUT_OF_BOUNDS_EXCEPTION); expectedCatch.add(utility.RUNTIME_EXCEPTION); expectedCatch.add(utility.EXCEPTION); assertEquals(expectedCatch, utility.catchableSubset(unitAnalysis.mightThrow(arrayRef))); }
@Test public void testGArrayRef() { ArrayRef arrayRef = Grimp.v().newArrayRef( Grimp.v().newLocal("local1", ArrayType.v(RefType.v("java.lang.Object"), 1)), IntConstant.v(0)); Set expectedRep = new ExceptionHashSet(utility.VM_ERRORS); expectedRep.add(utility.NULL_POINTER_EXCEPTION); expectedRep.add(utility.ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION); assertTrue(ExceptionTestUtility.sameMembers(expectedRep, Collections.EMPTY_SET, unitAnalysis.mightThrow(arrayRef))); Set expectedCatch = new ExceptionHashSet(utility.VM_ERRORS_PLUS_SUPERTYPES); expectedCatch.add(utility.NULL_POINTER_EXCEPTION); expectedCatch.add(utility.ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION); expectedCatch.add(utility.INDEX_OUT_OF_BOUNDS_EXCEPTION); expectedCatch.add(utility.RUNTIME_EXCEPTION); expectedCatch.add(utility.EXCEPTION); assertEquals(expectedCatch, utility.catchableSubset(unitAnalysis.mightThrow(arrayRef))); }
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()); }
/** * 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()); }
/** * the operations that are not relevant for analysis like "not" or casts * are removed - array refs are only removed if explicitly stated * @param val the value which should be pruned * @param keepArrayRef if false then array refs are pruned to the base array object * @return the value (possibly pruned to base object) */ //we want to keep ArrayRef for objects on the right side of the assignment public static Value selectBase(Value val, boolean keepArrayRef){ //we taint base of array instead of array elements if (val instanceof ArrayRef && !keepArrayRef) { return selectBase(((ArrayRef) val).getBase(), keepArrayRef); } if (val instanceof JCastExpr) { return selectBase(((JCastExpr) val).getOpBox().getValue(), keepArrayRef); } // Check for unary operators like "not" or "length" if (val instanceof UnopExpr) return selectBase(((UnopExpr) val).getOp(), keepArrayRef); return val; }
public boolean addTaintValue(TaintValue tv){ if(!isInTaintSet(tv)){ this.taintsSet.add(tv); //[start] array additional Value v = tv.getTaintValue(); if(v instanceof ArrayRef){ Value arrayBase = ((ArrayRef) v).getBase(); TaintValue arrayTV = new TaintValue(tv.getActivation(), arrayBase); addTaintValue(arrayTV); } //[end] return true; } return false; }
/** * * @param value * @param currUnit currUnit must be after the TaintValue's activation * @return == */ public TaintValue isTainted(Value value, Unit currUnit){ TaintValue result = null; Value handledValue = null; //[start] array additional, CastExpt if(value instanceof ArrayRef){ handledValue = ((ArrayRef) value).getBase(); }else if(value instanceof CastExpr){ handledValue = ((CastExpr) value).getOp(); }else{ handledValue = value; } //[end] for(TaintValue tv : taintsSet){ Unit activation = tv.getActivation(); Value tmp = tv.getTaintValue(); if(tmp.toString().equals(handledValue.toString()) && allUnits.indexOf(activation) < allUnits.indexOf(currUnit)){ result = tv; break; } } return result; }
/** * 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); } } }
public static boolean isWrongType(Value value) { while (value.getType() instanceof ArrayRef) { value = ((ArrayRef) value.getType()).getBase(); } if (value instanceof PrimType) { return true; } Type type = value.getType(); while (type instanceof ArrayType) { type = ((ArrayType) type).getArrayElementType(); } if (type instanceof PrimType) return true; if (!type.toString().contains("String") && !type.toString().contains("Object") && !type.toString().contains("Serializable") && !type.toString().contains("Comparable") && !type.toString().contains("CharSequence")) return true; return false; }
private boolean isPrimitive(Value value) { while (value.getType() instanceof ArrayRef) { value = ((ArrayRef) value.getType()).getBase(); } if (value instanceof PrimType) { return true; } Type type = value.getType(); while (type instanceof ArrayType) { type = ((ArrayType) type).getArrayElementType(); } if (type instanceof PrimType) return true; return false; }
/** * * @param parameter * @param body * @return */ private Pair<Value, List<Unit>> generateParameterArray(List<Value> parameter, Body body){ List<Unit> generated = new ArrayList<Unit>(); NewArrayExpr arrayExpr = Jimple.v().newNewArrayExpr(RefType.v("java.lang.Object"), IntConstant.v(parameter.size())); Value newArrayLocal = generateFreshLocal(body, getParameterArrayType()); Unit newAssignStmt = Jimple.v().newAssignStmt(newArrayLocal, arrayExpr); generated.add(newAssignStmt); for(int i = 0; i < parameter.size(); i++){ Value index = IntConstant.v(i); ArrayRef leftSide = Jimple.v().newArrayRef(newArrayLocal, index); Value rightSide = generateCorrectObject(body, parameter.get(i), generated); Unit parameterInArray = Jimple.v().newAssignStmt(leftSide, rightSide); generated.add(parameterInArray); } return new Pair<Value, List<Unit>>(newArrayLocal, generated); }
@Override public void caseArrayRef(ArrayRef v) { arrayRef = v; Value array = arrayRef.getBase(); Value index = arrayRef.getIndex(); SecurityConstraintValueReadSwitch baseSwitch = getReadSwitch(array); SecurityConstraintValueReadSwitch indexSwitch = getReadSwitch(index); addReadComponents(baseSwitch.getReadComponents()); addReadComponents(indexSwitch.getReadComponents()); setComponentDimension(AnalysisUtils.getDimension(v.getType())); if (baseSwitch.getEqualComponents().size() > 0) { addWriteComponent(baseSwitch.getEqualComponents().get(0)); for (int i = 1; i < baseSwitch.getEqualComponents().size(); i++) { appendEqualComponent(baseSwitch.getEqualComponents().get(1)); } } }
@Override public void caseArrayRef(ArrayRef v) { Value array = v.getBase(); Value index = v.getIndex(); SecurityConstraintValueReadSwitch baseSwitch = getReadSwitch(array); SecurityConstraintValueReadSwitch indexSwitch = getReadSwitch(index); addInheritedWriteEffects(baseSwitch.getInheritedWriteEffects()); addInheritedWriteEffects(indexSwitch.getInheritedWriteEffects()); addReadComponents(baseSwitch.getReadComponents()); addReadComponents(indexSwitch.getReadComponents()); setComponentDimension(getDimension(v.getType())); if (baseSwitch.getEqualComponents().size() > 0) { addReadComponent(baseSwitch.getEqualComponents().get(0)); for (int i = 1; i < baseSwitch.getEqualComponents().size(); i++) { appendEqualComponent(baseSwitch.getEqualComponents().get(1)); } } }
/** * Add the level of a read array field to the security-level-list. * @param a -ArrayRef- The referenced array field * @param pos -Unit- The position where this reference occurs */ public static void addLevelInAssignStmt(ArrayRef a, Unit pos) { logger.info( "Add Level of Array " + a.toString() + " in assign stmt"); ArrayList<Type> parameterTypes = new ArrayList<Type>(); parameterTypes.add(RefType.v("java.lang.Object")); parameterTypes.add(RefType.v("java.lang.String")); String signature = getSignatureForArrayField(a); Unit assignSignature = Jimple.v().newAssignStmt( local_for_Strings, StringConstant.v(signature)); unitStore_Before.insertElement(unitStore_Before.new Element(assignSignature, pos)); lastPos = assignSignature; Expr addObj = Jimple.v().newVirtualInvokeExpr( hs, Scene.v().makeMethodRef(Scene.v().getSootClass(HANDLE_CLASS), "joinLevelOfArrayFieldAndAssignmentLevel", parameterTypes, Scene.v().getObjectType(), false), a.getBase(), local_for_Strings); Unit assignExpr = Jimple.v().newInvokeStmt(addObj); unitStore_Before.insertElement(unitStore_Before.new Element(assignExpr, pos)); lastPos = pos; }
public SMTBinding getCorrectBindingForArrayRef(ArrayRef arrayRef) { for(Map.Entry<String, SMTBinding> entry : arrayHelper.entrySet()) { if(entry.getKey().equals(arrayRef.toString())) return entry.getValue(); } return null; }
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 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; }
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; }
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 buildArrayPutInsn(ArrayRef destRef, Value source) { Value array = destRef.getBase(); Register arrayReg = regAlloc.asLocal(array); Value index = destRef.getIndex(); Register indexReg = regAlloc.asImmediate(index, constantV); Register sourceReg = regAlloc.asImmediate(source, constantV); String arrayTypeDescriptor = SootToDexUtils.getArrayTypeDescriptor((ArrayType) array.getType()); Opcode opc = getPutGetOpcodeWithTypeSuffix("aput", arrayTypeDescriptor); return new Insn23x(opc, sourceReg, arrayReg, indexReg); }
private Insn buildArrayGetInsn(Register destinationReg, ArrayRef sourceRef) { Value index = sourceRef.getIndex(); Register indexReg = regAlloc.asImmediate(index, constantV); Value array = sourceRef.getBase(); Register arrayReg = regAlloc.asLocal(array); String arrayTypeDescriptor = SootToDexUtils.getArrayTypeDescriptor((ArrayType) array.getType()); Opcode opc = getPutGetOpcodeWithTypeSuffix("aget", arrayTypeDescriptor); return new Insn23x(opc, destinationReg, arrayReg, indexReg); }
public void jimplify (DexBody body) throws InvalidDalvikBytecodeException { if(!(instruction instanceof Instruction23x)) throw new IllegalArgumentException("Expected Instruction23x but got: "+instruction.getClass()); Instruction23x aGetInstr = (Instruction23x)instruction; int dest = aGetInstr.getRegisterA(); Local arrayBase = body.getRegisterLocal(aGetInstr.getRegisterB()); Local index = body.getRegisterLocal(aGetInstr.getRegisterC()); ArrayRef arrayRef = Jimple.v().newArrayRef(arrayBase, index); Local l = body.getRegisterLocal(dest); assign = Jimple.v().newAssignStmt(l, arrayRef); if (aGetInstr.getOpcode().value == Opcode.AGET_OBJECT.value) assign.addTag(new ObjectOpTag()); setUnit(assign); addTags(assign); body.add(assign); if (IDalvikTyper.ENABLE_DVKTYPER) { Debug.printDbg(IDalvikTyper.DEBUG, "constraint: "+ assign); DalvikTyper.v().addConstraint(assign.getLeftOpBox(), assign.getRightOpBox()); DalvikTyper.v().setType(arrayRef.getIndexBox(), IntType.v(), true); } }
public boolean isInSequenceAssignment(Stmt s, Value leftOp, int index){ //DEBUG=false; if(!(s instanceof DefinitionStmt)) return false; DefinitionStmt ds = (DefinitionStmt)s; Value leftValue = ds.getLeftOp(); if(! (leftValue instanceof ArrayRef)) return false; if(DEBUG){ System.out.println("Stmt number "+index + " is an array ref assignment"+leftValue); System.out.println("Array is"+leftOp); } ArrayRef leftRef = (ArrayRef)leftValue; if(! (leftOp.equals(leftRef.getBase()))){ if(DEBUG) System.out.println("Not assigning to same array"); return false; } if( ! (leftRef.getIndex() instanceof IntConstant)){ if(DEBUG) System.out.println("Cant determine index of assignment"); return false; } IntConstant leftIndex = (IntConstant)leftRef.getIndex(); if(leftIndex.value != index){ if(DEBUG) System.out.println("Out of order assignment"); return false; } return true; }
@Override public void caseAssignStmt(AssignStmt s) { Value lhs = s.getLeftOp(); if (lhs instanceof ArrayRef && (lhs.getType() instanceof UnknownType || lhs.getType() instanceof RefType)) { // This corresponds to an aastore byte code. result = result.add(mgr.ARRAY_STORE_EXCEPTION); } result = result.add(mightThrow(s.getLeftOp())); result = result.add(mightThrow(s.getRightOp())); }
@Override public boolean isApplicable(UnitGraph graph, Set<Unit> input, Unit node, Set<Unit> output, Set<Value> taintedValues, Queue<MethodAnalysis> queue, Set<MethodAnalysis> processed) { return !input.isEmpty() && node instanceof AssignStmt && ((AssignStmt)node).getRightOp() instanceof ArrayRef; }
@Override public void propagateTaint(UnitGraph graph, Set<Unit> input, Unit node, Set<Unit> output, Set<Value> taintedValues, Queue<MethodAnalysis> queue, Set<MethodAnalysis> processed) { assert(isApplicable(graph, input, node, output, taintedValues, queue, processed)); if(isTainted(taintedValues, node)) taintedValues.add(((ArrayRef)((AssignStmt)node).getRightOp()).getBase()); }