public static String getDescriptor(soot.Type t) { if (t instanceof PrimType) { if (t.equals(BooleanType.v())) { return "Z"; } else if (t.equals(ByteType.v())) { return "B"; } else if (t.equals(ShortType.v())) { return "S"; } else if (t.equals(CharType.v())) { return "C"; } else if (t.equals(IntType.v())) { return "I"; } else if (t.equals(LongType.v())) { return "J"; } else if (t.equals(FloatType.v())) { return "F"; } else { // DoubleType return "D"; } } else if (t.equals(VoidType.v())) { return "V"; } else if (t instanceof soot.ArrayType) { soot.ArrayType at = (soot.ArrayType) t; return "[" + getDescriptor(at.getElementType()); } else { // RefType RefType rt = (RefType) t; return "L" + rt.getClassName().replace('.', '/') + ";"; } }
public void outAFullIdentNonvoidType(AFullIdentNonvoidType node) { String typeName = (String) mProductions.removeLast(); Type t = RefType.v(typeName); int dim = node.getArrayBrackets().size(); if (dim > 0) t = ArrayType.v(t, dim); mProductions.addLast(t); }
public void type(Type t) { handleIndent(); if (t instanceof RefType) { String name = ((RefType) t).getSootClass().getJavaStyleName(); /* * March 30th 2006, Nomair * Adding check to check that the fully qualified name can actually be removed */ if (!name.equals(((RefType) t).getSootClass().toString())) { // means javaStyle name is probably shorter check that there is no class clash in imports // for this // System.out.println(">>>>Type is"+t.toString()); // System.out.println(">>>>Name is"+name); name = RemoveFullyQualifiedName.getReducedName( body.getImportList(), ((RefType) t).getSootClass().toString(), t); } output.append(name); } else if (t instanceof ArrayType) { ((ArrayType) t).toString(this); } else { output.append(t.toString()); } }
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; }
private Type getSootType(AnnotationElem e) { Type annotationType; switch (e.getKind()) { case '[': // array // Until now we only know it's some kind of array. annotationType = ARRAY_TYPE; AnnotationArrayElem array = (AnnotationArrayElem) e; if (array.getNumValues() > 0) { // Try to determine type of the array AnnotationElem firstElement = array.getValueAt(0); Type type = getSootType(firstElement); if (type == null) return null; if (type.equals(ARRAY_TYPE)) return ARRAY_TYPE; return ArrayType.v(type, 1); } break; case 's': // string annotationType = RefType.v("java.lang.String"); break; case 'c': // class annotationType = RefType.v("java.lang.Class"); break; case 'e': // enum AnnotationEnumElem enumElem = (AnnotationEnumElem) e; annotationType = Util.getType(enumElem.getTypeName()); ; break; case 'L': case 'J': case 'S': case 'D': case 'I': case 'F': case 'B': case 'C': case 'V': case 'Z': annotationType = Util.getType(String.valueOf(e.getKind())); break; default: annotationType = null; break; } return annotationType; }
private Type fixType(Type type) { if (type instanceof RefType) { RefType ref_type = (RefType) type; SootClass soot_class = ref_type.getSootClass(); if (shouldMap(soot_class)) { SootClass new_class = getMapping(soot_class); return new_class.getType(); } else { return type; } } else if (type instanceof ArrayType) { ArrayType array_type = (ArrayType) type; Type base = fixType(array_type.baseType); return ArrayType.v(base, array_type.numDimensions); } else { return type; } }
public void outAMultiNewExpr(AMultiNewExpr node) { LinkedList arrayDesc = node.getArrayDescriptor(); int descCnt = arrayDesc.size(); List sizes = new LinkedList(); Iterator it = arrayDesc.iterator(); while (it.hasNext()) { AArrayDescriptor o = (AArrayDescriptor) it.next(); if (o.getImmediate() != null) sizes.add(0, (Value) mProductions.removeLast()); else break; } Type type = (Type) mProductions.removeLast(); ArrayType arrayType = ArrayType.v(type, descCnt); mProductions.addLast(Jimple.v().newNewMultiArrayExpr(arrayType, sizes)); }
public void fixFields() { Iterator<SootField> iter = m_fieldsToFix.keySet().iterator(); while (iter.hasNext()) { SootField curr = iter.next(); SootClass soot_class = curr.getDeclaringClass(); SootField orig = curr; SootClass field_cls = curr.getDeclaringClass(); if (shouldMap(field_cls)) { SootClass new_field_cls = getMapping(field_cls); curr = new_field_cls.getFieldByName(curr.getName()); } Type type = curr.getType(); if (type instanceof RefType) { RefType ref_type = (RefType) type; if (shouldMap(ref_type.getSootClass())) { SootClass new_class = getMapping(ref_type.getSootClass()); curr.setType(new_class.getType()); } } else if (type instanceof ArrayType) { ArrayType array_type = (ArrayType) type; if (array_type.baseType instanceof RefType == false) { continue; } RefType ref_type = (RefType) array_type.baseType; if (shouldMap(ref_type.getSootClass())) { SootClass new_class = getMapping(ref_type.getSootClass()); ArrayType new_type = ArrayType.v(new_class.getType(), array_type.numDimensions); curr.setType(new_type); } } List<FieldRef> refs = m_fieldsToFix.get(orig); for (FieldRef ref : refs) { ref.setFieldRef(curr.makeRef()); } } }
private NumericConstant getArrayElement(Number element, DexBody body, int arrayRegister) { List<DexlibAbstractInstruction> instructions = body.instructionsBefore(this); Set<Integer> usedRegisters = new HashSet<Integer>(); usedRegisters.add(arrayRegister); Type elementType = null; Outer: for (DexlibAbstractInstruction i : instructions) { if (usedRegisters.isEmpty()) break; for (int reg : usedRegisters) if (i instanceof NewArrayInstruction) { NewArrayInstruction newArrayInstruction = (NewArrayInstruction) i; Instruction22c instruction22c = (Instruction22c) newArrayInstruction.instruction; if (instruction22c.getRegisterA() == reg) { ArrayType arrayType = (ArrayType) DexType.toSoot((TypeReference) instruction22c.getReference()); elementType = arrayType.getElementType(); break Outer; } } // // look for obsolete registers // for (int reg : usedRegisters) { // if (i.overridesRegister(reg)) { // usedRegisters.remove(reg); // break; // there can't be more than one obsolete // } // } // look for new registers for (int reg : usedRegisters) { int newRegister = i.movesToRegister(reg); if (newRegister != -1) { usedRegisters.add(newRegister); usedRegisters.remove(reg); break; // there can't be more than one new } } } if (elementType == null) { // throw new InternalError("Unable to find array type to type array elements!"); G.v() .out .println( "Warning: Unable to find array type to type array elements! Array was not defined! (obfuscated bytecode?)"); return null; } NumericConstant value; if (elementType instanceof BooleanType) { value = IntConstant.v(element.intValue()); IntConstant ic = (IntConstant) value; if (!(ic.value == 0 || ic.value == 1)) { throw new RuntimeException("ERROR: Invalid value for boolean: " + value); } } else if (elementType instanceof ByteType) { value = IntConstant.v(element.byteValue()); } else if (elementType instanceof CharType || elementType instanceof ShortType) { value = IntConstant.v(element.shortValue()); } else if (elementType instanceof DoubleType) { value = DoubleConstant.v(Double.longBitsToDouble(element.longValue())); } else if (elementType instanceof FloatType) { value = FloatConstant.v(Float.intBitsToFloat(element.intValue())); } else if (elementType instanceof IntType) { value = IntConstant.v(element.intValue()); } else if (elementType instanceof LongType) { value = LongConstant.v(element.longValue()); } else { throw new RuntimeException( "Invalid Array Type occured in FillArrayDataInstruction: " + elementType); } Debug.printDbg("array element: ", value); return value; }
/* nonvoid_type = {base} base_type_no_name array_brackets*; {quoted} quoted_name array_brackets* | {ident} identifier array_brackets* | {full_ident} full_identifier array_brackets*; */ public void outABaseNonvoidType(ABaseNonvoidType node) { Type t = (Type) mProductions.removeLast(); int dim = node.getArrayBrackets().size(); if (dim > 0) t = ArrayType.v(t, dim); mProductions.addLast(t); }
public void caseArrayType(ArrayType soottype) { soottype.getElementType().apply(this); }
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(); } }
private Type getParameterArrayType() { Type parameterArrayType = RefType.v("java.lang.Object"); Type parameterArray = ArrayType.v(parameterArrayType, 1); return parameterArray; }
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; } }