public JDynamicInvokeExpr( SootMethodRef bootstrapMethodRef, List<Value> bootstrapArgs, SootMethodRef methodRef, List<Value> methodArgs) { 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.methodRef = methodRef; this.bsmArgBoxes = new ValueBox[bootstrapArgs.size()]; this.argBoxes = new ValueBox[methodArgs.size()]; for (int i = 0; i < bootstrapArgs.size(); i++) { // RoboVM note: Changed to handle InvokeExpr values in bootstrap args Value v = bootstrapArgs.get(i); if (v instanceof InvokeExpr) { this.bsmArgBoxes[i] = Jimple.v().newInvokeExprBox(v); } else { this.bsmArgBoxes[i] = Jimple.v().newImmediateBox(v); } } for (int i = 0; i < methodArgs.size(); i++) { this.argBoxes[i] = Jimple.v().newImmediateBox((Value) methodArgs.get(i)); } }
public void outANonstaticInvokeExpr(ANonstaticInvokeExpr node) { List args; if (node.getArgList() != null) args = (List) mProductions.removeLast(); else args = new ArrayList(); SootMethodRef method = (SootMethodRef) mProductions.removeLast(); String local = (String) mProductions.removeLast(); Local l = (Local) mLocals.get(local); if (l == null) throw new RuntimeException("did not find local: " + local); Node invokeType = (Node) node.getNonstaticInvoke(); Expr invokeExpr; if (invokeType instanceof ASpecialNonstaticInvoke) { invokeExpr = Jimple.v().newSpecialInvokeExpr(l, method, args); } else if (invokeType instanceof AVirtualNonstaticInvoke) { invokeExpr = Jimple.v().newVirtualInvokeExpr(l, method, args); } else { if (debug) if (!(invokeType instanceof AInterfaceNonstaticInvoke)) throw new RuntimeException("expected interface invoke."); invokeExpr = Jimple.v().newInterfaceInvokeExpr(l, method, args); } mProductions.addLast(invokeExpr); }
public void outAIdentityNoTypeStatement(AIdentityNoTypeStatement node) { mProductions.removeLast(); // get rid of @caughtexception string presently on top of the stack Value local = (Value) mLocals.get(mProductions.removeLast()); // the local ref from it's identifier Unit u = Jimple.v().newIdentityStmt(local, Jimple.v().newCaughtExceptionRef()); mProductions.addLast(u); }
public static SootMethod mockSootMethod( String clsName, String methodSubSignature, boolean isStatic) { SootClass sc = mockSootClass(clsName); SootMethod sm = null; try { sm = sc.getMethod(methodSubSignature); } catch (Exception ex) { sm = null; } if (null == sm) { int m = Modifier.PUBLIC; if (isStatic) { m = m | Modifier.STATIC; } List<Type> paramTypes = new ArrayList<Type>(); paramTypes.add(ArrayType.v(RefType.v("java.lang.Object"), 1)); String[] strs = methodSubSignature.split(" "); String methodName = strs[1].trim().substring(0, strs[1].trim().indexOf("(")); if (null == methodName || methodName.isEmpty()) { return null; } sm = new SootMethod(methodName, paramTypes, RefType.v("java.lang.Object"), m); sc.addMethod(sm); // Add body of sm JimpleBody b = Jimple.v().newBody(sm); sm.setActiveBody(b); // LocalGenerator lg = new LocalGenerator(b); { b.insertIdentityStmts(); // Local rtLoc = lg.generateLocal(RefType.v("java.lang.Object")); // Local param0 = lg.generateLocal(ArrayType.v(RefType.v("java.lang.Object"), 1)); // Unit param0U = Jimple.v().newIdentityStmt(rtLoc, // Jimple.v().newParameterRef(ArrayType.v(RefType.v("java.lang.Object"), 1), 0)); // Unit rtLocAssignU = Jimple.v().newAssignStmt(rtLoc, param0); Unit returnU = Jimple.v().newReturnStmt(b.getParameterLocal(0)); // b.getUnits().add(param0U); b.getUnits().add(returnU); } System.out.println("validation:" + b); b.validate(); } return sm; }
public Object clone() { List argList = new ArrayList(getArgCount()); for (int i = 0; i < getArgCount(); i++) { argList.add(i, Jimple.cloneIfNecessary(getArg(i))); } return new JInterfaceInvokeExpr(Jimple.cloneIfNecessary(getBase()), methodRef, argList); }
public void outAGotoStatement(AGotoStatement node) { String targetLabel = (String) mProductions.removeLast(); UnitBox box = Jimple.v().newStmtBox(null); Unit branch = Jimple.v().newGotoStmt(box); addBoxToPatch(targetLabel, box); mProductions.addLast(branch); }
public void outAIfStatement(AIfStatement node) { String targetLabel = (String) mProductions.removeLast(); Value condition = (Value) mProductions.removeLast(); UnitBox box = Jimple.v().newStmtBox(null); Unit u = Jimple.v().newIfStmt(condition, box); addBoxToPatch(targetLabel, box); mProductions.addLast(u); }
public void outAReturnStatement(AReturnStatement node) { Value v; Stmt s = null; if (node.getImmediate() != null) { v = (Value) mProductions.removeLast(); s = Jimple.v().newReturnStmt(v); } else { s = Jimple.v().newReturnVoidStmt(); } mProductions.addLast(s); }
public void jimplify(DexBody body) { TwoRegisterInstruction i = (TwoRegisterInstruction) instruction; int dest = i.getRegisterA(); int object = i.getRegisterB(); FieldIdItem f = (FieldIdItem) ((InstructionWithReference) instruction).getReferencedItem(); InstanceFieldRef r = Jimple.v().newInstanceFieldRef(body.getRegisterLocal(object), getSootFieldRef(f)); assign = Jimple.v().newAssignStmt(body.getRegisterLocal(dest), r); setUnit(assign); tagWithLineNumber(assign); body.add(assign); }
public void jimplify(DexBody body) { if (!(instruction instanceof Instruction31t)) throw new IllegalArgumentException( "Expected Instruction31t but got: " + instruction.getClass()); Instruction31t fillArrayInstr = (Instruction31t) instruction; int destRegister = fillArrayInstr.getRegisterA(); int offset = fillArrayInstr.getCodeOffset(); int targetAddress = codeAddress + offset; Instruction referenceTable = body.instructionAtAddress(targetAddress).instruction; if (!(referenceTable instanceof ArrayPayload)) { throw new RuntimeException( "Address " + targetAddress + "refers to an invalid PseudoInstruction."); } ArrayPayload arrayTable = (ArrayPayload) referenceTable; // NopStmt nopStmtBeginning = Jimple.v().newNopStmt(); // body.add(nopStmtBeginning); Local arrayReference = body.getRegisterLocal(destRegister); List<Number> elements = arrayTable.getArrayElements(); int numElements = elements.size(); Stmt firstAssign = null; for (int i = 0; i < numElements; i++) { ArrayRef arrayRef = Jimple.v().newArrayRef(arrayReference, IntConstant.v(i)); NumericConstant element = getArrayElement(elements.get(i), body, destRegister); if (element == null) // array was not defined -> element type can not be found (obfuscated bytecode?) break; AssignStmt assign = Jimple.v().newAssignStmt(arrayRef, element); addTags(assign); body.add(assign); if (i == 0) { firstAssign = assign; } } if (firstAssign == null) { // if numElements == 0. Is it possible? firstAssign = Jimple.v().newNopStmt(); body.add(firstAssign); } // NopStmt nopStmtEnd = Jimple.v().newNopStmt(); // body.add(nopStmtEnd); // defineBlock(nopStmtBeginning, nopStmtEnd); setUnit(firstAssign); }
public void outAInvokeStatement(AInvokeStatement node) { Value op = (Value) mProductions.removeLast(); Unit u = Jimple.v().newInvokeStmt(op); mProductions.addLast(u); }
public void outALookupswitchStatement(ALookupswitchStatement node) { List lookupValues = new ArrayList(); List targets = new ArrayList(); UnitBox defaultTarget = null; if (node.getCaseStmt() != null) { int size = node.getCaseStmt().size(); for (int i = 0; i < size; i++) { Object valueTargetPair = mProductions.removeLast(); if (valueTargetPair instanceof UnitBox) { if (defaultTarget != null) throw new RuntimeException("error: can't ;have more than 1 default stmt"); defaultTarget = (UnitBox) valueTargetPair; } else { Object[] pair = (Object[]) valueTargetPair; lookupValues.add(0, pair[0]); targets.add(0, pair[1]); } } } else { throw new RuntimeException("error: switch stmt has no case stmts"); } Value key = (Value) mProductions.removeLast(); Unit switchStmt = Jimple.v().newLookupSwitchStmt(key, lookupValues, targets, defaultTarget); mProductions.addLast(switchStmt); }
public void outAAssignStatement(AAssignStatement node) { Value rvalue = (Value) mProductions.removeLast(); Value variable = (Value) mProductions.removeLast(); Unit u = Jimple.v().newAssignStmt(variable, rvalue); mProductions.addLast(u); }
AbstractStaticInvokeExpr(SootMethodRef methodRef, List args) { super.methodRef = methodRef; super.argBoxes = new ArrayList(); for (int i = 0; i < args.size(); i++) this.argBoxes.add(Jimple.v().newImmediateBox((Value) args.get(i))); }
public void jimplify(DexBody body) { Instruction11x throwInstruction = (Instruction11x) instruction; throwStmt = Jimple.v().newThrowStmt(body.getRegisterLocal(throwInstruction.getRegisterA())); setUnit(throwStmt); tagWithLineNumber(throwStmt); body.add(throwStmt); }
private List<Unit> instrumentIntentAddings( BiDiInterproceduralCFG<Unit, SootMethod> cfg, Unit unit, InvokeExpr sinkExpr, Set<ResultSourceInfo> sourceInfo) { if (isMethodInterComponentSink(sinkExpr.getMethod())) { SootMethod method = cfg.getMethodOf(unit); Body body = null; if (method.hasActiveBody()) body = method.retrieveActiveBody(); else throw new RuntimeException("No body found!"); Set<String> sourceCategories = getDataIdList(sourceInfo); final String hashSetType = "java.util.HashSet"; List<Unit> generated = new ArrayList<Unit>(); // HashSet initialization Local hashSetLocal = generateFreshLocal(body, RefType.v(hashSetType)); NewExpr newExpr = Jimple.v().newNewExpr(RefType.v(hashSetType)); AssignStmt assignStmt = Jimple.v().newAssignStmt(hashSetLocal, newExpr); generated.add(assignStmt); // constructor call SpecialInvokeExpr constructorCall = Jimple.v() .newSpecialInvokeExpr( hashSetLocal, Scene.v().getMethod("<java.util.HashSet: void <init>()>").makeRef()); InvokeStmt constructorCallStmt = Jimple.v().newInvokeStmt(constructorCall); generated.add(constructorCallStmt); // add categories to HashSet for (String cat : sourceCategories) { InterfaceInvokeExpr addCall = Jimple.v() .newInterfaceInvokeExpr( hashSetLocal, Scene.v().getMethod("<java.util.Set: boolean add(java.lang.Object)>").makeRef(), StringConstant.v(cat)); InvokeStmt addCallStmt = Jimple.v().newInvokeStmt(addCall); generated.add(addCallStmt); } // get Intent Value intent = sinkExpr.getArg(0); List<Object> args = new ArrayList<Object>(); args.add(RefType.v("android.content.Intent")); args.add(intent); args.add(RefType.v(hashSetType)); args.add(hashSetLocal); StaticInvokeExpr sie = Instrumentation.createJimpleStaticInvokeExpr( Settings.INSTRUMENTATION_HELPER_JAVA, "addTaintInformationToIntent", args); InvokeStmt invStmt = Jimple.v().newInvokeStmt(sie); generated.add(invStmt); return generated; } return Collections.emptyList(); }
/** * Generate a default assignment with 'local' as left-hand-side value. * * @param local * @return */ private Unit createCorrectDummyAssignment(Local local) { Unit dummyAssignemnt = null; if (local.getType() instanceof PrimType) { if (local.getType() instanceof IntType) { StaticInvokeExpr sie = Instrumentation.createJimpleStaticInvokeExpr(Settings.SANITIZER, "dummyInteger", null); dummyAssignemnt = Jimple.v().newAssignStmt(local, sie); } else if (local.getType() instanceof BooleanType) { StaticInvokeExpr sie = Instrumentation.createJimpleStaticInvokeExpr(Settings.SANITIZER, "dummyBoolean", null); dummyAssignemnt = Jimple.v().newAssignStmt(local, sie); } else if (local.getType() instanceof ByteType) { StaticInvokeExpr sie = Instrumentation.createJimpleStaticInvokeExpr(Settings.SANITIZER, "dummyByte", null); dummyAssignemnt = Jimple.v().newAssignStmt(local, sie); } else if (local.getType() instanceof CharType) { StaticInvokeExpr sie = Instrumentation.createJimpleStaticInvokeExpr( Settings.SANITIZER, "dummyCharacter", null); dummyAssignemnt = Jimple.v().newAssignStmt(local, sie); } else if (local.getType() instanceof DoubleType) { StaticInvokeExpr sie = Instrumentation.createJimpleStaticInvokeExpr(Settings.SANITIZER, "dummyDouble", null); dummyAssignemnt = Jimple.v().newAssignStmt(local, sie); } else if (local.getType() instanceof FloatType) { StaticInvokeExpr sie = Instrumentation.createJimpleStaticInvokeExpr(Settings.SANITIZER, "dummyFloat", null); dummyAssignemnt = Jimple.v().newAssignStmt(local, sie); } else if (local.getType() instanceof LongType) { StaticInvokeExpr sie = Instrumentation.createJimpleStaticInvokeExpr(Settings.SANITIZER, "dummyLong", null); dummyAssignemnt = Jimple.v().newAssignStmt(local, sie); } else if (local.getType() instanceof ShortType) { StaticInvokeExpr sie = Instrumentation.createJimpleStaticInvokeExpr(Settings.SANITIZER, "dummyShort", null); dummyAssignemnt = Jimple.v().newAssignStmt(local, sie); } else throw new RuntimeException("Oops, the primitive type is not correct"); } else { if (local.getType().equals(RefType.v("java.lang.String"))) dummyAssignemnt = Jimple.v().newAssignStmt(local, StringConstant.v("")); else dummyAssignemnt = Jimple.v().newAssignStmt(local, NullConstant.v()); } return dummyAssignemnt; }
public void outAArrayRef(AArrayRef node) { Value immediate = (Value) mProductions.removeLast(); String identifier = (String) mProductions.removeLast(); Local l = (Local) mLocals.get(identifier); if (l == null) throw new RuntimeException("did not find local: " + identifier); mProductions.addLast(Jimple.v().newArrayRef(l, immediate)); }
public void outALocalFieldRef(ALocalFieldRef node) { SootFieldRef field = (SootFieldRef) mProductions.removeLast(); String local = (String) mProductions.removeLast(); Local l = (Local) mLocals.get(local); if (l == null) throw new RuntimeException("did not find local: " + local); mProductions.addLast(Jimple.v().newInstanceFieldRef(l, field)); }
public void outACatchClause(ACatchClause node) { String exceptionName; UnitBox withUnit, fromUnit, toUnit; withUnit = Jimple.v().newStmtBox(null); addBoxToPatch((String) mProductions.removeLast(), withUnit); toUnit = Jimple.v().newStmtBox(null); addBoxToPatch((String) mProductions.removeLast(), toUnit); fromUnit = Jimple.v().newStmtBox(null); addBoxToPatch((String) mProductions.removeLast(), fromUnit); exceptionName = (String) mProductions.removeLast(); Trap trap = Jimple.v().newTrap(mResolver.makeClassRef(exceptionName), fromUnit, toUnit, withUnit); mProductions.addLast(trap); }
public void jimplify(DexBody body) { if (!(instruction instanceof Instruction21c)) throw new IllegalArgumentException( "Expected Instruction21c but got: " + instruction.getClass()); Instruction21c checkCastInstr = (Instruction21c) instruction; Local castValue = body.getRegisterLocal(checkCastInstr.getRegisterA()); Type checkCastType = DexType.toSoot((TypeIdItem) checkCastInstr.getReferencedItem()); CastExpr castExpr = Jimple.v().newCastExpr(castValue, checkCastType); // generate "x = (Type) x" // splitter will take care of the rest assign = Jimple.v().newAssignStmt(castValue, castExpr); setUnit(assign); tagWithLineNumber(assign); body.add(assign); }
public void outAIdentityStatement(AIdentityStatement node) { Type identityRefType = (Type) mProductions.removeLast(); String atClause = (String) mProductions.removeLast(); Value local = (Value) mLocals.get(mProductions.removeLast()); // the local ref from it's identifier Value ref = null; if (atClause.startsWith("@this")) { ref = Jimple.v().newThisRef((RefType) identityRefType); } else if (atClause.startsWith("@parameter")) { int index = Integer.parseInt(atClause.substring(10, atClause.length() - 1)); ref = Jimple.v().newParameterRef(identityRefType, index); } else throw new RuntimeException( "shouldn't @caughtexception be handled by outAIdentityNoTypeStatement: got" + atClause); Unit u = Jimple.v().newIdentityStmt(local, ref); mProductions.addLast(u); }
/** * @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); }
public void outADeclaration(ADeclaration node) { List localNameList = (List) mProductions.removeLast(); Type type = (Type) mProductions.removeLast(); Iterator it = localNameList.iterator(); List localList = new ArrayList(); while (it.hasNext()) { Local l = Jimple.v().newLocal((String) it.next(), type); mLocals.put(l.getName(), l); localList.add(l); } mProductions.addLast(localList); }
/** * Create a method conveniently. The method is added to the class "TestClass". Parameters can be * given as an (positional) array of local variables (the "identity statements", required by Soot * to map parameters to local variables, are inserted automatically) */ public SootMethod makeMethod( int modifier, String name, List<Local> params, soot.Type retType, List<Unit> bodyStmts) { SootMethod m = new SootMethod( name, params.stream().map(Local::getType).collect(toList()), retType, modifier); this.testClass.addMethod(m); Body body = Jimple.v().newBody(m); m.setActiveBody(body); // set the statements for the body.. first the identity statements, then the bodyStmts if (!m.isStatic()) { body.getLocals().add(localThis); body.getUnits() .add(Jimple.v().newIdentityStmt(localThis, Jimple.v().newThisRef(testClass.getType()))); } IntStream.range(0, params.size()) .forEach( pos -> { Local l = params.get(pos); ParameterRef pr = Jimple.v().newParameterRef(l.getType(), pos); body.getUnits().add(Jimple.v().newIdentityStmt(l, pr)); }); body.getUnits().addAll(bodyStmts); // set the locals for the body Set<Local> locals = Stream.concat( params.stream(), body.getUseAndDefBoxes() .stream() .filter(b -> b.getValue() instanceof Local) .map(b -> (Local) b.getValue())) .collect(toSet()); locals.removeAll(body.getLocals()); body.getLocals().addAll(locals); return m; }
public class G { public static final Jimple jimple = Jimple.v(); static final SootClass innerClass; static final String innerClassStr = "edu.gatech.util.innerClass"; static final SootMethodRef testMethodRef; static { innerClass = Scene.v().getSootClass(innerClassStr); testMethodRef = innerClass.getMethod("void test()").makeRef(); } }
public void toString(UnitPrinter up) { up.literal(Jimple.v().STATICINVOKE); up.literal(" "); up.methodRef(methodRef); up.literal("("); for (int i = 0; i < argBoxes.size(); i++) { if (i != 0) up.literal(", "); getArgBox(i).toString(up); } up.literal(")"); }
public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append(Jimple.v().STATICINVOKE + " " + methodRef.getSignature() + "("); for (int i = 0; i < argBoxes.size(); i++) { if (i != 0) buffer.append(", "); buffer.append(getArg(i).toString()); } buffer.append(")"); return buffer.toString(); }
public static SootMethod createSootMethod( SootClass sootClass, String name, List<Type> paramTypes, Type returnType, boolean isStatic) { int modifier = Modifier.PUBLIC; if (isStatic) { modifier = modifier | Modifier.STATIC; } SootMethod sootMethod = new SootMethod(name, paramTypes, returnType, modifier); sootClass.addMethod(sootMethod); Body body = Jimple.v().newBody(sootMethod); sootMethod.setActiveBody(body); return sootMethod; }
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)); }