Search in sources :

Example 51 with Method

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

the class ImplicitReferenceTest method testImplicitMethodLiteral.

@Test
public void testImplicitMethodLiteral() throws RecognitionException, IOException {
    ClassDef classDef = SmaliTestUtils.compileSmali("" + ".class public LHelloWorld;\n" + ".super Ljava/lang/Object;\n" + ".field public static field1:Ljava/lang/reflect/Method; = toString()V\n" + ".field public static field2:Ljava/lang/reflect/Method; = V()V\n" + ".field public static field3:Ljava/lang/reflect/Method; = I()V\n" + ".field public static field4:Ljava/lang/Class; = I");
    Map<String, Field> fields = Maps.newHashMap();
    for (Field field : classDef.getFields()) {
        fields.put(field.getName(), field);
    }
    Field field = fields.get("field1");
    Assert.assertNotNull(field);
    Assert.assertNotNull(field.getInitialValue());
    Assert.assertEquals(ValueType.METHOD, field.getInitialValue().getValueType());
    MethodEncodedValue methodEncodedValue = (MethodEncodedValue) field.getInitialValue();
    Assert.assertEquals(classDef.getType(), methodEncodedValue.getValue().getDefiningClass());
    Assert.assertEquals("toString", methodEncodedValue.getValue().getName());
    field = fields.get("field2");
    Assert.assertNotNull(field);
    Assert.assertNotNull(field.getInitialValue());
    Assert.assertEquals(ValueType.METHOD, field.getInitialValue().getValueType());
    methodEncodedValue = (MethodEncodedValue) field.getInitialValue();
    Assert.assertEquals(classDef.getType(), methodEncodedValue.getValue().getDefiningClass());
    Assert.assertEquals("V", methodEncodedValue.getValue().getName());
    field = fields.get("field3");
    Assert.assertNotNull(field);
    Assert.assertNotNull(field.getInitialValue());
    Assert.assertEquals(ValueType.METHOD, field.getInitialValue().getValueType());
    methodEncodedValue = (MethodEncodedValue) field.getInitialValue();
    Assert.assertEquals(classDef.getType(), methodEncodedValue.getValue().getDefiningClass());
    Assert.assertEquals("I", methodEncodedValue.getValue().getName());
    field = fields.get("field4");
    Assert.assertNotNull(field);
    Assert.assertNotNull(field.getInitialValue());
    Assert.assertEquals(ValueType.TYPE, field.getInitialValue().getValueType());
    TypeEncodedValue typeEncodedValue = (TypeEncodedValue) field.getInitialValue();
    Assert.assertEquals("I", typeEncodedValue.getValue());
}
Also used : Field(org.jf.dexlib2.iface.Field) ClassDef(org.jf.dexlib2.iface.ClassDef) TypeEncodedValue(org.jf.dexlib2.iface.value.TypeEncodedValue) MethodEncodedValue(org.jf.dexlib2.iface.value.MethodEncodedValue) Test(org.junit.Test)

Example 52 with Method

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

the class CallSiteTest method testBuilderCallSite.

