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 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); }
public static void removeUnit(Body b, Unit u) { LocalGenerator lg = new LocalGenerator(b); if (u instanceof DefinitionStmt) { DefinitionStmt def = (DefinitionStmt) u; Type t = def.getRightOp().getType(); if (!(t instanceof PrimType)) { Local l_obj = lg.generateLocal(RefType.v("java.lang.Object")); Local l_type = lg.generateLocal(t); Unit u1 = Jimple.v().newAssignStmt(l_obj, Jimple.v().newNewExpr(RefType.v("java.lang.Object"))); Unit u2 = Jimple.v().newAssignStmt(l_type, Jimple.v().newCastExpr(l_obj, t)); def.getRightOpBox().setValue(l_type); b.getUnits().insertBefore(u1, u); b.getUnits().insertBefore(u2, u); return; } } b.getUnits().remove(u); }
private void insertCastOrBoxingCode(Local lhs, Local rhs, Chain<Unit> newUnits) { //if assigning to a primitive type then there's nothing to do if(lhs.getType() instanceof RefLikeType) { if((rhs.getType() instanceof RefLikeType)) { //insert cast newUnits.add(Jimple.v().newAssignStmt(lhs, Jimple.v().newCastExpr(rhs, lhs.getType()))); } else { //primitive type in rhs; insert boxing code RefType boxedType = ((PrimType)rhs.getType()).boxedType(); SootMethodRef ref = Scene.v().makeMethodRef( boxedType.getSootClass(), "valueOf", Collections.<Type>singletonList(rhs.getType()), boxedType, true ); newUnits.add(Jimple.v().newAssignStmt(lhs, Jimple.v().newStaticInvokeExpr(ref,rhs))); } } }
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); } }
public void jimplify (DexBody body) { TwoRegisterInstruction i = (TwoRegisterInstruction)instruction; int dest = i.getRegisterA(); int object = i.getRegisterB(); FieldReference f = (FieldReference)((ReferenceInstruction)instruction).getReference(); InstanceFieldRef r = Jimple.v().newInstanceFieldRef(body.getRegisterLocal(object), getSootFieldRef(f)); assign = Jimple.v().newAssignStmt(body.getRegisterLocal(dest), r); setUnit(assign); addTags(assign); body.add(assign); if (IDalvikTyper.ENABLE_DVKTYPER) { Debug.printDbg(IDalvikTyper.DEBUG, "constraint: "+ assign); int op = (int)instruction.getOpcode().value; DalvikTyper.v().setType(assign.getLeftOpBox(), r.getType(), false); } }
/** * 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; }
@Ignore("Fails") @Test public void testJReturnVoidStmt() { Stmt s = Jimple.v().newReturnVoidStmt(); Set expectedRep = new ExceptionHashSet(utility.VM_ERRORS); expectedRep.add(utility.ILLEGAL_MONITOR_STATE_EXCEPTION); assertTrue(ExceptionTestUtility.sameMembers(expectedRep, Collections.EMPTY_SET, unitAnalysis.mightThrow(s))); Set expectedCatch = new ExceptionHashSet(utility.VM_ERRORS_PLUS_SUPERTYPES); expectedCatch.add(utility.ILLEGAL_MONITOR_STATE_EXCEPTION); expectedCatch.add(utility.RUNTIME_EXCEPTION); expectedCatch.add(utility.EXCEPTION); assertEquals(expectedCatch, utility.catchableSubset(unitAnalysis.mightThrow(s))); }
/** * 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; }
/** * Catch Formal creation - method parameters */ private soot.Local createCatchFormal(polyglot.ast.Formal formal){ soot.Type sootType = Util.getSootType(formal.type().type()); soot.Local formalLocal = createLocal(formal.localInstance()); soot.jimple.CaughtExceptionRef exceptRef = soot.jimple.Jimple.v().newCaughtExceptionRef(); soot.jimple.Stmt stmt = soot.jimple.Jimple.v().newIdentityStmt(formalLocal, exceptRef); body.getUnits().add(stmt); Util.addLnPosTags(stmt, formal.position()); Util.addLnPosTags(((soot.jimple.IdentityStmt) stmt).getRightOpBox(), formal.position()); ArrayList<String> names = new ArrayList<String>(); names.add(formal.name()); stmt.addTag(new soot.tagkit.ParamNamesTag(names)); return formalLocal; }
public Value createJimpleConstantValue(cp_info[] constant_pool) { CONSTANT_Class_info cc = (CONSTANT_Class_info) (constant_pool[class_index]); CONSTANT_NameAndType_info cn = (CONSTANT_NameAndType_info) (constant_pool[name_and_type_index]); String className = cc.toString(constant_pool); String nameAndType = cn.toString(constant_pool); String name = nameAndType.substring(0, nameAndType.indexOf(":")); String typeName = nameAndType.substring(nameAndType.indexOf(":") + 1); List parameterTypes; Type returnType; // Generate parameters & returnType & parameterTypes { Type[] types = Util.v().jimpleTypesOfFieldOrMethodDescriptor( typeName); parameterTypes = new ArrayList(); for (int k = 0; k < types.length - 1; k++) { parameterTypes.add(types[k]); } returnType = types[types.length - 1]; } return Jimple.v().newStaticInvokeExpr(Scene.v().makeMethodRef(Scene.v().getSootClass(className), name, parameterTypes, returnType, true)); }
public void outAMultiNewExpr(AMultiNewExpr node) { LinkedList arrayDesc = node.getArrayDescriptor(); int descCnt = arrayDesc.size(); List sizes = new LinkedList(); Iterator it = arrayDesc.iterator(); while(it.hasNext()) { AArrayDescriptor o = (AArrayDescriptor) it.next(); if(o.getImmediate() != null) sizes.add(0,mProductions.removeLast()); else break; } Type type = (Type) mProductions.removeLast(); ArrayType arrayType = ArrayType.v(type, descCnt); mProductions.addLast(Jimple.v().newNewMultiArrayExpr(arrayType, sizes)); }
public void jimplify (DexBody body) { int dest = ((OneRegisterInstruction) instruction).getRegisterA(); Constant cst = getConstant(dest, body); assign = Jimple.v().newAssignStmt(body.getRegisterLocal(dest), cst); setUnit(assign); addTags(assign); body.add(assign); if (IDalvikTyper.ENABLE_DVKTYPER) { Debug.printDbg(IDalvikTyper.DEBUG, "constraint: "+ assign); int op = (int)instruction.getOpcode().value; if (cst instanceof UntypedConstant) { DalvikTyper.v().addConstraint(assign.getLeftOpBox(), assign.getRightOpBox()); } else { DalvikTyper.v().setType(assign.getLeftOpBox(), cst.getType(), false); } } }
private soot.Value getSimpleAssignLocal(polyglot.ast.Assign assign){ soot.jimple.AssignStmt stmt; soot.Value left = base().createLHS(assign.left()); soot.Value right = base().getSimpleAssignRightLocal(assign); stmt = soot.jimple.Jimple.v().newAssignStmt(left, right); body.getUnits().add(stmt); Util.addLnPosTags(stmt, assign.position()); Util.addLnPosTags(stmt.getRightOpBox(), assign.right().position()); Util.addLnPosTags(stmt.getLeftOpBox(), assign.left().position()); if (left instanceof soot.Local){ return left; } else { return right; } }
private soot.Value getStrConAssignLocal(polyglot.ast.Assign assign){ soot.jimple.AssignStmt stmt; soot.Value left = base().createLHS(assign.left()); soot.Value right = getStringConcatAssignRightLocal(assign); stmt = soot.jimple.Jimple.v().newAssignStmt(left, right); body.getUnits().add(stmt); Util.addLnPosTags(stmt, assign.position()); Util.addLnPosTags(stmt.getRightOpBox(), assign.right().position()); Util.addLnPosTags(stmt.getLeftOpBox(), assign.left().position()); if (left instanceof soot.Local){ return left; } else { return right; } }
/** * creates a field ref */ protected soot.jimple.FieldRef getFieldRef(polyglot.ast.Field field) { soot.SootClass receiverClass = ((soot.RefType)Util.getSootType(field.target().type())).getSootClass(); soot.SootFieldRef receiverField = soot.Scene.v().makeFieldRef(receiverClass, field.name(), Util.getSootType(field.type()), field.flags().isStatic()); soot.jimple.FieldRef fieldRef; if (field.fieldInstance().flags().isStatic()) { fieldRef = soot.jimple.Jimple.v().newStaticFieldRef(receiverField); } else { soot.Local base; base = (soot.Local)base().getBaseLocal(field.target()); fieldRef = soot.jimple.Jimple.v().newInstanceFieldRef(base, receiverField); } if (field.target() instanceof polyglot.ast.Local && fieldRef instanceof soot.jimple.InstanceFieldRef){ Util.addLnPosTags(((soot.jimple.InstanceFieldRef)fieldRef).getBaseBox(), field.target().position()); } return fieldRef; }
private soot.Local createStringBuffer(polyglot.ast.Expr expr){ // create and add one string buffer soot.Local local = lg.generateLocal(soot.RefType.v("java.lang.StringBuffer")); soot.jimple.NewExpr newExpr = soot.jimple.Jimple.v().newNewExpr(soot.RefType.v("java.lang.StringBuffer")); soot.jimple.Stmt assign = soot.jimple.Jimple.v().newAssignStmt(local, newExpr); body.getUnits().add(assign); Util.addLnPosTags(assign, expr.position()); soot.SootClass classToInvoke1 = soot.Scene.v().getSootClass("java.lang.StringBuffer"); soot.SootMethodRef methodToInvoke1 = soot.Scene.v().makeMethodRef(classToInvoke1, "<init>", new ArrayList(), soot.VoidType.v(), false); soot.jimple.SpecialInvokeExpr invoke = soot.jimple.Jimple.v().newSpecialInvokeExpr(local, methodToInvoke1); soot.jimple.Stmt invokeStmt = soot.jimple.Jimple.v().newInvokeStmt(invoke); body.getUnits().add(invokeStmt); Util.addLnPosTags(invokeStmt, expr.position()); return local; }
public void jimplify (DexBody body) { TwoRegisterInstruction i = (TwoRegisterInstruction)instruction; int source = i.getRegisterA(); int object = i.getRegisterB(); FieldReference f = (FieldReference)((ReferenceInstruction)instruction).getReference(); InstanceFieldRef instanceField = Jimple.v().newInstanceFieldRef(body.getRegisterLocal(object), getSootFieldRef(f)); Local sourceValue = body.getRegisterLocal(source); assign = getAssignStmt(body, sourceValue, instanceField); setUnit(assign); addTags(assign); body.add(assign); if (IDalvikTyper.ENABLE_DVKTYPER) { Debug.printDbg(IDalvikTyper.DEBUG, "constraint: "+ assign); int op = (int)instruction.getOpcode().value; DalvikTyper.v().setType(assign.getRightOpBox(), instanceField.getType(), true); } }
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); }
protected Stmt switchStatement(DexBody body, Instruction targetData, Local key) { SparseSwitchPayload i = (SparseSwitchPayload) targetData; List<? extends SwitchElement> seList = i.getSwitchElements(); // the default target always follows the switch statement int defaultTargetAddress = codeAddress + instruction.getCodeUnits(); Unit defaultTarget = body.instructionAtAddress(defaultTargetAddress).getUnit(); List<IntConstant> lookupValues = new ArrayList<IntConstant>(); List<Unit> targets = new ArrayList<Unit>(); for(SwitchElement se: seList) { lookupValues.add(IntConstant.v(se.getKey())); int offset = se.getOffset(); targets.add(body.instructionAtAddress(codeAddress + offset).getUnit()); } switchStmt = Jimple.v().newLookupSwitchStmt(key, lookupValues, targets, defaultTarget); setUnit(switchStmt); if (IDalvikTyper.ENABLE_DVKTYPER) { Debug.printDbg(IDalvikTyper.DEBUG, "constraint: "+ switchStmt); DalvikTyper.v().setType(switchStmt.getKeyBox(), IntType.v(), true); } return switchStmt; }
public void outAStaticInvokeExpr(AStaticInvokeExpr node) { List args; if(node.getArgList() != null) args = (List) mProductions.removeLast(); else args = new ArrayList(); SootMethodRef method = (SootMethodRef) mProductions.removeLast(); method = Scene.v().makeMethodRef(method.declaringClass(), method.name(), method.parameterTypes(), method.returnType(), true); mProductions.addLast(Jimple.v().newStaticInvokeExpr(method, args)); }
public void outACaseStmt(ACaseStmt node) { String labelName = (String) mProductions.removeLast(); UnitBox box = Jimple.v().newStmtBox(null); addBoxToPatch(labelName, box); Value labelValue = null; if(node.getCaseLabel() instanceof AConstantCaseLabel) labelValue = (Value) mProductions.removeLast(); // if labelValue == null, this is the default label. if(labelValue == null) mProductions.addLast(box); else { Object[] valueTargetPair = new Object[2]; valueTargetPair[0] = labelValue; valueTargetPair[1] = box; mProductions.addLast(valueTargetPair); } }
/** * Executes the "jimplify" operation for a virtual invocation */ protected void jimplifyVirtual(DexBody body) { // In some applications, InterfaceInvokes are disguised as VirtualInvokes. // We fix this silently SootMethodRef ref = getSootMethodRef(); if (ref.declaringClass().isInterface()) { // Force re-resolving. Otherwise, if this created a phantom class, // it would not be marked as an interface. methodRef = null; jimplifyInterface(body); return; } // This is actually a VirtualInvoke List<Local> parameters = buildParameters(body, false); invocation = Jimple.v().newVirtualInvokeExpr(parameters.get(0), ref, parameters.subList(1, parameters.size())); body.setDanglingInstruction(this); }
public JDynamicInvokeExpr(SootMethodRef bootstrapMethodRef, List<? extends Value> bootstrapArgs, SootMethodRef methodRef, int tag, List<? extends Value> methodArgs) { super(methodRef, new ValueBox[methodArgs.size()]); if(!methodRef.getSignature().startsWith("<"+SootClass.INVOKEDYNAMIC_DUMMY_CLASS_NAME+": ")) throw new IllegalArgumentException("Receiver type of JDynamicInvokeExpr must be "+SootClass.INVOKEDYNAMIC_DUMMY_CLASS_NAME+"!"); if(!bootstrapMethodRef.returnType().equals(RefType.v("java.lang.invoke.CallSite"))) { throw new IllegalArgumentException("Return type of bootstrap method must be java.lang.invoke.CallSite!"); } this.bsmRef = bootstrapMethodRef; this.bsmArgBoxes = new ValueBox[bootstrapArgs.size()]; this.tag = tag; for(int i = 0; i < bootstrapArgs.size(); i++) { this.bsmArgBoxes[i] = Jimple.v().newImmediateBox(bootstrapArgs.get(i)); } for(int i = 0; i < methodArgs.size(); i++) { this.argBoxes[i] = Jimple.v().newImmediateBox( methodArgs.get(i)); } }
public void literal( String s ) { handleIndent(); if( eatSpace && s.equals(" ") ) { eatSpace = false; return; } eatSpace = false; if( false || s.equals( Jimple.STATICINVOKE ) || s.equals( Jimple.VIRTUALINVOKE ) || s.equals( Jimple.INTERFACEINVOKE ) ) { eatSpace = true; return; } output.append(s); }
@Test public void testJExitMonitorStmt() { Stmt s = Jimple.v().newExitMonitorStmt(StringConstant.v("test")); Set expectedRep = new ExceptionHashSet(utility.VM_ERRORS); expectedRep.add(utility.ILLEGAL_MONITOR_STATE_EXCEPTION); expectedRep.add(utility.NULL_POINTER_EXCEPTION); assertTrue(ExceptionTestUtility.sameMembers(expectedRep, Collections.EMPTY_SET, unitAnalysis.mightThrow(s))); Set expectedCatch = new ExceptionHashSet(utility.VM_ERRORS_PLUS_SUPERTYPES); expectedCatch.add(utility.ILLEGAL_MONITOR_STATE_EXCEPTION); expectedCatch.add(utility.NULL_POINTER_EXCEPTION); expectedCatch.add(utility.RUNTIME_EXCEPTION); expectedCatch.add(utility.EXCEPTION); assertEquals(expectedCatch, utility.catchableSubset(unitAnalysis.mightThrow(s))); }
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; } }
public void jimplify (DexBody body) { TwoRegisterInstruction i = (TwoRegisterInstruction) instruction; Debug.printDbg("moveInstruction: ", i); int dest = i.getRegisterA(); int source = i.getRegisterB(); assign = Jimple.v().newAssignStmt(body.getRegisterLocal(dest), body.getRegisterLocal(source)); setUnit(assign); addTags(assign); body.add(assign); if (IDalvikTyper.ENABLE_DVKTYPER) { Debug.printDbg(IDalvikTyper.DEBUG, "constraint: "+ assign); int op = (int)instruction.getOpcode().value; DalvikTyper.v().addConstraint(assign.getLeftOpBox(), assign.getRightOpBox()); } }
public void jimplify (DexBody body) { TwoRegisterInstruction i = (TwoRegisterInstruction)instruction; int dest = i.getRegisterA(); int source = i.getRegisterB(); Type targetType = getTargetType(); CastExpr cast = Jimple.v().newCastExpr(body.getRegisterLocal(source), targetType); assign = Jimple.v().newAssignStmt(body.getRegisterLocal(dest), cast); assign.addTag (getTag()); setUnit(assign); addTags(assign); body.add(assign); if (IDalvikTyper.ENABLE_DVKTYPER) { Debug.printDbg(IDalvikTyper.DEBUG, "constraint cast: "+ assign +" castexpr type: "+ cast.getType()+" cast type: "+ cast.getCastType()); int op = (int)instruction.getOpcode().value; DalvikTyper.v().setType(assign.getLeftOpBox(), cast.getType(), false); //DalvikTyper.v().captureAssign((JAssignStmt)assign, op); } }
public static Unit makeJimpleStaticCallForPathExecution(String methodName, Object... args) { SootClass sootClass = Scene.v().getSootClass(UtilInstrumenter.JAVA_CLASS_FOR_PATH_EXECUTION); Unit generated = null; ArrayList<Type> argTypes = new ArrayList<Type>(); ArrayList<Value> argList = new ArrayList<Value>(); if (args != null) { if (args.length % 2 != 0) { throw new RuntimeException( "Mismatched argument types:values in static call to " + methodName); } else { for (int i = 0; i < args.length; i++) if (i % 2 == 0) // First type, then argument argTypes.add((Type) args[i]); else argList.add((Value) args[i]); } } SootMethod createAndAdd = sootClass.getMethod(methodName, argTypes); StaticInvokeExpr sie = Jimple.v().newStaticInvokeExpr( createAndAdd.makeRef(), argList); generated = Jimple.v().newInvokeStmt(sie); return generated; }
private void prepareHandlerPostDelayed(Body body, Stmt invokeStmt, SootMethodRef reportRef) { InvokeExpr expr = invokeStmt.getInvokeExpr(); Value oldValue = expr.getArg(1); Value newValue = LongConstant.v(2000L); expr.setArg(1, newValue); // Report the change InvokeStmt reportStmt = Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr( reportRef, oldValue, newValue)); reportStmt.addTag(new InstrumentedCodeTag()); body.getUnits().insertAfter(reportStmt, invokeStmt); }
@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)); } } } }
@Override protected void internalTransform(Body b, String phaseName, Map<String, String> options) { // Do not instrument methods in framework classes if (!canInstrumentMethod(b.getMethod())) return; // Make a reference to the tracker method SootMethodRef ref = Scene.v().makeMethodRef( Scene.v().getSootClass(UtilInstrumenter.JAVA_CLASS_FOR_CODE_POSITIONS), "setLastExecutedStatement", Collections.<Type>singletonList(IntType.v()), VoidType.v(), true); final String methodSig = b.getMethod().getSignature(); // Iterate over all the units and add a unit that sets the current // execution pointer int curLineNum = 0; for (Iterator<Unit> unitIt = b.getUnits().snapshotIterator(); unitIt.hasNext(); ) { Unit curUnit = unitIt.next(); // If we're still inside the IdentityStmt block, there's nothing to // instrument if (curUnit instanceof IdentityStmt || // If this unit was instrumented by another transformer, there's nothing to instrument curUnit.hasTag(InstrumentedCodeTag.name)) continue; // Get the current code positions CodePosition codePos = codePositionManager.getCodePositionForUnit(curUnit, methodSig, curLineNum++, ((Stmt) curUnit).getJavaSourceStartLineNumber()); Stmt setCodePosStmt = Jimple.v().newInvokeStmt( Jimple.v().newStaticInvokeExpr(ref, IntConstant.v(codePos.getID()))); setCodePosStmt.addTag(new InstrumentedCodeTag()); b.getUnits().insertAfter(setCodePosStmt, curUnit); } }
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); }
@Override protected void internalTransform(Body b, String phaseName, Map<String, String> options) { // Do not instrument methods in framework classes if (!canInstrumentMethod(b.getMethod())) return; // Create method references final SootMethodRef targetReachedRef = Scene.v().makeMethodRef( Scene.v().getSootClass(UtilInstrumenter.JAVA_CLASS_FOR_CODE_POSITIONS), "reportTargetReachedSynchronous", Collections.<Type>emptyList(), VoidType.v(), true); // Iterate over the method and find calls to the target methods for (Iterator<Unit> unitIt = b.getUnits().snapshotIterator(); unitIt.hasNext(); ) { Stmt stmt = (Stmt) unitIt.next(); if(targetSignatures.contains(stmt)){ // Notify the server that the target was reached Stmt reachedStmt = Jimple.v().newInvokeStmt( Jimple.v().newStaticInvokeExpr(targetReachedRef)); reachedStmt.addTag(new InstrumentedCodeTag()); b.getUnits().insertBefore(reachedStmt, stmt); } } }
@Override protected void internalTransform(String phaseName, Map<String, String> options) { // Make a reference to the registration method SootMethodRef ref = Scene.v().makeMethodRef( Scene.v().getSootClass(UtilInstrumenter.JAVA_CLASS_FOR_CRASH_REPORTING), "registerExceptionHandler", Collections.<Type>emptyList(), VoidType.v(), true); for (String sig : methodsToInstrument) { try{ SootMethod sm = Scene.v().grabMethod(sig); if(sm == null) continue; for (Iterator<Unit> unitIt = sm.getActiveBody().getUnits() .snapshotIterator(); unitIt.hasNext(); ) { Unit curUnit = unitIt.next(); // If we're still inside the IdentityStmt block, there's nothing to // instrument if (curUnit instanceof IdentityStmt) continue; // Put the registration in Stmt stmt = Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(ref)); stmt.addTag(new InstrumentedCodeTag()); sm.getActiveBody().getUnits().insertAfter(stmt, curUnit); break; } }catch(Exception ex) { ex.printStackTrace(); } } }
private Stmt createFakeStmt (SootMethod sm) { Stmt s = null; SootClass sc = sm.getDeclaringClass(); if (sm.isStatic()) { s = Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(sm.makeRef())); } else { if (sc.isInterface()) { s = Jimple.v().newInvokeStmt(Jimple.v().newInterfaceInvokeExpr(Jimple.v().newLocal("a", VoidType.v()), sm.makeRef())); } else { s = Jimple.v().newInvokeStmt(Jimple.v().newVirtualInvokeExpr(Jimple.v().newLocal("a", VoidType.v()), sm.makeRef())); } } return s; }
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 Body generateBody(SootMethod initMethod) { String mName = initMethod.getName(); Body newBody = Jimple.v().newBody(); SootMethod tmpSM = new SootMethod("toto", new ArrayList<Type>(), VoidType.v()); if (mName.equals("<init>")) { // first case: create new object newBody = createNewInstance(initMethod); // the following statement is temporary otherwise an exception // will be raised during the unit graph construction newBody.setMethod(tmpSM); System.out.println("add body 1:\n" + newBody); updateNewBody(newBody); System.out.println("add body 2:\n" + newBody); } else { // case 1: if (initMethod.getDeclaringClass().toString().equals("android.app.ContextImpl") // && mName.startsWith("get")) // case 2: static method to create manager // Body b = initMethod.retrieveActiveBody(); newBody.importBodyContentsFrom(b); // the following statement is temporary otherwise an exception // will be raised during the unit graph construction newBody.setMethod(tmpSM); updateNewBody (newBody); } return newBody; }
private void assignServiceToField(Body b, SootClass initClass, SootClass sc) { Value l = getLocalWithName(b, makeLocalName(sc.getType()), sc.getType()); SootField f = initClass.getFieldByName(makeFieldName(sc.getType())); StaticFieldRef sfr = Jimple.v().newStaticFieldRef(f.makeRef()); Unit u = Jimple.v().newAssignStmt(sfr, l); b.getUnits().add(u); }