Search in sources :

Example 41 with MethodImplementation

use of org.jf.dexlib2.iface.MethodImplementation in project smali by JesusFreke.

the class ClassDefinition method writeDirectMethods.

private Set<String> writeDirectMethods(BaksmaliWriter writer) throws IOException {
    boolean wroteHeader = false;
    Set<String> writtenMethods = new HashSet<String>();
    Iterable<? extends Method> directMethods;
    if (classDef instanceof DexBackedClassDef) {
        directMethods = ((DexBackedClassDef) classDef).getDirectMethods(false);
    } else {
        directMethods = classDef.getDirectMethods();
    }
    for (Method method : directMethods) {
        if (!wroteHeader) {
            writer.write("\n\n");
            writer.write("# direct methods");
            wroteHeader = true;
        }
        writer.write('\n');
        // TODO: check for method validation errors
        String methodString = formatter.getShortMethodDescriptor(method);
        BaksmaliWriter methodWriter = writer;
        if (!writtenMethods.add(methodString)) {
            writer.write("# duplicate method ignored\n");
            methodWriter = getCommentingWriter(writer);
        }
        MethodImplementation methodImpl = method.getImplementation();
        if (methodImpl == null) {
            MethodDefinition.writeEmptyMethodTo(methodWriter, method, this);
        } else {
            MethodDefinition methodDefinition = new MethodDefinition(this, method, methodImpl);
            methodDefinition.writeTo(methodWriter);
        }
    }
    return writtenMethods;
}
Also used : BaksmaliWriter(org.jf.baksmali.formatter.BaksmaliWriter) DexBackedClassDef(org.jf.dexlib2.dexbacked.DexBackedClassDef) HashSet(java.util.HashSet)

Example 42 with MethodImplementation

use of org.jf.dexlib2.iface.MethodImplementation in project atlas by alibaba.

the class ClassDefinition method writeVirtualMethods.

private void writeVirtualMethods(IndentingWriter writer, Set<String> directMethods) throws IOException {
    boolean wroteHeader = false;
    Set<String> writtenMethods = new HashSet<String>();
    Iterable<? extends Method> virtualMethods;
    Set<? extends Method> modifieds = null;
    if (classDef instanceof DexBackedClassDef) {
        virtualMethods = ((DexBackedClassDef) classDef).getVirtualMethods(false);
        modifieds = (Set<? extends Method>) DexDiffInfo.modifiedMethods;
    } else {
        virtualMethods = classDef.getVirtualMethods();
    }
    MethodReplaceAnnotation replaceAnnotaion;
    for (Method method : virtualMethods) {
        if (!fullMethod && !DexDiffInfo.addedClasses.contains(classDef)) {
            if (!modifieds.contains(method) && !DexDiffInfo.addedMethods.contains(method)) {
                continue;
            }
        }
        if (!wroteHeader) {
            writer.write("\n\n");
            writer.write("# virtual methods");
            wroteHeader = true;
        }
        writer.write('\n');
        // TODO: check for method validation errors
        String methodString = ReferenceUtil.getMethodDescriptor(method, true);
        IndentingWriter methodWriter = writer;
        if (!writtenMethods.add(methodString)) {
            writer.write("# duplicate method ignored\n");
            methodWriter = new CommentingIndentingWriter(writer);
        } else if (directMethods.contains(methodString)) {
            writer.write("# There is both a direct and virtual method with this signature.\n" + "# You will need to rename one of these methods, including all references.\n");
            System.err.println(String.format("Duplicate direct+virtual method found: %s->%s", classDef.getType(), methodString));
            System.err.println("You will need to rename one of these methods, including all references.");
        }
        MethodImplementation methodImpl = method.getImplementation();
        if (methodImpl == null) {
            MethodDefinition.writeEmptyMethodTo(methodWriter, method, options);
        } else {
            MethodDefinition methodDefinition = new MethodDefinition(this, method, methodImpl);
            methodDefinition.writeTo(methodWriter);
        }
    }
}
Also used : MethodImplementation(org.jf.dexlib2.iface.MethodImplementation) Method(org.jf.dexlib2.iface.Method) MethodReplaceAnnotation(com.taobao.android.apatch.annotation.MethodReplaceAnnotation) IndentingWriter(org.jf.util.IndentingWriter) DexBackedClassDef(org.jf.dexlib2.dexbacked.DexBackedClassDef) HashSet(java.util.HashSet)

