/** * Gets the baf body for the given SootMethod. This method will first check * whether the method already has a baf body. If not, it will query the local * cache. If this fails as well, it will construct a new baf body. * @param method The method for which to obtain a baf body * @return The baf body for the given method */ protected BafBody getBafBody(SootMethod method) { final Body activeBody = method.getActiveBody(); if (activeBody instanceof BafBody) return (BafBody) activeBody; BafBody body = bafBodyCache.get(method); if (body != null) return body; if (activeBody instanceof JimpleBody) { body = PackManager.v().convertJimpleBodyToBaf(method); } else { throw new RuntimeException( "ASM-backend can only translate Baf- and JimpleBodies!"); } bafBodyCache.put(method, body); return body; }
private TypeResolver(JimpleBody stmtBody, Scene scene) { this.stmtBody = stmtBody; hierarchy = ClassHierarchy.classHierarchy(scene); OBJECT = hierarchy.OBJECT; NULL = hierarchy.NULL; typeVariable(OBJECT); typeVariable(NULL); // hack for J2ME library, reported by Stephen Cheng if (!Options.v().j2me()) { typeVariable(hierarchy.CLONEABLE); typeVariable(hierarchy.SERIALIZABLE); } }
private boolean typingFailed(JimpleBody b) { // Check to see if any locals are untyped { Iterator<Local> localIt = b.getLocals().iterator(); while (localIt.hasNext()) { Local l = localIt.next(); if (l.getType().equals(UnknownType.v()) || l.getType().equals(ErroneousType.v())) { return true; } } } return false; }
private TypeResolverBV(JimpleBody stmtBody, Scene scene) { this.stmtBody = stmtBody; hierarchy = ClassHierarchy.classHierarchy(scene); OBJECT = hierarchy.OBJECT; NULL = hierarchy.NULL; typeVariable(OBJECT); typeVariable(NULL); // hack for J2ME library, reported by Stephen Cheng if (!Options.v().j2me()) { typeVariable(hierarchy.CLONEABLE); typeVariable(hierarchy.SERIALIZABLE); } }
/** * Create the default constructor for the Averroes library class. */ private void createAverroesAbstractLibraryInit() { SootMethod init = Hierarchy.getNewDefaultConstructor(); JimpleBody body = Jimple.v().newBody(init); init.setActiveBody(body); averroesAbstractLibraryClass.addMethod(init); // Call superclass constructor body.insertIdentityStmts(); body.getUnits().add( Jimple.v().newInvokeStmt( Jimple.v().newSpecialInvokeExpr(body.getThisLocal(), Hierarchy.getDefaultConstructor(Hierarchy.v().getJavaLangObject()).makeRef(), Collections.<Value> emptyList()))); // Add return statement body.getUnits().addLast(Jimple.v().newReturnVoidStmt()); // Finally validate the Jimple body body.validate(); }
/** * Create the static initializer for the Averroes library class. */ private void createAverroesLibraryInit() { SootMethod init = Hierarchy.getNewDefaultConstructor(); JimpleBody body = Jimple.v().newBody(init); init.setActiveBody(body); averroesLibraryClass.addMethod(init); // Call superclass constructor body.insertIdentityStmts(); body.getUnits().add( Jimple.v().newInvokeStmt( Jimple.v().newSpecialInvokeExpr(body.getThisLocal(), Hierarchy.getDefaultConstructor(averroesAbstractLibraryClass).makeRef(), Collections.<Value> emptyList()))); // Add return statement body.getUnits().addLast(Jimple.v().newReturnVoidStmt()); // Finally validate the Jimple body body.validate(); }
private static SootMethod genericMethod(SootMethod m, boolean removeSync) { SootClass c = m.getDeclaringClass(); SootMethod s = new SootMethod(m.getName(), m.getParameterTypes(), m.getReturnType(), m.getModifiers() & ~Modifier.NATIVE); if (removeSync) s.setModifiers(s.getModifiers() & ~Modifier.SYNCHRONIZED); c.removeMethod(m); c.addMethod(s); if (s.isConcrete()) { JimpleBody body = Jimple.v().newBody(s); Chain<Unit> units = body.getUnits(); Chain<Local> locals = body.getLocals(); boolean isStatic = (s.getModifiers() & Modifier.STATIC) != 0; if (!isStatic) { Local thisLcl = Jimple.v().newLocal("this", c.getType()); locals.add(thisLcl); units.add(Jimple.v().newIdentityStmt(thisLcl, Jimple.v().newThisRef(c.getType()))); } int paramCnt = s.getParameterCount(); List<Type> paramTypeList = s.getParameterTypes(); for (int i = 0; i < paramCnt; i++) { Local lcl = Jimple.v().newLocal("l" + i, paramTypeList.get(i)); locals.add(lcl); units.add(Jimple.v().newIdentityStmt(lcl, Jimple.v().newParameterRef(paramTypeList.get(i), i))); } s.setActiveBody(body); } return s; }
/** * Stub for instance method "void start()" in class java.lang.Thread. */ private static SootMethod getThreadStartEquiv(SootMethod m) { SootMethod s = genericMethod(m, true); JimpleBody body =(JimpleBody) s.retrieveActiveBody(); SootClass c = s.getDeclaringClass(); String runSig = "void run()"; SootMethod runM = c.getMethod(runSig); Chain<Unit> units = body.getUnits(); Local thisLcl = body.getThisLocal(); units.add(Jimple.v().newInvokeStmt(Jimple.v().newVirtualInvokeExpr(thisLcl, runM.makeRef()))); units.add(Jimple.v().newReturnVoidStmt()); methodToStub.put(m, s); methodToStub.put(s, s); if (Config.verbose >= 2) System.out.println("Custom stub (getThreadStartEquiv) for method: " + s.getName() + ":" + s.getDeclaringClass()); return s; }
/** * Stub for instance method "java.lang.Object clone()" in class java.lang.Object. */ private static SootMethod getCloneEquiv(SootMethod m) { SootMethod s = genericMethod(m, false); JimpleBody body =(JimpleBody) s.retrieveActiveBody(); SootClass c = s.getDeclaringClass(); Chain<Unit> units = body.getUnits(); Chain<Local> locals = body.getLocals(); Local lcl1 = Jimple.v().newLocal("l", c.getType()); locals.add(lcl1); Local thisLocal = body.getThisLocal(); units.add(Jimple.v().newAssignStmt(lcl1,thisLocal)); units.add(Jimple.v().newReturnStmt(lcl1)); methodToStub.put(m, s); methodToStub.put(s, s); if (Config.verbose >= 2) System.out.println("Custom stub (getCloneEquiv) for method: " + s.getName() + ":" + s.getDeclaringClass()); return s; }
private static SootMethod getDoPrivileged(SootMethod m){ SootMethod s = genericMethod(m,false); JimpleBody body =(JimpleBody) s.retrieveActiveBody(); List<Type> paramTypes = m.getParameterTypes(); RefType param1 = (RefType)paramTypes.get(0); SootClass c = param1.getSootClass(); String runSig = "java.lang.Object run()"; SootMethod runM = c.getMethod(runSig); Chain<Unit> units = body.getUnits(); Chain<Local> locals = body.getLocals(); Local invokeBase = locals.getFirst(); Local t0 = Jimple.v().newLocal("t0", RefType.v("java.lang.Object")); locals.add(t0); units.add(Jimple.v().newAssignStmt(t0, Jimple.v().newInterfaceInvokeExpr(invokeBase, runM.makeRef()))); units.add(Jimple.v().newReturnStmt(t0)); methodToStub.put(m, s); methodToStub.put(s, s); if (Config.verbose >= 2) System.out.println("Custom stub (getDoPrivileged1) for method: " + s.getName() + ":" + s.getDeclaringClass()); return s; }
/** * Empty stub for unsupported native methods / excluded methods */ private static SootMethod emptyStub(SootMethod m) { SootMethod s = genericMethod(m, false); if (s.isConcrete()) { JimpleBody body =(JimpleBody) s.retrieveActiveBody(); SootClass c = s.getDeclaringClass(); Chain<Unit> units = body.getUnits(); if (s.getReturnType() instanceof VoidType) units.add(Jimple.v().newReturnVoidStmt()); else { Chain<Local> locals = body.getLocals(); Local lcl = Jimple.v().newLocal("retlcl", s.getReturnType()); locals.add(lcl); units.add(Jimple.v().newReturnStmt(lcl)); } } methodToStub.put(m, s); methodToStub.put(s, s); if (Config.verbose >= 2) System.out.println("Empty stub for method: " + s.getName() + ":" + s.getDeclaringClass()); return s; }
/** * 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(JimpleBody 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(19)), getValueForType(body, gen, tp.getElementType(), constructionStack, parentClasses)); body.getUnits().add(assign); return local; }
/** * Create default constructor of the wrapper class. * @return */ private SootMethod createInit() { SootMethod method = new SootMethod("<init>", new ArrayList<Type>(), VoidType.v(), Modifier.PUBLIC); JimpleBody body = Jimple.v().newBody(method); method.setActiveBody(body); Chain <Local> locals = body.getLocals(); PatchingChain<Unit> units = body.getUnits(); RefType thisType = RefType.v(WRAPPER_PATH); Local r0 = jimple.newLocal("r0", thisType); locals.add(r0); units.add(jimple.newIdentityStmt(r0, jimple.newThisRef(thisType))); SootMethod initObject = scene.getMethod("<java.lang.Object: void <init>()>"); units.add(jimple.newInvokeStmt (jimple.newSpecialInvokeExpr(r0, initObject.makeRef()))); units.add(jimple.newReturnVoidStmt()); return method; }
private static Map/*<Integer,Local>*/ getLocals(SootClass sc, String methodname, String typename) { Map res = new HashMap(); Iterator mi = sc.getMethods().iterator(); while (mi.hasNext()) { SootMethod sm = (SootMethod)mi.next(); System.err.println(sm.getName()); if (true && sm.getName().equals(methodname) && sm.isConcrete()) { JimpleBody jb = (JimpleBody)sm.retrieveActiveBody(); Iterator ui = jb.getUnits().iterator(); while (ui.hasNext()) { Stmt s = (Stmt)ui.next(); int line = getLineNumber(s); // find definitions Iterator bi = s.getDefBoxes().iterator(); while (bi.hasNext()) { Object o = bi.next(); if (o instanceof ValueBox) { Value v = ((ValueBox)o).getValue(); if (v.getType().toString().equals(typename) && v instanceof Local) res.put(new Integer(line),v); } } } } } return res; }
private void stashBodiesForClass(SootClass sc) { methodToParsedBodyMap = new HashMap<SootMethod, JimpleBody>(); Walker w = new BodyExtractorWalker(sc, SootResolver.v(), methodToParsedBodyMap); boolean oldPhantomValue = Scene.v().getPhantomRefs(); Scene.v().setPhantomRefs(true); mTree.apply(w); Scene.v().setPhantomRefs(oldPhantomValue); }
public TypeResolver(JimpleBody jb) { this.jb = jb; this.assignments = new ArrayList<DefinitionStmt>(); this.depends = new HashMap<Local, BitSet>(); for ( Local v : this.jb.getLocals() ) this.addLocal(v); this.initAssignments(); }
public CastInsertionUseVisitor(boolean countOnly, JimpleBody jb, Typing tg, IHierarchy h) { this.jb = jb; this.tg = tg; this.h = h; this.countOnly = countOnly; this.count = 0; }
public TypePromotionUseVisitor(JimpleBody jb, Typing tg) { this.jb = jb; this.tg = tg; this.fail = false; this.typingChanged = false; }
public void check(Stmt stmt, JimpleBody stmtBody) throws TypeException { try { this.stmtBody = stmtBody; stmt.apply(this); } catch (RuntimeTypeException e) { StringWriter st = new StringWriter(); PrintWriter pw = new PrintWriter(st); e.printStackTrace(pw); pw.close(); throw new TypeException(st.toString()); } }
private static int compareTypings(JimpleBody a, JimpleBody b) { int r = 0; Iterator<Local> ib = b.getLocals().iterator(); for (Local v : a.getLocals()) { Type ta = v.getType(), tb = ib.next().getType(); if (soot.jimple.toolkits.typing.fast.TypeResolver .typesEqual(ta, tb)) continue; /* * Sometimes there is no reason to choose between the char and byte / * short types. Enabling this check allows one algorithm to select * char and the other to select byte / short without returning * incomparable. */ else if (true && ((ta instanceof CharType && (tb instanceof ByteType || tb instanceof ShortType)) || (tb instanceof CharType && (ta instanceof ByteType || ta instanceof ShortType)))) continue; else if (soot.jimple.toolkits.typing.fast.AugHierarchy.ancestor_( ta, tb)) { if (r == -1) return 3; else r = 1; } else if (soot.jimple.toolkits.typing.fast.AugHierarchy.ancestor_( tb, ta)) { if (r == 1) return 3; else r = -1; } else return 3; } return r; }
/** Removes {@link NopStmt}s from the passed body (which must be a {@link JimpleBody}). Complexity is linear with respect to the statements. */ protected void internalTransform(Body b, String phaseName, Map<String, String> options) { JimpleBody body = (JimpleBody)b; if(Options.v().verbose()) G.v().out.println("[" + body.getMethod().getName() + "] Removing nops..."); Chain<Unit> units = body.getUnits(); // Just do one trivial pass. { Iterator<Unit> stmtIt = units.snapshotIterator(); while(stmtIt.hasNext()) { Unit u = stmtIt.next(); if (u instanceof NopStmt) { // Hack: do not remove nop, if is is used for a Trap which // is at the very end of the code. boolean keepNop = false; if (b.getUnits().getLast() == u) { for (Trap t : b.getTraps()) { if (t.getEndUnit() == u) { keepNop = true; } } } if (!keepNop) { units.remove(u); } } } } }
public BafBody convertJimpleBodyToBaf(SootMethod m) { JimpleBody body = (JimpleBody) m.getActiveBody().clone(); //Change // ConditionalBranchFolder.v().transform(body); // UnreachableCodeEliminator.v().transform(body); // DeadAssignmentEliminator.v().transform(body); // UnusedLocalEliminator.v().transform(body); BafBody bafBody = Baf.v().newBody(body); PackManager.v().getPack("bop").apply(bafBody); PackManager.v().getPack("tag").apply(bafBody); if( Options.v().validate() ) { bafBody.validate(); } return bafBody; }
protected void internalTransform(Body b, String phaseName, Map<String, String> options) { initialize(options); SootMethod meth = b.getMethod(); if ((methodsToPrint == null) || (meth.getDeclaringClass().getName() == methodsToPrint.get(meth.getName()))) { Body body = ir.getBody((JimpleBody) b); print_cfg(body); } }
private SootMethod createMockSink(String name) { name = String.format("mockSink%d_%s", mockMethodId++, name); List<Type> paras = new ArrayList<>(); paras.add(objectClass.getType()); SootMethod m = new SootMethod(name, paras, VoidType.v(), Modifier.PUBLIC | Modifier.STATIC); webViewBridgeClass.addMethod(m); JimpleBody mockSinkBody = Jimple.v().newBody(m); mockSinkBody.getUnits().addLast(Jimple.v().newReturnVoidStmt()); m.setActiveBody(mockSinkBody); this.setJavaMethodArgsAsSink(m); return m; }
private SootMethod createMockSource(String name) { name = String.format("mockSource%d_%s", mockMethodId++, name); List<Type> paras = new ArrayList<>(); SootMethod m = new SootMethod(name, paras, objectClass.getType(), Modifier.PUBLIC | Modifier.STATIC); webViewBridgeClass.addMethod(m); JimpleBody mockSourceBody = Jimple.v().newBody(m); mockSourceBody.getUnits().addLast( Jimple.v().newReturnStmt( Jimple.v().newLocal("taint", objectClass.getType()))); m.setActiveBody(mockSourceBody); this.setJavaMethodRetAsSource(m); return m; }
/** * Create the Jimple body for the given library method. If it's a * constructor, then we need to initialize all the fields in the class with * objects compatible from the LPT. If it's the static initializer, then we * need to initialize all the static fields of the class with objects * compatible from the LPT. method. * * @param method * * @return */ private JimpleBody createJimpleBody(SootMethod method) { if (method.getDeclaringClass().getName().equals(Names.AVERROES_ABSTRACT_LIBRARY_CLASS) || method.getDeclaringClass().getName().equals(Names.AVERROES_LIBRARY_CLASS)) { throw new IllegalArgumentException("Creating Jimple body for " + method.getSignature() + ". We should never enter createJimpleBody() for the Averroes library classes."); } // Create a basic Jimple body AverroesJimpleBody body = new AverroesJimpleBody(method); // Insert the appropriate method body if (body.isConstructor()) { body.initializeInstanceFields(); } else if (body.isStaticInitializer()) { body.initializeStaticFields(); } else { // the standard library method will have nothing more in its body } // Insert the standard Jimple body footer body.insertStandardJimpleBodyFooter(); // Validate the Jimple body body.validate(); // TODO // System.out.println(body.getJimpleBody()); return (JimpleBody) method.getActiveBody(); }
/** * Stub for static method "void set(Object array, int index, Object value) * in class java.lang.reflect.Array. * Stub code is as follows: * t0 = (Object[])param0 * t0[0] = param2 * return */ private static SootMethod getArraySetEquiv(SootMethod m) { SootMethod s = genericMethod(m, false); JimpleBody body =(JimpleBody) s.retrieveActiveBody(); SootClass c = s.getDeclaringClass(); Chain<Unit> units = body.getUnits(); Chain<Local> locals = body.getLocals(); //t0 = (Object[])param0 Local l0 = body.getParameterLocal(0); CastExpr ce0 = Jimple.v().newCastExpr(l0, ArrayType.v(RefType.v("java.lang.Object"), 1)); Local t0 = Jimple.v().newLocal("t0", c.getType()); locals.add(t0); units.add(Jimple.v().newAssignStmt(t0, ce0)); //t0[0] = param2 Local l2 = body.getParameterLocal(2); ArrayRef ar2 = Jimple.v().newArrayRef((Value)t0, (Value)IntConstant.v(0)); units.add(Jimple.v().newAssignStmt(ar2, l2)); //return units.add(Jimple.v().newReturnVoidStmt()); methodToStub.put(m, s); methodToStub.put(s, s); if (Config.verbose >= 2) System.out.println("Custom stub (getArraySetEquiv) for method: " + s.getName() + ":" + s.getDeclaringClass()); return s; }
public SootMethod generateDummyMainMethod(List<String> entryPoints, String sootClassName) { List<String> androidClasses = new ArrayList<String>(); androidClasses.add(sootClassName); SootMethod mainMethod = new SootMethod(DUMMY_MAIN_METHOD, new ArrayList<Type>(), VoidType.v(), Modifier.PUBLIC);// | Modifier.STATIC); //no need be static JimpleBody body = Jimple.v().newBody(mainMethod); mainMethod.setActiveBody(body); SootClass compSootClass = Scene.v().getSootClass(sootClassName); compSootClass.addMethod(mainMethod); //this is mandatory, the default dummyMainMethod is static, so they //do not deal thisIdentity. since we don't need static dummyMainMethod, //we should define it explicit body.insertIdentityStmts(); Map<String, List<String>> callbackFunctions = new HashMap<String, List<String>>(); callbackFunctions.put(sootClassName, getCallbackFunctions(compSootClass)); AndroidEntryPointCreator androidEPCreator = new AndroidEntryPointCreator(androidClasses); androidEPCreator.setCallbackFunctions(callbackFunctions); return androidEPCreator.createDummyMain(mainMethod); }
public SootMethod generateRedirectMethodForStartActivity(SootClass wrapper) { System.out.println("create method to call wrapper class: "+ wrapper); String newSM_name = "redirector" + num++; List<Type> newSM_parameters = new ArrayList<Type>(); newSM_parameters.add(INTENT_TYPE); Type newSM_return_type = VoidType.v(); int modifiers = Modifier.STATIC | Modifier.PUBLIC; SootMethod newSM = new SootMethod(newSM_name, newSM_parameters, newSM_return_type, modifiers); ipcSC.addMethod(newSM); JimpleBody b = Jimple.v().newBody(newSM); newSM.setActiveBody(b); LocalGenerator lg = new LocalGenerator(b); // identity Local intentParameterLocal = lg.generateLocal(INTENT_TYPE); Unit intentParameterU = Jimple.v().newIdentityStmt( intentParameterLocal, Jimple.v().newParameterRef(INTENT_TYPE, 0)); // new Local al = lg.generateLocal(wrapper.getType()); Unit newU = (Unit) Jimple.v().newAssignStmt(al, Jimple.v().newNewExpr(wrapper.getType()) ); // init List<Type> parameters = new ArrayList<Type>(); parameters.add(INTENT_TYPE); SootMethod method = wrapper.getMethod("<init>", parameters, VoidType.v()); List<Value> args = new ArrayList<Value>(); args.add(intentParameterLocal); Unit initU = (Unit) Jimple.v().newInvokeStmt( Jimple.v().newSpecialInvokeExpr(al, method.makeRef(), args)); // call dummyMainMethod //method = wrapper.getMethodByName(ICCDummyMainCreator.DUMMY_MAIN_METHOD); method = wrapper.getMethodByName("onCreate"); args = new ArrayList<Value>(); Local pLocal = lg.generateLocal(RefType.v("android.os.Bundle")); Unit nullParamU = (Unit) Jimple.v().newAssignStmt(pLocal, NullConstant.v()); args.add(pLocal); InvokeExpr invoke = Jimple.v().newVirtualInvokeExpr(al, method.makeRef(), args); Unit callU = (Unit) Jimple.v().newInvokeStmt(invoke); b.getUnits().add(intentParameterU); b.getUnits().add(newU); b.getUnits().add(initU); b.getUnits().add(nullParamU); b.getUnits().add(callU); b.getUnits().add(Jimple.v().newReturnVoidStmt()); System.out.println("new lifecypcle method: "+ newSM +" body: "+ newSM.retrieveActiveBody()); return newSM; }
protected SootMethod createEmptyMainMethod(JimpleBody body){ SootMethod mainMethod = new SootMethod("dummyMainMethod", new ArrayList<Type>(), VoidType.v()); body.setMethod(mainMethod); mainMethod.setActiveBody(body); SootClass mainClass = new SootClass("dummyMainClass"); mainClass.addMethod(mainMethod); // First add class to scene, then make it an application class // as addClass contains a call to "setLibraryClass" Scene.v().addClass(mainClass); mainClass.setApplicationClass(); mainMethod.setModifiers(Modifier.PUBLIC | Modifier.STATIC); return mainMethod; }
/** * Constructed for a given method. * @param jb the Jimple body of the method */ public LocalAnalysis(JimpleBody jb) { CompleteUnitGraph ug = new CompleteUnitGraph(jb); unitGraph = ug; defs = new SimpleLocalDefs(ug); uses = new SimpleLocalUses(ug,defs); }
private SootMethod generatedTestMethod(SootClass sootClass) { List<RefType> parameterTypes = new ArrayList<RefType>(); for (int i = 0; i < 2; i++) { parameterTypes.add(RefType.v("int")); } SootMethod sootMethod = new SootMethod("compare", parameterTypes, RefType.v("int")); sootMethod.setDeclaringClass(sootClass); sootClass.addMethod(sootMethod); JimpleBody body = Jimple.v().newBody(sootMethod); sootMethod.setActiveBody(body); Chain<Unit> units = body.getUnits(); units.add(Jimple.v().newReturnStmt(IntConstant.v(42))); return sootMethod; }
/** * Method creates a static initializer with an empty body for the specified * class and returns this method. * * @param sootClass * Class for which the empty static initializer should be * created. * @return Static initializer method with an empty method body for the * specified class. */ public static SootMethod generatedEmptyStaticInitializer(SootClass sootClass) { SootMethod sootMethod = new SootMethod(staticInitializerName, new ArrayList<Object>(), VoidType.v(), STATIC); sootMethod.setDeclaringClass(sootClass); sootClass.addMethod(sootMethod); JimpleBody body = Jimple.v().newBody(sootMethod); sootMethod.setActiveBody(body); Chain<Unit> units = body.getUnits(); units.add(Jimple.v().newReturnVoidStmt()); return sootMethod; }
/** * Creates a method body that throws an "unresolved compilation error" * message * @param declaringClass The class that was supposed to contain the method * @return The created SootMethod */ private SootMethod createUnresolvedErrorMethod(SootClass declaringClass) { SootMethod m = new SootMethod(name, parameterTypes, returnType, isStatic()?Modifier.STATIC:0); int modifiers = Modifier.PUBLIC; // we don't know who will be calling us if (isStatic()) modifiers |= Modifier.STATIC; m.setModifiers(modifiers); JimpleBody body = Jimple.v().newBody(m); m.setActiveBody(body); final LocalGenerator lg = new LocalGenerator(body); // For producing valid Jimple code, we need to access all parameters. // Otherwise, methods like "getThisLocal()" will fail. if (!isStatic) { RefType thisType = RefType.v(declaringClass); Local lThis = lg.generateLocal(thisType); body.getUnits().add(Jimple.v().newIdentityStmt(lThis, Jimple.v().newThisRef(thisType))); } for (int i = 0; i < m.getParameterCount(); i++) { Type paramType = m.getParameterType(i); Local lParam = lg.generateLocal(paramType); body.getUnits().add(Jimple.v().newIdentityStmt(lParam, Jimple.v().newParameterRef(paramType, i))); } //exc = new Error RefType runtimeExceptionType = RefType.v("java.lang.Error"); NewExpr newExpr = Jimple.v().newNewExpr(runtimeExceptionType); Local exceptionLocal = lg.generateLocal(runtimeExceptionType); AssignStmt assignStmt = Jimple.v().newAssignStmt(exceptionLocal, newExpr); body.getUnits().add(assignStmt); //exc.<init>(message) SootMethodRef cref = Scene.v().makeConstructorRef(runtimeExceptionType.getSootClass(), Collections.<Type>singletonList(RefType.v("java.lang.String"))); SpecialInvokeExpr constructorInvokeExpr = Jimple.v().newSpecialInvokeExpr(exceptionLocal, cref, StringConstant.v("Unresolved compilation error: Method "+getSignature()+" does not exist!")); InvokeStmt initStmt = Jimple.v().newInvokeStmt(constructorInvokeExpr); body.getUnits().insertAfter(initStmt, assignStmt); //throw exc body.getUnits().insertAfter(Jimple.v().newThrowStmt(exceptionLocal), initStmt); declaringClass.addMethod(m); return m; }
private void addCaching(Kind kind) { SootClass c; String methodName; switch(kind) { case ClassNewInstance: c = Scene.v().getSootClass("java.lang.Class"); methodName = "knownClassNewInstance"; break; case ConstructorNewInstance: c = Scene.v().getSootClass("java.lang.reflect.Constructor"); methodName = "knownConstructorNewInstance"; break; case MethodInvoke: c = Scene.v().getSootClass("java.lang.reflect.Method"); methodName = "knownMethodInvoke"; break; case ClassForName: //Cannot implement caching in this case because we can add no field to the String argument return; default: throw new IllegalStateException("unknown kind: "+kind); } SootClass reflCallsClass = Scene.v().getSootClass("soot.rtlib.tamiflex.ReflectiveCalls"); SootMethod m = reflCallsClass.getMethodByName(methodName); JimpleBody body = (JimpleBody) m.retrieveActiveBody(); LocalGenerator localGen = new LocalGenerator(body); Unit firstStmt = body.getFirstNonIdentityStmt(); firstStmt = body.getUnits().getPredOf(firstStmt); Stmt jumpTarget = Jimple.v().newNopStmt(); Chain<Unit> newUnits = new HashChain<Unit>(); //alreadyCheckedLocal = m.alreadyChecked InstanceFieldRef fieldRef = Jimple.v().newInstanceFieldRef(body.getParameterLocal(m.getParameterCount()-1), Scene.v().makeFieldRef(c, ALREADY_CHECKED_FIELDNAME, BooleanType.v(), false)); Local alreadyCheckedLocal = localGen.generateLocal(BooleanType.v()); newUnits.add(Jimple.v().newAssignStmt(alreadyCheckedLocal, fieldRef)); //if(!alreadyChecked) goto jumpTarget newUnits.add(Jimple.v().newIfStmt(Jimple.v().newEqExpr(alreadyCheckedLocal, IntConstant.v(0)), jumpTarget)); //return newUnits.add(Jimple.v().newReturnVoidStmt()); //jumpTarget: nop newUnits.add(jumpTarget); //m.alreadyChecked = true InstanceFieldRef fieldRef2 = Jimple.v().newInstanceFieldRef(body.getParameterLocal(m.getParameterCount()-1), Scene.v().makeFieldRef(c, ALREADY_CHECKED_FIELDNAME, BooleanType.v(), false)); newUnits.add(Jimple.v().newAssignStmt(fieldRef2, IntConstant.v(1))); body.getUnits().insertAfter(newUnits, firstStmt); if(Options.v().validate()) body.validate(); }
public UseChecker(JimpleBody jb) { this.jb = jb; }
public void collect(Stmt stmt, JimpleBody stmtBody) { this.stmtBody = stmtBody; stmt.apply(this); }
/** Assign types to local variables. * */ protected void internalTransform(Body b, String phaseName, Map<String, String> options) { if (b == null) { throw new NullPointerException(); } Date start = new Date(); if (Options.v().verbose()) G.v().out.println("[TypeAssigner] typing system started on " + start); JBTROptions opt = new JBTROptions(options); ignoreWrongStaticNess = opt.ignore_wrong_staticness(); /* * Setting this guard to true enables comparison of the original and new * type assigners. This will be slow since type assignment will always * happen twice. The actual types used for Jimple are determined by the * use-old-type-assigner option. * * Each comparison is written as a separate semicolon-delimited line to * the standard output, and the first field is always 'cmp' for use in * grep. The format is: * * cmp;Method Name;Stmt Count;Old Inference Time (ms); New Inference * Time (ms);Typing Comparison * * The Typing Comparison field compares the old and new typings: -2 - * Old typing contains fewer variables (BAD!) -1 - Old typing is tighter * (BAD!) 0 - Typings are equal 1 - New typing is tighter 2 - New typing * contains fewer variables 3 - Typings are incomparable (inspect * manually) * * In a final release this guard, and anything in the first branch, * would probably be removed. */ if (opt.compare_type_assigners()) { compareTypeAssigners(b,opt.use_older_type_assigner()); } else { if (opt.use_older_type_assigner()) TypeResolver.resolve((JimpleBody) b, Scene.v()); else (new soot.jimple.toolkits.typing.fast.TypeResolver( (JimpleBody) b)).inferTypes(); } Date finish = new Date(); if (Options.v().verbose()) { long runtime = finish.getTime() - start.getTime(); long mins = runtime / 60000; long secs = (runtime % 60000) / 1000; G.v().out.println("[TypeAssigner] typing system ended. It took " + mins + " mins and " + secs + " secs."); } replaceNullType(b); if (typingFailed((JimpleBody) b)) throw new RuntimeException("type inference failed!"); }
public Body getBody(JimpleBody b) { return b; }