public static HashSet<SootMethod> getAllImplementations(SootMethod method) { Chain appClasses = Scene.v().getApplicationClasses(); HashSet<SootClass> implementingClasses = new HashSet<SootClass>(1); HashSet<SootMethod> overridingMethods = new HashSet<SootMethod>(1); SootClass t = method.getDeclaringClass(); if ( /*t.isAbstract() || */ t.isPhantom() || t.isPhantomClass()) { boolean b1 = t.isAbstract(); boolean be = t.isPhantom(); boolean b3 = t.isPhantomClass(); try { throw new Exception("Need to implement for Plantom Classes"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } if (t.isAbstract()) { for (Object object : appClasses) { SootClass clazz = (SootClass) object; SootClass superClass = clazz.getSuperclass(); { if (superClass.getName().equals(t.toString())) { implementingClasses.add(clazz); SootMethod m2 = clazz.getMethod( method.getName(), method.getParameterTypes(), method.getReturnType()); overridingMethods.add(m2); } } } } if (t.isInterface()) { for (Object object : appClasses) { SootClass clazz = (SootClass) object; Chain<SootClass> interfaces = clazz.getInterfaces(); for (SootClass sootClass : interfaces) { if (sootClass.getName().equals(t.toString())) { implementingClasses.add(clazz); SootMethod m2 = clazz.getMethod( method.getName(), method.getParameterTypes(), method.getReturnType()); overridingMethods.add(m2); } } } } return overridingMethods; }
/** For instance invokes */ public static ArrayList<SootMethod> resolveAppCall(Type tgtType, SootMethodRef methodRef) { final NumberedString mSubsignature = methodRef.getSubSignature(); if (tgtType instanceof RefType) { // find first class upwards in hierarchy, starting from cls, that implements method (i.e., // *concrete* method) SootClass cls = ((RefType) tgtType).getSootClass(); while (!cls.declaresMethod(mSubsignature)) cls = cls .getSuperclass(); // if method not in this class, it HAS to be in a superclass, so a // superclass must exist if (!cls.hasTag(ClassTag.TAG_NAME)) return null; // not an app method // finally, store resolved app method SootMethod m = cls.getMethod(mSubsignature); assert m.hasTag(MethodTag.TAG_NAME); ArrayList<SootMethod> methods = new ArrayList<SootMethod>(); methods.add(m); // just one element, directly resolved return methods; } if (tgtType instanceof AnySubType) { // return set of all app subtypes that implement referenced method SootClass baseCls = ((AnySubType) tgtType).getBase().getSootClass(); List subClasses = baseCls.isInterface() ? Scene.v().getActiveHierarchy().getImplementersOf(baseCls) : Scene.v().getActiveHierarchy().getSubclassesOf(baseCls); ArrayList<SootMethod> methods = new ArrayList<SootMethod>(); for (Object oSubCls : subClasses) { SootClass subCls = (SootClass) oSubCls; if (subCls.hasTag(ClassTag.TAG_NAME)) { try { SootMethod m = subCls.getMethod(mSubsignature); assert m.hasTag(MethodTag.TAG_NAME); if (!m.isAbstract()) methods.add(m); } catch (RuntimeException e) { } } } return methods; } assert tgtType instanceof ArrayType; // only other case observed so far return new ArrayList(); // no array class/method is in app }
public void staticBlockInlining(SootClass sootClass) { this.sootClass = sootClass; // retrieve the clinit method if any for sootClass if (!sootClass.declaresMethod("void <clinit>()")) { System.out.println("no clinit"); return; } SootMethod clinit = sootClass.getMethod("void <clinit>()"); // System.out.println(clinit); // retireve the active body if (!clinit.hasActiveBody()) throw new RuntimeException("method " + clinit.getName() + " has no active body!"); Body clinitBody = clinit.getActiveBody(); Chain units = ((DavaBody) clinitBody).getUnits(); if (units.size() != 1) { throw new RuntimeException("DavaBody AST doesn't have single root."); } ASTNode AST = (ASTNode) units.getFirst(); if (!(AST instanceof ASTMethodNode)) throw new RuntimeException("Starting node of DavaBody AST is not an ASTMethodNode"); AST.apply(new MethodCallFinder(this)); }
/** * Resolve the concrete target of a special invoke using our modified semantics for special invoke * expression. */ private SootMethod resolveSpecialInvokeTarget(SpecialInvokeExpr si) { SootMethod target = null; try { target = SootUtils.resolve(si.getMethodRef()); } catch (CannotFindMethodException e) { logger.error("Cannot find concrete method target for special invoke: {}", si); return null; } String targetSubSig = target.getSubSignature(); SootClass current = target.getDeclaringClass(); while (true) { if (current.declaresMethod(targetSubSig)) { return current.getMethod(targetSubSig); } // not a match in current, try superclass on next loop if (current.hasSuperclass()) current = current.getSuperclass(); else { logger.error("Cannot find concrete method target for special invoke: {}", si); droidsafe.main.Main.exit(1); return null; } } }
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; }
/** * Finds in class hierarchy and returns all app and lib concrete methods possibly referenced by * method ref. Method is assumed to be virtual (not special or static). Returns true if there are * library methods among targets found. */ public static boolean getConcreteCallTargets( InvokeExpr instInvExpr, /*OUT*/ Set<SootMethod> appTargets, /*OUT*/ Set<SootMethod> libTargets) { // get class of method ref; we start searching from this class SootMethodRef mref = instInvExpr.getMethodRef(); SootClass cls = mref.declaringClass(); // starting class final NumberedString subsignature = mref.getSubSignature(); // signature to search for // CASE 1: object is of declared class type or inherited from some superclass // find first superclass, starting from current cls, that declares method; there HAS to // be such a class // note that if cls is interface, superclass if java.lang.Object // note that we don't check if there is indeed an interface declaring the method; we assume this // is the case if no superclass declares it while (!cls.declaresMethod(subsignature) && cls.hasSuperclass()) cls = cls.getSuperclass(); // never an interface // now, method might not be in superclass, or might be abstract; in that case, it's not a target SootMethod m; if (cls.declaresMethod(subsignature)) { m = cls.getMethod(subsignature); if (!m.isAbstract()) { if (cls.hasTag(ClassTag.TAG_NAME)) appTargets.add(m); // add app method else libTargets.add(m); // add lib method } } // (only for virtual/interface calls) // CASE 2: object's actual type is a subclass; any subclass declaring the method is a possible // target // we have to check all superclasses of implementers, because starting cls might be // interface if (instInvExpr instanceof VirtualInvokeExpr || instInvExpr instanceof InterfaceInvokeExpr) { cls = mref.declaringClass(); // start again from declaring class List<SootClass> allSubclasses = getAllSubtypes(cls); for (SootClass subCls : allSubclasses) { m = getMethodInClassOrSuperclass(subCls, subsignature); if (m != null && !m.isAbstract()) { if (m.getDeclaringClass().hasTag(ClassTag.TAG_NAME)) appTargets.add(m); // add app method else libTargets.add(m); // add lib method } } } return !libTargets.isEmpty(); }
public static void main(String[] args) { List<String> argsList = new ArrayList<String>(Arrays.asList(args)); argsList.addAll( Arrays.asList( new String[] { "-w", // "-p", "cg.spark", "on-fly-cg:true", // "-main-class", "testers.CallGraphs",// main-class "testers.CallGraphs", // argument classes // "testers.A" // })); argsList.add("-soot-class-path"); argsList.add( "/home/nnguyen/workspaceluna/CoGConstructor/bin:/usr/java/jdk1.7.0_79/jre/lib/rt.jar:/usr/java/jdk1.7.0_79/jre/lib/jce.jar"); argsList.add("-p"); argsList.add("cg"); argsList.add("all-reachable:true"); argsList.add("-p"); argsList.add("cg.spark"); argsList.add("on-fly-cg:true"); argsList.add("-f"); argsList.add("J"); // argsList.add("-no-bodies-for-excluded"); // argsList.add("pre-jimplify:true"); System.out.println("JB " + PackManager.v().getPack("jb").getDefaultOptions()); System.out.println("JBLS " + PackManager.v().getPhase("jb.ls").getDefaultOptions()); System.out.println("JBDAE " + PackManager.v().getPhase("jb.dae").getDefaultOptions()); System.out.println("CHCHA " + PackManager.v().getPhase("cg.cha").getDeclaredOptions()); System.out.println("CG" + PackManager.v().getPack("cg").getDeclaredOptions()); // PackManager.v().getPack("wjtp").add(new Transform("wjtp.myTrans", new SceneTransformer() { // // System.out.println(PackManager.v().getPhase("cg.spark").getDeclaredOptions()); // // // PackManager.v().getPack("cg").add(new Transform("cg.myTrans", new SceneTransformer() { // // @Override // protected void internalTransform(String phaseName, Map options) { // CHATransformer.v().transform(); // SootClass a = Scene.v().getSootClass("testers.A"); // // SootMethod src = Scene.v().getMainClass().getMethodByName("doStuff"); // CallGraph cg = Scene.v().getCallGraph(); // // Iterator<MethodOrMethodContext> targets = new Targets(cg.edgesOutOf(src)); // // while (targets.hasNext()) { // SootMethod tgt = (SootMethod) targets.next(); // System.out.println(src + " may call " + tgt); // } // // Iterator<MethodOrMethodContext> sources = new Sources(cg.edgesInto(src)); // // while (sources.hasNext()) { // SootMethod tgt = (SootMethod) sources.next(); // // System.out.println(src + " may be called by " + tgt + " " + tgt.getName()); // } // // } // // })); args = argsList.toArray(new String[0]); Options.v().parse(args); // disable if want to use soot.Main.main Options.v().set_keep_line_number(true); Options.v().set_whole_program(true); Options.v().set_allow_phantom_refs(true); Options.v().setPhaseOption("jb", "use-original-names:true"); // soot.Main.main(args); List addedEntryPoints = new ArrayList(); // for (String ePoint : customEntryPoints) { SootClass c = Scene.v().forceResolve("testers.CallGraphs", SootClass.BODIES); c.setApplicationClass(); Scene.v().loadNecessaryClasses(); SootMethod method; String methodName = "main"; if (!methodName.contains("(")) { method = c.getMethodByName(methodName); System.out.println("FOUND IT"); } else { // List<Type> types = new ArrayList<Type>(); method = c.getMethod(methodName); System.out.println("FOUND IT"); } addedEntryPoints.add(method); // } Scene.v().setEntryPoints(addedEntryPoints); PackManager.v().runPacks(); JimpleBasedInterproceduralCFG icfg = new JimpleBasedInterproceduralCFG(); IFDSTabulationProblem< Unit, Pair<Value, Set<DefinitionStmt>>, SootMethod, InterproceduralCFG<Unit, SootMethod>> problem = (IFDSTabulationProblem) new IFDSReachingDefinitions(icfg); System.out.println("Number of threads :" + problem.numThreads()); JimpleIFDSSolver<Pair<Value, Set<DefinitionStmt>>, InterproceduralCFG<Unit, SootMethod>> solver = new JimpleIFDSSolver< Pair<Value, Set<DefinitionStmt>>, InterproceduralCFG<Unit, SootMethod>>( problem, true); System.out.println("Started Solving...."); System.out.println(Scene.v().getMainMethod().getName()); SootMethod mMethod = Scene.v().getSootClass("testers.CallGraphs").getMethodByName("main"); // SootMethod mMethod = Scene.v().getMainClass().getMethodByName("doStuff2"); BiDirICFGFactory icfgFactory = new DefaultBiDiICFGFactory(); IInfoflowCFG iCfg = icfgFactory.buildBiDirICFG(CallgraphAlgorithm.AutomaticSelection, true); CallGraph cg = Scene.v().getCallGraph(); // SootClass cl = Scene.v().getMainClass(); for (SootClass cl : Scene.v().getClasses()) { for (SootMethod sm : cl.getMethods()) { if (sm.getSignature().contains("testers") || sm.getSignature().contains("java.lang.Object next()")) { // if // (sm.getSignature().equals("<testers.CallGraphs$CellIterator: java.lang.Object // next()>")) // { // if (sm.getSignature().equals("<testers.CallGraphs: void p4(int)>")) { System.out.println( "WE FOUND " + sm.getSignature() + " AT " + sm.getJavaSourceStartLineNumber()); Iterator sources = new Sources(cg.edgesInto(sm)); while (sources.hasNext()) { SootMethod sm2 = (SootMethod) sources.next(); System.out.println("CALLED BY " + sm2.getSignature()); } // sources = new Sources(cg.edgesOutOf(sm)); // while (sources.hasNext()) { // SootMethod sm2 = (SootMethod) sources.next(); // System.out.println("CALLS " + sm2.getSignature()); // } // } } } } if (mMethod.hasActiveBody()) { System.out.println("YESSSSSSSSSSSSSSSSS"); Body b = mMethod.getActiveBody(); for (Unit u : b.getUnits()) { System.out.println(u + " AT " + u.getJavaSourceStartLineNumber()); } System.out.println("==================="); for (Unit u : b.getUnits()) { if (u instanceof IfStmt) { System.out.println("IF STMT AT " + u.getJavaSourceStartLineNumber()); IfStmt stmt = (IfStmt) u; System.out.println(u); Value condition = stmt.getCondition(); ValueBox conditionBox = stmt.getConditionBox(); System.out.println( "Condition " + condition + " AT " + conditionBox.getJavaSourceStartLineNumber()); System.out.println( "Target " + stmt.getTarget() + " AT " + stmt.getTarget().getJavaSourceStartLineNumber()); System.out.println( iCfg.getPostdominatorOf(u) + " AT " + u.getJavaSourceStartLineNumber()); System.out.println(iCfg.getSuccsOf(u)); System.out.println("====="); } if (u instanceof GotoStmt) { System.out.println("GOTO STMT AT " + u.getJavaSourceStartLineNumber()); GotoStmt stmt = (GotoStmt) u; System.out.println(u); System.out.println(stmt.getTarget()); System.out.println("====="); } } } // commented to test the IfStmt // if (!Scene.v().getMainMethod().hasActiveBody()) { // System.out.println("NONOOOOOOOOOOOOOOOOOOOOOOOOOOO"); // } // // Scene.v().getMainMethod().getActiveBody() // solver.solve(); // System.out.println("Completed Solving...."); // solver.dumpResults(); }
private StructureConstant createClassInfoStruct() { int flags = 0; if (Modifier.isPublic(sootClass.getModifiers())) { flags |= CI_PUBLIC; } if (Modifier.isFinal(sootClass.getModifiers())) { flags |= CI_FINAL; } if (Modifier.isInterface(sootClass.getModifiers())) { flags |= CI_INTERFACE; } if (Modifier.isAbstract(sootClass.getModifiers())) { flags |= CI_ABSTRACT; } if ((sootClass.getModifiers() & 0x1000) > 0) { flags |= CI_SYNTHETIC; } if (Modifier.isAnnotation(sootClass.getModifiers())) { flags |= CI_ANNOTATION; } if (Modifier.isEnum(sootClass.getModifiers())) { flags |= CI_ENUM; } if (attributesEncoder.classHasAttributes()) { flags |= CI_ATTRIBUTES; } if (hasFinalizer(sootClass)) { flags |= CI_FINALIZABLE; } // Create the ClassInfoHeader structure. StructureConstantBuilder header = new StructureConstantBuilder(); header.add(new NullConstant(I8_PTR)); // Points to the runtime Class struct header.add(new IntegerConstant(flags)); header.add(getString(getInternalName(sootClass))); if (sootClass.declaresMethod("<clinit>", Collections.emptyList(), VoidType.v())) { SootMethod method = sootClass.getMethod("<clinit>", Collections.emptyList(), VoidType.v()); header.add(new FunctionRef(mangleMethod(method), getFunctionType(method))); } else { header.add(new NullConstant(I8_PTR)); } header.add(sizeof(classType)); header.add(sizeof(instanceType)); if (!instanceFields.isEmpty()) { header.add(offsetof(instanceType, 1, 1)); } else { header.add(sizeof(instanceType)); } header.add(new IntegerConstant((short) countReferences(classFields))); header.add(new IntegerConstant((short) countReferences(instanceFields))); PackedStructureConstantBuilder body = new PackedStructureConstantBuilder(); body.add(new IntegerConstant((short) sootClass.getInterfaceCount())); body.add(new IntegerConstant((short) sootClass.getFieldCount())); body.add(new IntegerConstant((short) sootClass.getMethodCount())); if (!sootClass.isInterface()) { body.add( getStringOrNull( sootClass.hasSuperclass() ? getInternalName(sootClass.getSuperclass()) : null)); } if (attributesEncoder.classHasAttributes()) { body.add(new ConstantBitcast(attributesEncoder.getClassAttributes().ref(), I8_PTR)); } for (SootClass s : sootClass.getInterfaces()) { body.add(getString(getInternalName(s))); } for (SootField f : sootClass.getFields()) { flags = 0; soot.Type t = f.getType(); if (t instanceof PrimType) { if (t.equals(BooleanType.v())) { flags |= DESC_Z; } else if (t.equals(ByteType.v())) { flags |= DESC_B; } else if (t.equals(ShortType.v())) { flags |= DESC_S; } else if (t.equals(CharType.v())) { flags |= DESC_C; } else if (t.equals(IntType.v())) { flags |= DESC_I; } else if (t.equals(LongType.v())) { flags |= DESC_J; } else if (t.equals(FloatType.v())) { flags |= DESC_F; } else if (t.equals(DoubleType.v())) { flags |= DESC_D; } flags <<= 12; } if (Modifier.isPublic(f.getModifiers())) { flags |= FI_PUBLIC; } else if (Modifier.isPrivate(f.getModifiers())) { flags |= FI_PRIVATE; } else if (Modifier.isProtected(f.getModifiers())) { flags |= FI_PROTECTED; } if (Modifier.isStatic(f.getModifiers())) { flags |= FI_STATIC; } if (Modifier.isFinal(f.getModifiers())) { flags |= FI_FINAL; } if (Modifier.isVolatile(f.getModifiers())) { flags |= FI_VOLATILE; } if (Modifier.isTransient(f.getModifiers())) { flags |= FI_TRANSIENT; } if ((f.getModifiers() & 0x1000) > 0) { flags |= FI_SYNTHETIC; } if (Modifier.isEnum(f.getModifiers())) { flags |= FI_ENUM; } if (attributesEncoder.fieldHasAttributes(f)) { flags |= FI_ATTRIBUTES; } body.add(new IntegerConstant((short) flags)); body.add(getString(f.getName())); if (!(t instanceof PrimType)) { body.add(getString(getDescriptor(f))); } if (f.isStatic()) { int index = classFields.indexOf(f); body.add(offsetof(classType, 1, index, 1)); } else { int index = instanceFields.indexOf(f); body.add(offsetof(instanceType, 1, 1 + index, 1)); } if (attributesEncoder.fieldHasAttributes(f)) { body.add(new ConstantBitcast(attributesEncoder.getFieldAttributes(f).ref(), I8_PTR)); } } for (SootMethod m : sootClass.getMethods()) { soot.Type t = m.getReturnType(); flags = 0; if (Modifier.isPublic(m.getModifiers())) { flags |= MI_PUBLIC; } else if (Modifier.isPrivate(m.getModifiers())) { flags |= MI_PRIVATE; } else if (Modifier.isProtected(m.getModifiers())) { flags |= MI_PROTECTED; } if (Modifier.isStatic(m.getModifiers())) { flags |= MI_STATIC; } if (Modifier.isFinal(m.getModifiers())) { flags |= MI_FINAL; } if (Modifier.isSynchronized(m.getModifiers())) { flags |= MI_SYNCHRONIZED; } if ((m.getModifiers() & 0x0040) > 0) { flags |= MI_BRIDGE; } if ((m.getModifiers() & 0x0080) > 0) { flags |= MI_VARARGS; } if (Modifier.isNative(m.getModifiers())) { if (!isStruct(sootClass) && !isStructMember(m)) { flags |= MI_NATIVE; } } if (Modifier.isAbstract(m.getModifiers())) { flags |= MI_ABSTRACT; } if (Modifier.isStrictFP(m.getModifiers())) { flags |= MI_STRICT; } if ((m.getModifiers() & 0x1000) > 0) { flags |= MI_SYNTHETIC; } if (attributesEncoder.methodHasAttributes(m)) { flags |= MI_ATTRIBUTES; } if (isBridge(m)) { flags |= MI_BRO_BRIDGE; } if (isCallback(m)) { flags |= MI_BRO_CALLBACK; } if ((t instanceof PrimType || t == VoidType.v()) && m.getParameterCount() == 0) { flags |= MI_COMPACT_DESC; } body.add(new IntegerConstant((short) flags)); body.add(getString(m.getName())); if ((flags & MI_COMPACT_DESC) > 0) { int desc = 0; if (t.equals(BooleanType.v())) { desc = DESC_Z; } else if (t.equals(ByteType.v())) { desc = DESC_B; } else if (t.equals(ShortType.v())) { desc = DESC_S; } else if (t.equals(CharType.v())) { desc = DESC_C; } else if (t.equals(IntType.v())) { desc = DESC_I; } else if (t.equals(LongType.v())) { desc = DESC_J; } else if (t.equals(FloatType.v())) { desc = DESC_F; } else if (t.equals(DoubleType.v())) { desc = DESC_D; } else if (t.equals(VoidType.v())) { desc = DESC_V; } body.add(new IntegerConstant((byte) desc)); } else { body.add(getString(getDescriptor(m))); } if (attributesEncoder.methodHasAttributes(m)) { body.add(new ConstantBitcast(attributesEncoder.getMethodAttributes(m).ref(), I8_PTR)); } if (!m.isAbstract()) { body.add(new ConstantBitcast(new FunctionRef(mangleMethod(m), getFunctionType(m)), I8_PTR)); body.add( new IntegerConstant( DUMMY_METHOD_SIZE)); // Size of function. This value will be modified later by // patching the .s file. if (m.isSynchronized()) { body.add( new ConstantBitcast( new FunctionRef(mangleMethod(m) + "_synchronized", getFunctionType(m)), I8_PTR)); } } if (isBridge(m)) { body.add(new GlobalRef(BridgeMethodCompiler.getTargetFnPtrName(m), I8_PTR)); } if (isCallback(m)) { body.add( new ConstantBitcast( new FunctionRef(mangleMethod(m) + "_callback", getCallbackFunctionType(m)), I8_PTR)); } } // Return the struct {header, body}. To be compatible with the C code in classinfo.c // it is important that the header is padded the same as in C so that the body starts // after sizeof(ClassInfoHeader) bytes. return new StructureConstantBuilder().add(header.build()).add(body.build()).build(); }
public static void mockConstructor(SootClass sc) { SootMethod sm = null; // Without parameters String methodSubSignature = "void <init>()"; try { sm = sc.getMethod(methodSubSignature); } catch (Exception ex) { sm = null; } int m = Modifier.PUBLIC; if (null == sm) { sm = new SootMethod("<init>", new ArrayList<Type>(), VoidType.v(), m); sc.addMethod(sm); // Add body JimpleBody b = Jimple.v().newBody(sm); sm.setActiveBody(b); { b.insertIdentityStmts(); b.getUnits().add(Jimple.v().newReturnVoidStmt()); } System.out.println("validation:" + b); b.validate(); } // Static init /* methodSubSignature = "void <clinit>()"; try { sm = sc.getMethod(methodSubSignature); } catch (Exception ex) { sm = null; } if (null == sm) { sm = new SootMethod("<clinit>", new ArrayList<Type>(), VoidType.v(), m | Modifier.STATIC); sc.addMethod(sm); //Add body JimpleBody b = Jimple.v().newBody(sm); sm.setActiveBody(b); { b.getUnits().add(Jimple.v().newReturnVoidStmt()); } b.validate(); System.out.println("validation:" + b); } */ // With parameter methodSubSignature = "void <init>(java.lang.Object[])"; try { sm = sc.getMethod(methodSubSignature); } catch (Exception ex) { sm = null; } if (null == sm) { List<Type> paramTypes = new ArrayList<Type>(); paramTypes.add(ArrayType.v(RefType.v("java.lang.Object"), 1)); sm = new SootMethod("<init>", paramTypes, VoidType.v(), m); sc.addMethod(sm); // Add body 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 param0Loc = 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 assignU = Jimple.v().newAssignStmt(rtLoc, Jimple.v().newCastExpr(param0Loc, // RefType.v("java.lang.Object"))); // b.getUnits().add(param0U); // b.getUnits().add(assignU); b.getUnits().add(Jimple.v().newReturnVoidStmt()); } System.out.println("validation:" + b); b.validate(); } }
/** * Returns method in given class or first upwards superclass, or null if not found in any class * (no interface checked) */ private static SootMethod getMethodInClassOrSuperclass( SootClass cls, NumberedString subsignature) { if (cls.declaresMethod(subsignature)) return cls.getMethod(subsignature); if (cls.hasSuperclass()) return getMethodInClassOrSuperclass(cls.getSuperclass(), subsignature); return null; }
@Override public void tranformsInvoke( SootMethod containingMthd, SootMethod callee, InvokeExpr invokeExpr, Stmt stmt, Body body) { if (!Project.v().isSrcClass(containingMthd.getDeclaringClass())) { return; } if (modified.contains(stmt)) { return; } modified.add(stmt); IntentResolutionStats.v().contentProviderOps++; Value lvalue = null; if (stmt instanceof AssignStmt) { lvalue = ((AssignStmt) stmt).getLeftOp(); } Set<SootField> targetCPFields = new LinkedHashSet<SootField>(); boolean resolved = true; for (IAllocNode node : PTABridge.v().getPTSetIns(invokeExpr.getArg(0))) { resolved = addToTargets(node, targetCPFields, stmt); if (!resolved) { UnresolvedICC.v().addInfo(stmt, callee, "Unresolved URI for Content Provider"); // can break here because we added all possible content provider destinations IntentResolutionStats.v().contentProviderOpsUnresolvedUri++; break; } } // for each field of harness that is a content provider for (SootField cpField : targetCPFields) { SootClass cpClass = ((RefType) cpField.getType()).getSootClass(); SootMethod target = cpClass.getMethod(callee.getSubSignature()); // create local and add to body Local local = Jimple.v().newLocal("_$contentprovider_local_" + localID++, cpField.getType()); body.getLocals().add(local); // set field of cp to local [local = harness.contentproviderfield] // set local to field Stmt localAssign = Jimple.v().newAssignStmt(local, Jimple.v().newStaticFieldRef(cpField.makeRef())); // insert before original statement body.getUnits().insertBefore(localAssign, stmt); InvokeExpr newInvoke = Jimple.v().newVirtualInvokeExpr(local, target.makeRef(), invokeExpr.getArgs()); // create statement to invoke Stmt toInsert = null; if (lvalue == null) { // original call not in an assign; toInsert = Jimple.v().newInvokeStmt(newInvoke); } else { // original call in an assign toInsert = Jimple.v().newAssignStmt(lvalue, newInvoke); } // insert after original statement just to have all locals assigned in a block body.getUnits().insertAfter(toInsert, stmt); logger.info( "Adding {} call to ContentProvider {} in method {}", callee.getSubSignature(), cpClass, containingMthd); // ignore generated calls in rcfg RCFG.v().ignoreInvokeForOutputEvents(toInsert); } // if resolved and in app target, then don't report if (resolved) { IntentResolutionStats.v().contentProviderOpsResolvedUri++; if (targetCPFields.size() > 0) { RCFG.v().ignoreInvokeForOutputEvents(stmt); IntentResolutionStats.v().contentProviderOpsInAppTotalTargets += targetCPFields.size(); } else { IntentResolutionStats.v().contentProviderOpsInterAppTarget++; } } }
private Value generateCorrectObject(Body body, Value value, List<Unit> generated) { if (value.getType() instanceof PrimType) { // in case of a primitive type, we use boxing (I know it is not nice, but it works...) in // order to use the Object type if (value.getType() instanceof BooleanType) { Local booleanLocal = generateFreshLocal(body, RefType.v("java.lang.Boolean")); SootClass sootClass = Scene.v().getSootClass("java.lang.Boolean"); SootMethod valueOfMethod = sootClass.getMethod("java.lang.Boolean valueOf(boolean)"); StaticInvokeExpr staticInvokeExpr = Jimple.v().newStaticInvokeExpr(valueOfMethod.makeRef(), value); Unit newAssignStmt = Jimple.v().newAssignStmt(booleanLocal, staticInvokeExpr); generated.add(newAssignStmt); return booleanLocal; } else if (value.getType() instanceof ByteType) { Local byteLocal = generateFreshLocal(body, RefType.v("java.lang.Byte")); SootClass sootClass = Scene.v().getSootClass("java.lang.Byte"); SootMethod valueOfMethod = sootClass.getMethod("java.lang.Byte valueOf(byte)"); StaticInvokeExpr staticInvokeExpr = Jimple.v().newStaticInvokeExpr(valueOfMethod.makeRef(), value); Unit newAssignStmt = Jimple.v().newAssignStmt(byteLocal, staticInvokeExpr); generated.add(newAssignStmt); return byteLocal; } else if (value.getType() instanceof CharType) { Local characterLocal = generateFreshLocal(body, RefType.v("java.lang.Character")); SootClass sootClass = Scene.v().getSootClass("java.lang.Character"); SootMethod valueOfMethod = sootClass.getMethod("java.lang.Character valueOf(char)"); StaticInvokeExpr staticInvokeExpr = Jimple.v().newStaticInvokeExpr(valueOfMethod.makeRef(), value); Unit newAssignStmt = Jimple.v().newAssignStmt(characterLocal, staticInvokeExpr); generated.add(newAssignStmt); return characterLocal; } else if (value.getType() instanceof DoubleType) { Local doubleLocal = generateFreshLocal(body, RefType.v("java.lang.Double")); SootClass sootClass = Scene.v().getSootClass("java.lang.Double"); SootMethod valueOfMethod = sootClass.getMethod("java.lang.Double valueOf(double)"); StaticInvokeExpr staticInvokeExpr = Jimple.v().newStaticInvokeExpr(valueOfMethod.makeRef(), value); Unit newAssignStmt = Jimple.v().newAssignStmt(doubleLocal, staticInvokeExpr); generated.add(newAssignStmt); return doubleLocal; } else if (value.getType() instanceof FloatType) { Local floatLocal = generateFreshLocal(body, RefType.v("java.lang.Float")); SootClass sootClass = Scene.v().getSootClass("java.lang.Float"); SootMethod valueOfMethod = sootClass.getMethod("java.lang.Float valueOf(float)"); StaticInvokeExpr staticInvokeExpr = Jimple.v().newStaticInvokeExpr(valueOfMethod.makeRef(), value); Unit newAssignStmt = Jimple.v().newAssignStmt(floatLocal, staticInvokeExpr); generated.add(newAssignStmt); return floatLocal; } else if (value.getType() instanceof IntType) { Local integerLocal = generateFreshLocal(body, RefType.v("java.lang.Integer")); SootClass sootClass = Scene.v().getSootClass("java.lang.Integer"); SootMethod valueOfMethod = sootClass.getMethod("java.lang.Integer valueOf(int)"); StaticInvokeExpr staticInvokeExpr = Jimple.v().newStaticInvokeExpr(valueOfMethod.makeRef(), value); Unit newAssignStmt = Jimple.v().newAssignStmt(integerLocal, staticInvokeExpr); generated.add(newAssignStmt); return integerLocal; } else if (value.getType() instanceof LongType) { Local longLocal = generateFreshLocal(body, RefType.v("java.lang.Long")); SootClass sootClass = Scene.v().getSootClass("java.lang.Long"); SootMethod valueOfMethod = sootClass.getMethod("java.lang.Long valueOf(long)"); StaticInvokeExpr staticInvokeExpr = Jimple.v().newStaticInvokeExpr(valueOfMethod.makeRef(), value); Unit newAssignStmt = Jimple.v().newAssignStmt(longLocal, staticInvokeExpr); generated.add(newAssignStmt); return longLocal; } else if (value.getType() instanceof ShortType) { Local shortLocal = generateFreshLocal(body, RefType.v("java.lang.Short")); SootClass sootClass = Scene.v().getSootClass("java.lang.Short"); SootMethod valueOfMethod = sootClass.getMethod("java.lang.Short valueOf(short)"); StaticInvokeExpr staticInvokeExpr = Jimple.v().newStaticInvokeExpr(valueOfMethod.makeRef(), value); Unit newAssignStmt = Jimple.v().newAssignStmt(shortLocal, staticInvokeExpr); generated.add(newAssignStmt); return shortLocal; } else throw new RuntimeException("Ooops, something went all wonky!"); } else // just return the value, there is nothing to box return value; }
private Value mutate(Value value) { if (value instanceof FieldRef) { FieldRef ref = (FieldRef) value; SootField field = ref.getField(); Type type = field.getType(); if (type instanceof RefType) { RefType ref_type = (RefType) type; SootClass soot_class = ref_type.getSootClass(); if (shouldMap(soot_class)) { addField(field, ref); } } else if (type instanceof ArrayType) { ArrayType array_type = (ArrayType) type; Type base_type = array_type.baseType; if (base_type instanceof RefType) { RefType ref_type = (RefType) base_type; SootClass soot_class = ref_type.getSootClass(); if (shouldMap(soot_class)) { addField(field, ref); } } } SootClass soot_class = field.getDeclaringClass(); if (shouldMap(soot_class)) { addField(field, ref); } return value; } else if (value instanceof InvokeExpr) { InvokeExpr expr = (InvokeExpr) value; SootMethodRef ref = expr.getMethodRef(); SootClass soot_class = ref.declaringClass(); final NumberedString subSignature = ref.getSubSignature(); if (shouldMap(soot_class)) { SootClass new_class = getMapping(soot_class); if (new_class.declaresMethod(subSignature)) { SootMethod new_method = RootbeerScene.v().getMethod(new_class, subSignature.getString()); addAddedMethod(new_method); fixArguments(new_method); RootbeerScene.v().getDfsInfo().addReachableMethodSig(new_method.getSignature()); expr.setMethodRef(new_method.makeRef()); } } else { if (soot_class.declaresMethod(ref.getSubSignature())) { SootMethod method = soot_class.getMethod(ref.getSubSignature()); fixArguments(method); } } ref = remapRef(ref); try { if (shouldMap(soot_class)) { soot_class = getMapping(soot_class); } SootMethod method = soot_class.getMethod(ref.getSubSignature()); RootbeerScene.v().getDfsInfo().addReachableMethodSig(method.getSignature()); expr.setMethodRef(method.makeRef()); } catch (Exception ex) { // ex.printStackTrace(); } return value; } else if (value instanceof NewExpr) { NewExpr expr = (NewExpr) value; RefType base_type = expr.getBaseType(); SootClass soot_class = base_type.getSootClass(); if (shouldMap(soot_class)) { SootClass new_class = getMapping(soot_class); expr.setBaseType(new_class.getType()); } return value; } else if (value instanceof NewArrayExpr) { NewArrayExpr expr = (NewArrayExpr) value; Type base_type = expr.getBaseType(); base_type = fixType(base_type); expr.setBaseType(base_type); return value; } else if (value instanceof NewMultiArrayExpr) { NewMultiArrayExpr expr = (NewMultiArrayExpr) value; ArrayType array_type = expr.getBaseType(); Type base_type = array_type.baseType; if (base_type instanceof RefType) { RefType ref_type = (RefType) base_type; SootClass soot_class = ref_type.getSootClass(); if (shouldMap(soot_class)) { SootClass new_class = getMapping(soot_class); ArrayType new_type = ArrayType.v(new_class.getType(), array_type.numDimensions); expr.setBaseType(new_type); } } return value; } else if (value instanceof CastExpr) { CastExpr expr = (CastExpr) value; Type cast_type = expr.getCastType(); cast_type = fixType(cast_type); expr.setCastType(cast_type); return value; } else if (value instanceof ParameterRef) { ParameterRef ref = (ParameterRef) value; Type new_type = fixType(ref.getType()); return new ParameterRef(new_type, ref.getIndex()); } else if (value instanceof ThisRef) { ThisRef ref = (ThisRef) value; Type new_type = fixType(ref.getType()); return new ThisRef((RefType) new_type); } else if (value instanceof Local) { Local local = (Local) value; Type type = local.getType(); local.setType(fixType(type)); return value; } else { return value; } }
static { innerClass = Scene.v().getSootClass(innerClassStr); testMethodRef = innerClass.getMethod("void test()").makeRef(); }