Example 43 with MethodImplementation

use of org.jf.dexlib2.iface.MethodImplementation in project atlas by alibaba.

the class ClassDefinition method writeDirectMethods.

private Set<String> writeDirectMethods(IndentingWriter writer) throws IOException {
    boolean wroteHeader = false;
    Set<String> writtenMethods = new HashSet<String>();
    Iterable<? extends Method> directMethods;
    Set<? extends Method> modifieds = null;
    if (classDef instanceof DexBackedClassDef) {
        directMethods = ((DexBackedClassDef) classDef).getDirectMethods(false);
        modifieds = (Set<? extends Method>) DexDiffInfo.modifiedMethods;
    } else {
        directMethods = classDef.getDirectMethods();
    }
    MethodReplaceAnnotation replaceAnnotaion;
    for (Method method : directMethods) {
        if (!fullMethod && !DexDiffInfo.addedClasses.contains(classDef)) {
            if (!modifieds.contains(method) && !DexDiffInfo.addedMethods.contains(method)) {
                continue;
            }
        }
        if (!wroteHeader) {
            writer.write("\n\n");
            writer.write("# direct methods");
            wroteHeader = true;
        }
        writer.write('\n');
        // TODO: check for method validation errors
        String methodString = ReferenceUtil.getMethodDescriptor(method, true);
        IndentingWriter methodWriter = writer;
        if (!writtenMethods.add(methodString)) {
            writer.write("# duplicate method ignored\n");
            methodWriter = new CommentingIndentingWriter(writer);
        }
        MethodImplementation methodImpl = method.getImplementation();
        if (methodImpl == null) {
            MethodDefinition.writeEmptyMethodTo(methodWriter, method, options);
        } else {
            MethodDefinition methodDefinition = new MethodDefinition(this, method, methodImpl);
            methodDefinition.setFullMethod(fullMethod);
            methodDefinition.writeTo(methodWriter);
        }
    }
    return writtenMethods;
}
Also used : MethodImplementation(org.jf.dexlib2.iface.MethodImplementation) Method(org.jf.dexlib2.iface.Method) MethodReplaceAnnotation(com.taobao.android.apatch.annotation.MethodReplaceAnnotation) IndentingWriter(org.jf.util.IndentingWriter) DexBackedClassDef(org.jf.dexlib2.dexbacked.DexBackedClassDef) HashSet(java.util.HashSet)

Example 44 with MethodImplementation

use of org.jf.dexlib2.iface.MethodImplementation in project atlas by alibaba.

the class PatchFieldTool method reDexMethods.

private static List<Method> reDexMethods(@Nonnull ClassDef classDef) {
    List<Method> taintedMethods = Lists.newArrayList();
    for (Method method : classDef.getMethods()) {
        MethodImplementation implementation = method.getImplementation();
        MutableMethodImplementation mutableImplementation = new MutableMethodImplementation(implementation);
        taintedMethods.add(new ImmutableMethod(method.getDefiningClass(), method.getName(), method.getParameters(), method.getReturnType(), method.getAccessFlags(), method.getAnnotations(), mutableImplementation));
    }
    return taintedMethods;
}
Also used : MutableMethodImplementation(org.jf.dexlib2.builder.MutableMethodImplementation) ImmutableMethod(org.jf.dexlib2.immutable.ImmutableMethod) MutableMethodImplementation(org.jf.dexlib2.builder.MutableMethodImplementation) ImmutableMethod(org.jf.dexlib2.immutable.ImmutableMethod)

Example 45 with MethodImplementation

use of org.jf.dexlib2.iface.MethodImplementation in project atlas by alibaba.

the class PatchMethodTool method modifyMethod.

