public void hookSuperclass(HookMap hooks, ClassDefItem classDef) { HookItem oldTarget = HookItem.getInstance(classDef.getSuperclass()); if (oldTarget == null) { return; } if (!hooks.containsKey(oldTarget)) { return; } TypeIdItem newTarget = (TypeIdItem) hooks.get(oldTarget); assert (newTarget != null); if (newTarget == classDef.getClassType()) { return; } classDef.setSuperclass(newTarget); HookClass classType = new HookClass(classDef.getClassType()); if (hooks.mIgnoreMethods.contains(classType)) { return; } if (hooks.mDead.isEmpty()) { return; } // get rid of virtual methods so the hooked class method is called instead String className = newTarget.getTypeDescriptor(); List<EncodedMethod> newDirects = new LinkedList<EncodedMethod>(); List<EncodedMethod> newVirtuals = new LinkedList<EncodedMethod>(); ClassDataItem classData = classDef.getClassData(); for (EncodedMethod encodedMethod : classData.getDirectMethods()) { newDirects.add(encodedMethod); } for (EncodedMethod encodedMethod : classData.getVirtualMethods()) { HookMethod method = new HookMethod(encodedMethod.method); method.mClasspath = className; if (!hooks.mDead.contains(method)) { newVirtuals.add(encodedMethod); } } classData.update(newDirects, newVirtuals); }
public void caseClassConstant(ClassConstant c) { // "array class" types are unmodified boolean classIsArray = c.value.startsWith("["); String className = classIsArray ? c.value : SootToDexUtils.getDexClassName(c.value); TypeIdItem referencedClass = TypeIdItem.internTypeIdItem(stmtV.getBelongingFile(), className); stmtV.addInsn(new Insn21c(Opcode.CONST_CLASS, destinationReg, referencedClass)); }
private void initClassMaps() { mClasses = new HashMap<HookClass, TypeIdItem>(); mClassMethods = new HashMap<HookClass, HashSet<EncodedMethod>>(); mSubclasses = new HashMap<String, Set<String>>(); for (ClassDefItem item : mDexFile.ClassDefsSection.getItems()) { TypeIdItem classType = item.getClassType(); HookClass classHook = new HookClass(classType); mClasses.put(classHook, classType); String superclassType = item.getSuperclass().getTypeDescriptor(); Set<String> subclassSet = mSubclasses.get(superclassType); if (subclassSet == null) { subclassSet = new TreeSet<String>(); mSubclasses.put(superclassType, subclassSet); } subclassSet.add(classType.getTypeDescriptor()); ClassDataItem classData = item.getClassData(); if (classData == null) { continue; } HashSet<EncodedMethod> classMethods = new HashSet<EncodedMethod>(); for (EncodedMethod method : classData.getDirectMethods()) { classMethods.add(method); } for (EncodedMethod method : classData.getVirtualMethods()) { classMethods.add(method); } mClassMethods.put(classHook, classMethods); } }
protected static void writeStartLocal( IndentingWriter writer, CodeItem codeItem, int register, StringIdItem name, TypeIdItem type, StringIdItem signature) throws IOException { writer.write(".local "); RegisterFormatter.writeTo(writer, codeItem, register); writer.write(", "); writer.write(name.getStringValue()); writer.write(':'); writer.write(type.getTypeDescriptor()); if (signature != null) { writer.write(",\""); writer.write(signature.getStringValue()); writer.write('"'); } }
public HookClass(TypeIdItem item) { mClasspath = item.getTypeDescriptor(); }