@Test
public void testBuilderCallSite() throws IOException {
    DexBuilder dexBuilder = new DexBuilder(Opcodes.forArtVersion(111));
    BuilderCallSiteReference callSite = dexBuilder.internCallSite(new ImmutableCallSiteReference("call_site_1", new ImmutableMethodHandleReference(MethodHandleType.INVOKE_STATIC, new ImmutableMethodReference("Lcls1;", "loader", ImmutableList.of("Ljava/lang/invoke/Lookup;", "Ljava/lang/String;", "Ljava/lang/invoke/MethodType;"), "Ljava/lang/invoke/CallSite;")), "someMethod", new ImmutableMethodProtoReference(ImmutableList.of(), "V"), ImmutableList.of()));
    MethodImplementationBuilder methodImplementationBuilder = new MethodImplementationBuilder(10);
    methodImplementationBuilder.addInstruction(new BuilderInstruction35c(Opcode.INVOKE_CUSTOM, 0, 0, 0, 0, 0, 0, callSite));
    BuilderMethod method = dexBuilder.internMethod("Lcls1;", "method1", null, "V", 0, ImmutableSet.of(), ImmutableSet.of(), methodImplementationBuilder.getMethodImplementation());
    dexBuilder.internClassDef("Lcls1;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, null, ImmutableSet.of(), null, ImmutableList.of(method));
    File tempFile = File.createTempFile("dex", ".dex");
    dexBuilder.writeTo(new FileDataStore(tempFile));
    verifyDexFile(DexFileFactory.loadDexFile(tempFile, Opcodes.forArtVersion(111)));
}
Also used : ImmutableMethodProtoReference(org.jf.dexlib2.immutable.reference.ImmutableMethodProtoReference) ImmutableMethodReference(org.jf.dexlib2.immutable.reference.ImmutableMethodReference) ImmutableMethodHandleReference(org.jf.dexlib2.immutable.reference.ImmutableMethodHandleReference) BuilderInstruction35c(org.jf.dexlib2.builder.instruction.BuilderInstruction35c) BuilderMethod(org.jf.dexlib2.writer.builder.BuilderMethod) ImmutableDexFile(org.jf.dexlib2.immutable.ImmutableDexFile) File(java.io.File) DexFile(org.jf.dexlib2.iface.DexFile) FileDataStore(org.jf.dexlib2.writer.io.FileDataStore) BuilderCallSiteReference(org.jf.dexlib2.writer.builder.BuilderCallSiteReference) MethodImplementationBuilder(org.jf.dexlib2.builder.MethodImplementationBuilder) DexBuilder(org.jf.dexlib2.writer.builder.DexBuilder) ImmutableCallSiteReference(org.jf.dexlib2.immutable.reference.ImmutableCallSiteReference) Test(org.junit.Test)

Example 53 with Method

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

the class FastPatchTool method doPatch.

public void doPatch() throws IOException, PatchException, RecognitionException {
    MappingReader mappingReader = null;
    MappingProcessor mappingProcessor = null;
    if (outDir == null || !outDir.exists()) {
        return;
    }
    outPatchFile = new File(outDir, "apatch-unsigned.apatch");
    if (mappingFile != null && mappingFile.exists()) {
        mappingReader = new MappingReader(mappingFile);
        mappingProcessor = new MappingProcessorImpl(superClassMap);
        mappingReader.pump(mappingProcessor);
        mappingProcessor.updateMethod();
        mappingProcessor.updateFieldType();
    }
    for (FastPatchObject fastPatchObject : patchObjects) {
        Set<ClassDef> classes = new HashSet<ClassDef>();
        Map<ClassDef, List<Method>> patchClassDefs = new HashMap<ClassDef, List<Method>>();
        Set<ClassDef> addedClasses = new HashSet<ClassDef>();
        Map<ClassDef, List<Method>> newClassDef = new HashMap<ClassDef, List<Method>>();
        ArrayList<Method> methods = new ArrayList<Method>();
        for (File dexFile : fastPatchObject.DexFiles) {
            DexFile dFile = DexFileFactory.loadDexFile(dexFile.getAbsolutePath(), 19, true);
            classes.addAll(dFile.getClasses());
        }
        final Set<ClassDef> newClasses = new HashSet<ClassDef>();
        for (ClassDef classDef : classes) {
            String type = classDef.getType();
            if (fastPatchObject.addedClass.contains(SmaliUtils.getDalvikClassName(type))) {
                System.out.println("patch added class:" + type);
                addedClasses.add(classDef);
                continue;
            }
            for (Map.Entry<String, List<String>> entry : fastPatchObject.modifyClasses.entrySet()) {
                if (entry.getKey().equals(SmaliUtils.getDalvikClassName(type))) {
                    ArrayList<Method> newMethods = new ArrayList<Method>();
                    for (Method method : classDef.getMethods()) {
                        System.err.println(getMethodFullName(method));
                        if (entry.getValue().contains(getMethodFullName(method))) {
                            newMethods.add(method);
                        }
                    }
                    patchClassDefs.put(classDef, newMethods);
                    break;
                }
            }
        }
        if (patchClassDefs.size() == 0 && addedClasses.size() == 0) {
            continue;
        }
        if (mappingFile != null && mappingFile.exists()) {
            //第一步先将prepareclass混淆掉
            for (String className : fastPatchObject.prepareClasses) {
                ApkPatch.prepareClasses.add(mappingProcessor.getNewClassName(className).className);
            }
            //将replaceanatation混淆掉
            MethodReplaceAnnotation.ANNOTATION = DefineUtils.getDefineClassName(mappingProcessor.getNewClassName(DefineUtils.getDalvikClassName("Lcom/alipay/euler/andfix/annotation/MethodReplace;")).className, false);
            //将dex代码混淆掉
            InsTructionsReIClassDef insTructionsReDef = new InsTructionsReIClassDef(new MappingClassProcessor(mappingProcessor));
            for (ClassDef c : classes) {
                if (patchClassDefs.containsKey(c)) {
                    for (Method method : c.getMethods()) {
                        if (patchClassDefs.get(c).contains(method)) {
                            methods.add(insTructionsReDef.reMethod(method));
                        }
                    }
                    newClassDef.put(insTructionsReDef.reClassDef(c), methods);
                } else if (addedClasses.contains(c)) {
                    newClassDef.put(insTructionsReDef.reClassDef(c), new ArrayList<Method>());
                }
                if (c.getType().contains("/R$")) {
                    continue;
                }
                newClasses.add(insTructionsReDef.reClassDef(c));
            }
        } else {
            ApkPatch.prepareClasses.addAll(fastPatchObject.prepareClasses);
        }
        File patchDexFile = new File(outDir, "patch.dex");
        for (ClassDef classDef : newClassDef.keySet()) {
            System.out.println("modify class:" + classDef.getType());
        }
        if (newClassDef.size() > 0) {
            DexFileFactory.writeDexFile(patchDexFile.getAbsolutePath(), new ImmutableDexFile(newClassDef.keySet()));
        } else if (patchClassDefs.size() > 0) {
            DexFileFactory.writeDexFile(patchDexFile.getAbsolutePath(), new ImmutableDexFile(patchClassDefs.keySet()));
        }
        File tempDexFile = new File(outDir, "temp.dex");
        if (newClasses.size() > 0) {
            DexFileFactory.writeDexFile(tempDexFile.getAbsolutePath(), new DexFile() {

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

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

                        @Override
                        public int size() {
                            return newClasses.size();
                        }
                    };
                }
            });
        } else if (classes.size() > 0) {
            DexFileFactory.writeDexFile(tempDexFile.getAbsolutePath(), new ImmutableDexFile(classes));
        }
        SmaliDiffUtils.scanClasses(new File(outDir, "smali2"), Lists.newArrayList(tempDexFile));
        DexFile patchDex = DexFileFactory.loadDexFile(patchDexFile.getAbsolutePath(), 19, true);
        DexFile tempDex = DexFileFactory.loadDexFile(tempDexFile.getAbsolutePath(), 19, true);
        Set<? extends ClassDef> patchClasses = patchDex.getClasses();
        DexDiffInfo dexDiffInfo = new DexDiffInfo();
        for (ClassDef patchClassDef : patchClasses) {
            String type = patchClassDef.getType();
            if (fastPatchObject.addedClass.contains(SmaliUtils.getDalvikClassName(type))) {
                dexDiffInfo.getAddedClasses().add((DexBackedClassDef) patchClassDef);
                dexDiffInfo.addManifestAddClass(type);
                continue;
            }
            for (Method method : patchClassDef.getMethods()) {
                List<? extends CharSequence> parameters = method.getParameterTypes();
                if (methods.size() > 0) {
                    for (Method modifyMethod : methods) {
                        List<? extends CharSequence> modifyParameters = modifyMethod.getParameterTypes();
                        if (parameters.size() != modifyParameters.size() || !isEqualObj(parameters, modifyParameters)) {
                            continue;
                        }
                        if (modifyMethod.getName().equals(method.getName()))
                            dexDiffInfo.addModifiedMethods((DexBackedMethod) method);
                    }
                } else if (patchClassDefs.size() > 0) {
                    for (ClassDef classDef : patchClassDefs.keySet()) {
                        if (classDef.getType().equals(patchClassDef.getType())) {
                            List<Method> methodList = patchClassDefs.get(classDef);
                            for (Method method1 : methodList) {
                                if (method1.getName().equals(method.getName())) {
                                    dexDiffInfo.addModifiedMethods((DexBackedMethod) method);
                                }
                            }
                        }
                    }
                }
            }
        }
        FastBuild fastBuild = new FastBuild(fastPatchObject.bundleName, new File(outDir, bundleName));
        fastBuild.setClasses(tempDex.getClasses());
        fastBuild.setDiffInfo(dexDiffInfo);
        new AndFixFilterImpl(dexDiffInfo).filterDex();
        dexDiffInfo.update();
        APatchTool.isApatch = true;
        File adiffFile = new File(outDir, "apatch-diff.txt");
        File adiffJsonFile = new File(outDir, "apatch-diff.json");
        dexDiffInfo.writeToFile(fastPatchObject.bundleName, adiffFile, adiffJsonFile);
        try {
            File patchJarFile = fastBuild.dopatch();
            patchJarFiles.add(patchJarFile);
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (UnrecoverableEntryException e) {
            e.printStackTrace();
        }
    }
    File[] aPatchFiles = new File[patchJarFiles.size()];
    aPatchFiles = patchJarFiles.toArray(aPatchFiles);
    File mergePatchFile = null;
    if (null != aPatchFiles && aPatchFiles.length > 1) {
        MergePatch mergePatch = new MergePatch(aPatchFiles, "com_taobao_android", outDir);
        mergePatchFile = mergePatch.doMerge();
    } else if (null != aPatchFiles && aPatchFiles.length == 1) {
        mergePatchFile = aPatchFiles[0];
    }
    if (null != mergePatchFile && mergePatchFile.exists()) {
        FileUtils.moveFile(mergePatchFile, outPatchFile);
    }
}
Also used : DexBackedMethod(org.jf.dexlib2.dexbacked.DexBackedMethod) CertificateException(java.security.cert.CertificateException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) DexBackedClassDef(org.jf.dexlib2.dexbacked.DexBackedClassDef) InsTructionsReIClassDef(com.taobao.android.repatch.InsTructionsReIClassDef) ClassDef(org.jf.dexlib2.iface.ClassDef) MappingReader(com.taobao.android.repatch.mapping.MappingReader) UnrecoverableEntryException(java.security.UnrecoverableEntryException) Nonnull(javax.annotation.Nonnull) AndFixFilterImpl(com.taobao.android.apatch.AndFixFilterImpl) MappingClassProcessor(com.taobao.android.repatch.processor.MappingClassProcessor) Method(org.jf.dexlib2.iface.Method) DexBackedMethod(org.jf.dexlib2.dexbacked.DexBackedMethod) KeyStoreException(java.security.KeyStoreException) FastBuild(com.taobao.android.apatch.FastBuild) ImmutableDexFile(org.jf.dexlib2.immutable.ImmutableDexFile) DexFile(org.jf.dexlib2.iface.DexFile) DexDiffInfo(com.taobao.android.object.DexDiffInfo) FastPatchObject(com.taobao.android.repatch.FastPatchObject) MappingProcessor(com.taobao.android.repatch.mapping.MappingProcessor) MappingProcessorImpl(com.taobao.android.repatch.mapping.MappingProcessorImpl) InsTructionsReIClassDef(com.taobao.android.repatch.InsTructionsReIClassDef) ImmutableDexFile(org.jf.dexlib2.immutable.ImmutableDexFile) File(java.io.File) DexFile(org.jf.dexlib2.iface.DexFile) ImmutableDexFile(org.jf.dexlib2.immutable.ImmutableDexFile) MergePatch(com.taobao.android.apatch.MergePatch)