public static void modifyMethod(String srcDexFile, String outDexFile, boolean isAndFix) throws IOException {
    DexFile dexFile = DexFileFactory.loadDexFile(srcDexFile, Opcodes.getDefault());
    final Set<ClassDef> classes = Sets.newConcurrentHashSet();
    for (ClassDef classDef : dexFile.getClasses()) {
        Set<Method> methods = Sets.newConcurrentHashSet();
        boolean modifiedMethod = false;
        for (Method method : classDef.getMethods()) {
            MethodImplementation implementation = method.getImplementation();
            if (implementation != null && (methodNeedsModification(classDef, method, isAndFix))) {
                modifiedMethod = true;
                methods.add(new ImmutableMethod(method.getDefiningClass(), method.getName(), method.getParameters(), method.getReturnType(), method.getAccessFlags(), method.getAnnotations(), isAndFix ? modifyMethodAndFix(implementation, method) : modifyMethodTpatch(implementation, method)));
            } else {
                methods.add(method);
            }
        }
        if (!modifiedMethod) {
            classes.add(classDef);
        } else {
            classes.add(new ImmutableClassDef(classDef.getType(), classDef.getAccessFlags(), classDef.getSuperclass(), classDef.getInterfaces(), classDef.getSourceFile(), classDef.getAnnotations(), classDef.getFields(), methods));
        }
    }
    DexFileFactory.writeDexFile(outDexFile, new DexFile() {

        @Nonnull
        @Override
        public Set<? extends ClassDef> getClasses() {
            return new AbstractSet<ClassDef>() {

                @Nonnull
                @Override
                public Iterator<ClassDef> iterator() {
                    return classes.iterator();
                }

                @Override
                public int size() {
                    return classes.size();
                }
            };
        }

        @Nonnull
        @Override
        public Opcodes getOpcodes() {
            return Opcodes.getDefault();
        }
    });
}
Also used : MutableMethodImplementation(org.jf.dexlib2.builder.MutableMethodImplementation) MethodImplementation(org.jf.dexlib2.iface.MethodImplementation) ImmutableMethod(org.jf.dexlib2.immutable.ImmutableMethod) AbstractSet(java.util.AbstractSet) Set(java.util.Set) ImmutableClassDef(org.jf.dexlib2.immutable.ImmutableClassDef) Nonnull(javax.annotation.Nonnull) ImmutableMethod(org.jf.dexlib2.immutable.ImmutableMethod) Method(org.jf.dexlib2.iface.Method) DexFile(org.jf.dexlib2.iface.DexFile) DexBackedClassDef(org.jf.dexlib2.dexbacked.DexBackedClassDef) ImmutableClassDef(org.jf.dexlib2.immutable.ImmutableClassDef) ClassDef(org.jf.dexlib2.iface.ClassDef) Opcodes(org.jf.dexlib2.Opcodes) Iterator(java.util.Iterator)

Aggregations

MethodImplementation (org.jf.dexlib2.iface.MethodImplementation)29 Test (org.junit.Test)18 Method (org.jf.dexlib2.iface.Method)17 BuilderInstruction10x (org.jf.dexlib2.builder.instruction.BuilderInstruction10x)13 ClassDef (org.jf.dexlib2.iface.ClassDef)12 Instruction (org.jf.dexlib2.iface.instruction.Instruction)12 DexFile (org.jf.dexlib2.iface.DexFile)11 ImmutableMethod (org.jf.dexlib2.immutable.ImmutableMethod)11 MutableMethodImplementation (org.jf.dexlib2.builder.MutableMethodImplementation)9 MethodImplementationBuilder (org.jf.dexlib2.builder.MethodImplementationBuilder)8 DexBackedClassDef (org.jf.dexlib2.dexbacked.DexBackedClassDef)8 ImmutableClassDef (org.jf.dexlib2.immutable.ImmutableClassDef)8 ImmutableMethodParameter (org.jf.dexlib2.immutable.ImmutableMethodParameter)7 HashSet (java.util.HashSet)6 BuilderInstruction21c (org.jf.dexlib2.builder.instruction.BuilderInstruction21c)6 BuilderInstruction21t (org.jf.dexlib2.builder.instruction.BuilderInstruction21t)6 BuilderInstruction22c (org.jf.dexlib2.builder.instruction.BuilderInstruction22c)6 ReferenceInstruction (org.jf.dexlib2.iface.instruction.ReferenceInstruction)6 ImmutableDexFile (org.jf.dexlib2.immutable.ImmutableDexFile)6 ImmutableTypeReference (org.jf.dexlib2.immutable.reference.ImmutableTypeReference)6