/** * Clone given method into this class with given name. Update necessary state of prior analyses. */ private SootMethod cloneMethod(SootMethod ancestorM, String cloneName) { // check if we are cloning a method multiple times if (clonedToOriginal.containsValue(ancestorM)) { logger.error("Cloning method twice: {}", ancestorM); droidsafe.main.Main.exit(1); } SootMethod newMeth = new SootMethod( cloneName, ancestorM.getParameterTypes(), ancestorM.getReturnType(), ancestorM.getModifiers(), ancestorM.getExceptions()); // System.out.printf("\tAdding method %s.\n", ancestorM); // register method methods.addMethod(newMeth); clazz.addMethod(newMeth); clonedToOriginal.put(newMeth, ancestorM); API.v().cloneMethodClassifications(ancestorM, newMeth); // clone body Body newBody = (Body) ancestorM.retrieveActiveBody().clone(); newMeth.setActiveBody(newBody); JSAStrings.v().updateJSAResults(ancestorM.retrieveActiveBody(), newBody); return newMeth; }
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 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; }
/** Conveniently create a class deriving from Code.testClass */ public Pair<SootClass, SignatureTable<Level>> makeDerivedClass( String name, SootClass superClass, List<MethodWithSignature<Level>> methods) { SootClass result = makeFreshClass(name); result.setSuperclass(superClass); SignatureTable<Level> newSignatures = this.signatures; for (MethodWithSignature<Level> m : methods) { result.addMethod(m.method); newSignatures = newSignatures.extendWith( m.method, Interop.asJavaStream(m.signature.constraints.stream()).collect(Collectors.toList()), m.signature.effects); } return Pair.of(result, newSignatures); }
public void outAMethodMember(AMethodMember node) { int modifier = 0; Type type; String name; List parameterList = null; List throwsClause = null; JimpleBody methodBody = null; if (node.getMethodBody() instanceof AFullMethodBody) methodBody = (JimpleBody) mProductions.removeLast(); if (node.getThrowsClause() != null) throwsClause = (List) mProductions.removeLast(); if (node.getParameterList() != null) { parameterList = (List) mProductions.removeLast(); } else { parameterList = new ArrayList(); } Object o = mProductions.removeLast(); name = (String) o; type = (Type) mProductions.removeLast(); modifier = processModifiers(node.getModifier()); SootMethod method; if (throwsClause != null) method = new SootMethod(name, parameterList, type, modifier, throwsClause); else method = new SootMethod(name, parameterList, type, modifier); mSootClass.addMethod(method); if (method.isConcrete()) { methodBody.setMethod(method); method.setActiveBody(methodBody); } else if (node.getMethodBody() instanceof AFullMethodBody) throw new RuntimeException("Impossible: !concrete => ! instanceof"); }
private void compile(Clazz clazz, OutputStream out) throws IOException { sootClass = clazz.getSootClass(); mb = new ModuleBuilder(); trampolines = new HashSet<Trampoline>(); catches = new HashSet<String>(); classFields = getClassFields(sootClass); instanceFields = getInstanceFields(sootClass); classType = getClassType(sootClass); instanceType = getInstanceType(sootClass); attributesEncoder.encode(mb, sootClass); // Add a <clinit> method if the class has ConstantValueTags but no <clinit>. // This has to be done before createInfoStruct() is called otherwise the // ClassInfoHeader->initializer value will become NULL and constant static fields // will never be initialized. if (!sootClass.declaresMethodByName("<clinit>") && hasConstantValueTags(classFields)) { SootMethod clinit = new SootMethod("<clinit>", Collections.EMPTY_LIST, VoidType.v(), Modifier.STATIC); JimpleBody body = Jimple.v().newBody(clinit); clinit.setActiveBody(body); body.getUnits().add(new JReturnVoidStmt()); this.sootClass.addMethod(clinit); } if (isStruct(sootClass)) { if (!Modifier.isFinal(sootClass.getModifiers())) { throw new IllegalArgumentException("Struct class must be final"); } SootMethod _sizeOf = new SootMethod("_sizeOf", Collections.EMPTY_LIST, IntType.v(), Modifier.PROTECTED); sootClass.addMethod(_sizeOf); SootMethod sizeOf = new SootMethod( "sizeOf", Collections.EMPTY_LIST, IntType.v(), Modifier.PUBLIC | Modifier.STATIC); sootClass.addMethod(sizeOf); } mb.addInclude( getClass() .getClassLoader() .getResource( String.format("header-%s-%s.ll", config.getOs().getFamily(), config.getArch()))); mb.addInclude(getClass().getClassLoader().getResource("header.ll")); mb.addFunction(createInstanceof()); mb.addFunction(createCheckcast()); mb.addFunction(createLdcClass()); mb.addFunction(createLdcClassWrapper()); Function allocator = createAllocator(); mb.addFunction(allocator); mb.addFunction(createClassInitWrapperFunction(allocator.ref())); for (SootField f : sootClass.getFields()) { Function getter = createFieldGetter(f); Function setter = createFieldSetter(f); mb.addFunction(getter); mb.addFunction(setter); if (f.isStatic() && !f.isPrivate()) { mb.addFunction(createClassInitWrapperFunction(getter.ref())); if (!f.isFinal()) { mb.addFunction(createClassInitWrapperFunction(setter.ref())); } } } for (SootMethod method : sootClass.getMethods()) { String name = method.getName(); if (isBridge(method)) { bridgeMethod(method); } else if (isStruct(sootClass) && ("_sizeOf".equals(name) || "sizeOf".equals(name) || isStructMember(method))) { structMember(method); } else if (method.isNative()) { nativeMethod(method); } else if (!method.isAbstract()) { method(method); } if (!name.equals("<clinit>") && !name.equals("<init>") && !method.isPrivate() && !method.isStatic() && !Modifier.isFinal(method.getModifiers()) && !Modifier.isFinal(sootClass.getModifiers())) { createLookupFunction(method); } if (method.isStatic()) { String fnName = mangleMethod(method); if (method.isSynchronized()) { fnName += "_synchronized"; } FunctionRef fn = new FunctionRef(fnName, getFunctionType(method)); mb.addFunction(createClassInitWrapperFunction(fn)); } } Set<String> trampolineDependencies = new HashSet<String>(); for (Trampoline trampoline : trampolines) { trampolineResolver.compile(mb, trampoline); trampolineDependencies.addAll(trampolineResolver.getDependencies()); } Global classInfoStruct = null; StructureConstant classInfoErrorStruct = createClassInfoErrorStruct(); if (classInfoErrorStruct != null) { // The class cannot be loaded at runtime. Replace the ClassInfo struct // with a ClassInfoError struct with details of why. classInfoStruct = new Global(mangleClass(sootClass) + "_info_struct", classInfoErrorStruct); } else { classInfoStruct = new Global(mangleClass(sootClass) + "_info_struct", createClassInfoStruct()); } mb.addGlobal(classInfoStruct); Function infoFn = FunctionBuilder.infoStruct(sootClass); infoFn.add(new Ret(new ConstantBitcast(classInfoStruct.ref(), I8_PTR_PTR))); mb.addFunction(infoFn); out.write(mb.build().toString().getBytes("UTF-8")); clazz.clearDependencies(); clazz.addDependency( "java/lang/Object"); // Make sure no class or interface has zero dependencies if (sootClass.hasSuperclass() && !sootClass.isInterface()) { clazz.addDependency(getInternalName(sootClass.getSuperclass())); } for (SootClass iface : sootClass.getInterfaces()) { clazz.addDependency(getInternalName(iface)); } for (SootField f : sootClass.getFields()) { addDependencyIfNeeded(clazz, f.getType()); } for (SootMethod m : sootClass.getMethods()) { addDependencyIfNeeded(clazz, m.getReturnType()); @SuppressWarnings("unchecked") List<soot.Type> paramTypes = (List<soot.Type>) m.getParameterTypes(); for (soot.Type type : paramTypes) { addDependencyIfNeeded(clazz, type); } } clazz.addDependencies(attributesEncoder.getDependencies()); clazz.addDependencies(trampolineDependencies); clazz.addDependencies(catches); for (Trampoline t : trampolines) { if (!(t instanceof LdcString)) { String desc = t.getTarget(); if (desc.charAt(0) == 'L' || desc.charAt(0) == '[') { // Target is a descriptor addDependencyIfNeeded(clazz, desc); } else { clazz.addDependency(t.getTarget()); } } if (t instanceof FieldAccessor) { addDependencyIfNeeded(clazz, ((FieldAccessor) t).getFieldDesc()); } else if (t instanceof Invoke) { String methodDesc = ((Invoke) t).getMethodDesc(); addDependencyIfNeeded(clazz, getReturnTypeDescriptor(methodDesc)); for (String desc : getParameterDescriptors(methodDesc)) { addDependencyIfNeeded(clazz, desc); } } } clazz.saveDependencies(); }
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(); } }