Example 54 with Method

use of org.jf.dexlib2.iface.Method 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, 15, true);
    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();
                }
            };
        }
    });
}
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) Iterator(java.util.Iterator)

Example 55 with Method

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

the class MethodDefinition method writeEmptyMethodTo.

public static void writeEmptyMethodTo(IndentingWriter writer, Method method, baksmaliOptions options) throws IOException {
    writer.write(".method ");
    writeAccessFlags(writer, method.getAccessFlags());
    writer.write(method.getName());
    writer.write("(");
    ImmutableList<MethodParameter> methodParameters = ImmutableList.copyOf(method.getParameters());
    for (MethodParameter parameter : methodParameters) {
        writer.write(parameter.getType());
    }
    writer.write(")");
    writer.write(method.getReturnType());
    writer.write('\n');
    writer.indent(4);
    writeParameters(writer, method, methodParameters, options);
    String containingClass = null;
    if (options.useImplicitReferences) {
        containingClass = method.getDefiningClass();
    }
    //如果是修改的方法,需要添加ReplaceAnnotation
    if (DexDiffInfo.modifiedMethods.contains(method)) {
        MethodReplaceAnnotation replaceAnnotation = new MethodReplaceAnnotation(method.getDefiningClass(), method.getName());
        AnnotationFormatter.writeTo(writer, method.getAnnotations(), containingClass, replaceAnnotation);
    } else {
        AnnotationFormatter.writeTo(writer, method.getAnnotations(), containingClass);
    }
    writer.deindent(4);
    writer.write(".end method\n");
}
Also used : MethodReplaceAnnotation(com.taobao.android.apatch.annotation.MethodReplaceAnnotation) MethodParameter(org.jf.dexlib2.iface.MethodParameter)

Aggregations

Method (org.jf.dexlib2.iface.Method)30 ClassDef (org.jf.dexlib2.iface.ClassDef)27 MethodImplementation (org.jf.dexlib2.iface.MethodImplementation)23 Test (org.junit.Test)21 Instruction (org.jf.dexlib2.iface.instruction.Instruction)19 MethodReference (org.jf.dexlib2.iface.reference.MethodReference)18 DexFile (org.jf.dexlib2.iface.DexFile)16 ImmutableMethod (org.jf.dexlib2.immutable.ImmutableMethod)15 DexBackedClassDef (org.jf.dexlib2.dexbacked.DexBackedClassDef)13 ArrayList (java.util.ArrayList)12 ImmutableClassDef (org.jf.dexlib2.immutable.ImmutableClassDef)12 MutableMethodImplementation (org.jf.dexlib2.builder.MutableMethodImplementation)10 ImmutableDexFile (org.jf.dexlib2.immutable.ImmutableDexFile)10 HashSet (java.util.HashSet)9 Nonnull (javax.annotation.Nonnull)9 BuilderInstruction10x (org.jf.dexlib2.builder.instruction.BuilderInstruction10x)8 ReferenceInstruction (org.jf.dexlib2.iface.instruction.ReferenceInstruction)8 ImmutableMethodParameter (org.jf.dexlib2.immutable.ImmutableMethodParameter)8 ImmutableMethodReference (org.jf.dexlib2.immutable.reference.ImmutableMethodReference)8 File (java.io.File)7