Search in sources :

Example 1 with DexBackedMethod

use of org.jf.dexlib2.dexbacked.DexBackedMethod in project atlas by alibaba.

the class ApkPatch method getMethodAnnotaionPrepareClasses.

public static void getMethodAnnotaionPrepareClasses(DexDiffInfo dexDiffInfo, Set<String> prepareclasses) {
    for (DexBackedMethod method : dexDiffInfo.getModifiedMethods()) {
        Set<? extends Annotation> annotations = method.getAnnotations();
        if (annotations == null) {
            continue;
        }
        for (Annotation annotation : annotations) {
            String type = annotation.getType();
            if (type != null && type.startsWith("L") && type.endsWith(";")) {
                prepareclasses.add(type.substring(1, type.length() - 1).replace('/', '.'));
                System.out.println("prepare class: " + type);
            }
            Set<? extends AnnotationElement> elements = annotation.getElements();
            for (AnnotationElement dexBackedAnnotationElement : elements) {
                if (dexBackedAnnotationElement.getValue() instanceof DexBackedArrayEncodedValue) {
                    List<? extends EncodedValue> values = ((DexBackedArrayEncodedValue) dexBackedAnnotationElement.getValue()).getValue();
                    for (EncodedValue encodedValue : values) {
                        if (encodedValue instanceof TypeEncodedValue) {
                            prepareclasses.add(((TypeEncodedValue) encodedValue).getValue().substring(1, ((TypeEncodedValue) encodedValue).getValue().length() - 1).replace('/', '.'));
                            System.out.println("prepare class: " + ((TypeEncodedValue) encodedValue).getValue());
                        }
                    }
                } else if (dexBackedAnnotationElement.getValue() instanceof DexBackedTypeEncodedValue) {
                    String value = ((DexBackedTypeEncodedValue) dexBackedAnnotationElement.getValue()).getValue();
                    prepareclasses.add(value.substring(1, value.length() - 1).replace('/', '.'));
                    System.out.println("prepare class: " + value);
                }
            }
        }
    }
}
Also used : DexBackedArrayEncodedValue(org.jf.dexlib2.dexbacked.value.DexBackedArrayEncodedValue) DexBackedTypeEncodedValue(org.jf.dexlib2.dexbacked.value.DexBackedTypeEncodedValue) DexBackedArrayEncodedValue(org.jf.dexlib2.dexbacked.value.DexBackedArrayEncodedValue) DexBackedAnnotationEncodedValue(org.jf.dexlib2.dexbacked.value.DexBackedAnnotationEncodedValue) EncodedValue(org.jf.dexlib2.iface.value.EncodedValue) TypeEncodedValue(org.jf.dexlib2.iface.value.TypeEncodedValue) DexBackedTypeEncodedValue(org.jf.dexlib2.dexbacked.value.DexBackedTypeEncodedValue) TypeEncodedValue(org.jf.dexlib2.iface.value.TypeEncodedValue) DexBackedAnnotationElement(org.jf.dexlib2.dexbacked.DexBackedAnnotationElement) AnnotationElement(org.jf.dexlib2.iface.AnnotationElement) DexBackedMethod(org.jf.dexlib2.dexbacked.DexBackedMethod) Annotation(org.jf.dexlib2.iface.Annotation) DexBackedAnnotation(org.jf.dexlib2.dexbacked.DexBackedAnnotation) DexBackedTypeEncodedValue(org.jf.dexlib2.dexbacked.value.DexBackedTypeEncodedValue)

Example 2 with DexBackedMethod

use of org.jf.dexlib2.dexbacked.DexBackedMethod in project atlas by alibaba.

the class ApkPatch method buildPrepareClass.

private static Set<String> buildPrepareClass(File smaliDir, List<File> newFiles, DexDiffInfo info) throws PatchException {
    Set<DexBackedClassDef> classes = Sets.newHashSet();
    classes = SmaliDiffUtils.scanClasses(smaliDir, newFiles);
    ArrayList<String> methods = new ArrayList<String>();
    {
        Set<DexBackedMethod> tempSet = info.getModifiedMethods();
        for (DexBackedMethod methodRef : tempSet) {
            String template = methodRef.getDefiningClass() + "->" + methodRef.getName();
            methods.add(template);
            System.out.println("template: " + template);
            if (superClasses.containsKey(methodRef.getDefiningClass())) {
                ArrayList<String> derivedClasses = superClasses.get(methodRef.getDefiningClass());
                for (int i = 0; i < derivedClasses.size(); i++) {
                    template = derivedClasses.get(i) + "->" + methodRef.getName();
                    System.out.println("template: " + template);
                    methods.add(template);
                }
            }
        }
    }
    Set<String> prepareClasses = new HashSet<String>();
    try {
        final ClassFileNameHandler inFileNameHandler = new ClassFileNameHandler(smaliDir, ".smali");
        for (DexBackedClassDef classDef : classes) {
            currentClassType = null;
            String className = TypeGenUtil.newType(classDef.getType());
            // baksmali.disassembleClass(classDef, outFileNameHandler, options);
            File smaliFile = inFileNameHandler.getUniqueFilenameForClass(className);
            if (!smaliFile.exists()) {
                continue;
            }
            // 增加class注解到prepare
            getClassAnnotaionPrepareClasses(classDef, prepareClasses, info);
            BufferedReader br = new BufferedReader(new FileReader(smaliFile));
            // 一次读入一行,直到读入null为文件结束
            String data = br.readLine();
            while (data != null) {
                boolean find = false;
                for (String m : methods) {
                    if (data.contains(m)) {
                        find = true;
                        break;
                    }
                }
                if (find) {
                    prepareClasses.add(className.substring(1, className.length() - 1).replace('/', '.'));
                    System.out.println("prepare class: " + className);
                    break;
                }
                // 接着读下一行
                data = br.readLine();
            }
            br.close();
        }
    } catch (Exception e) {
        throw new PatchException(e);
    }
    for (DexBackedMethod method : info.getModifiedMethods()) {
        prepareClasses.add(method.getDefiningClass().substring(1, method.getDefiningClass().length() - 1).replace("/", "."));
    }
    // getMethodAnnotaionPrepareClasses(info,prepareClasses);
    return prepareClasses;
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) DexBackedMethod(org.jf.dexlib2.dexbacked.DexBackedMethod) ClassFileNameHandler(org.jf.util.ClassFileNameHandler) ArrayList(java.util.ArrayList) PatchException(com.taobao.android.differ.dex.PatchException) IOException(java.io.IOException) BufferedReader(java.io.BufferedReader) FileReader(java.io.FileReader) PatchException(com.taobao.android.differ.dex.PatchException) DexBackedClassDef(org.jf.dexlib2.dexbacked.DexBackedClassDef) File(java.io.File) HashSet(java.util.HashSet)

Example 3 with DexBackedMethod

use of org.jf.dexlib2.dexbacked.DexBackedMethod in project smali by JesusFreke.

the class DexBackedClassDef method getDirectMethods.

@Nonnull
public Iterable<? extends DexBackedMethod> getDirectMethods(final boolean skipDuplicates) {
    if (directMethodCount > 0) {
        DexReader reader = dexFile.getDataBuffer().readerAt(getDirectMethodsOffset());
        final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory();
        final int methodsStartOffset = reader.getOffset();
        Iterator<Integer> hiddenApiRestrictionIterator = hiddenApiRestrictionsReader == null ? null : hiddenApiRestrictionsReader.getRestrictionsForDirectMethods();
        return new Iterable<DexBackedMethod>() {

            @Nonnull
            @Override
            public Iterator<DexBackedMethod> iterator() {
                final AnnotationsDirectory.AnnotationIterator methodAnnotationIterator = annotationsDirectory.getMethodAnnotationIterator();
                final AnnotationsDirectory.AnnotationIterator parameterAnnotationIterator = annotationsDirectory.getParameterAnnotationIterator();
                return new VariableSizeLookaheadIterator<DexBackedMethod>(dexFile.getDataBuffer(), methodsStartOffset) {

                    private int count;

                    @Nullable
                    private MethodReference previousMethod;

                    private int previousIndex;

                    @Nullable
                    @Override
                    protected DexBackedMethod readNextItem(@Nonnull DexReader reader) {
                        while (true) {
                            if (++count > directMethodCount) {
                                virtualMethodsOffset = reader.getOffset();
                                return endOfData();
                            }
                            int hiddenApiRestrictions = NO_HIDDEN_API_RESTRICTIONS;
                            if (hiddenApiRestrictionIterator != null) {
                                hiddenApiRestrictions = hiddenApiRestrictionIterator.next();
                            }
                            DexBackedMethod item = new DexBackedMethod(dexFile, reader, DexBackedClassDef.this, previousIndex, methodAnnotationIterator, parameterAnnotationIterator, hiddenApiRestrictions);
                            MethodReference currentMethod = previousMethod;
                            MethodReference nextMethod = ImmutableMethodReference.of(item);
                            previousMethod = nextMethod;
                            previousIndex = item.methodIndex;
                            if (skipDuplicates && currentMethod != null && currentMethod.equals(nextMethod)) {
                                continue;
                            }
                            return item;
                        }
                    }
                };
            }
        };
    } else {
        if (directMethodsOffset > 0) {
            virtualMethodsOffset = directMethodsOffset;
        }
        return ImmutableSet.of();
    }
}
Also used : AnnotationsDirectory(org.jf.dexlib2.dexbacked.util.AnnotationsDirectory) Nonnull(javax.annotation.Nonnull) VariableSizeLookaheadIterator(org.jf.dexlib2.dexbacked.util.VariableSizeLookaheadIterator) MethodReference(org.jf.dexlib2.iface.reference.MethodReference) ImmutableMethodReference(org.jf.dexlib2.immutable.reference.ImmutableMethodReference) Nonnull(javax.annotation.Nonnull)

Example 4 with DexBackedMethod

use of org.jf.dexlib2.dexbacked.DexBackedMethod in project smali by JesusFreke.

the class DexBackedClassDef method getVirtualMethods.

@Nonnull
public Iterable<? extends DexBackedMethod> getVirtualMethods(final boolean skipDuplicates) {
    if (virtualMethodCount > 0) {
        DexReader reader = dexFile.getDataBuffer().readerAt(getVirtualMethodsOffset());
        final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory();
        final int methodsStartOffset = reader.getOffset();
        Iterator<Integer> hiddenApiRestrictionIterator = hiddenApiRestrictionsReader == null ? null : hiddenApiRestrictionsReader.getRestrictionsForVirtualMethods();
        return new Iterable<DexBackedMethod>() {

            final AnnotationsDirectory.AnnotationIterator methodAnnotationIterator = annotationsDirectory.getMethodAnnotationIterator();

            final AnnotationsDirectory.AnnotationIterator parameterAnnotationIterator = annotationsDirectory.getParameterAnnotationIterator();

            @Nonnull
            @Override
            public Iterator<DexBackedMethod> iterator() {
                return new VariableSizeLookaheadIterator<DexBackedMethod>(dexFile.getDataBuffer(), methodsStartOffset) {

                    private int count;

                    @Nullable
                    private MethodReference previousMethod;

                    private int previousIndex;

                    @Nullable
                    @Override
                    protected DexBackedMethod readNextItem(@Nonnull DexReader reader) {
                        while (true) {
                            if (++count > virtualMethodCount) {
                                return endOfData();
                            }
                            int hiddenApiRestrictions = NO_HIDDEN_API_RESTRICTIONS;
                            if (hiddenApiRestrictionIterator != null) {
                                hiddenApiRestrictions = hiddenApiRestrictionIterator.next();
                            }
                            DexBackedMethod item = new DexBackedMethod(dexFile, reader, DexBackedClassDef.this, previousIndex, methodAnnotationIterator, parameterAnnotationIterator, hiddenApiRestrictions);
                            MethodReference currentMethod = previousMethod;
                            MethodReference nextMethod = ImmutableMethodReference.of(item);
                            previousMethod = nextMethod;
                            previousIndex = item.methodIndex;
                            if (skipDuplicates && currentMethod != null && currentMethod.equals(nextMethod)) {
                                continue;
                            }
                            return item;
                        }
                    }
                };
            }
        };
    } else {
        return ImmutableSet.of();
    }
}
Also used : AnnotationsDirectory(org.jf.dexlib2.dexbacked.util.AnnotationsDirectory) Nonnull(javax.annotation.Nonnull) VariableSizeLookaheadIterator(org.jf.dexlib2.dexbacked.util.VariableSizeLookaheadIterator) MethodReference(org.jf.dexlib2.iface.reference.MethodReference) ImmutableMethodReference(org.jf.dexlib2.immutable.reference.ImmutableMethodReference) Nonnull(javax.annotation.Nonnull)

Example 5 with DexBackedMethod

use of org.jf.dexlib2.dexbacked.DexBackedMethod in project smali by JesusFreke.

the class DexBackedClassDef method getSize.

/**
 * Calculate and return the private size of a class definition.
 *
 * Calculated as: class_def_item size + type_id size + interfaces type_list +
 * annotations_directory_item overhead + class_data_item + static values overhead +
 * methods size + fields size
 *
 * @return size in bytes
 */
public int getSize() {
    // class_def_item has 8 uint fields in dex files
    int size = 8 * 4;
    // type_ids size
    size += TypeIdItem.ITEM_SIZE;
    // add interface list size if any
    int interfacesLength = getInterfaces().size();
    if (interfacesLength > 0) {
        // add size of the type_list
        // uint for size
        size += 4;
        // ushort per type_item
        size += interfacesLength * 2;
    }
    // annotations directory size if it exists
    AnnotationsDirectory directory = getAnnotationsDirectory();
    if (!AnnotationsDirectory.EMPTY.equals(directory)) {
        // 4 uints in annotations_directory_item
        size += 4 * 4;
        Set<? extends DexBackedAnnotation> classAnnotations = directory.getClassAnnotations();
        if (!classAnnotations.isEmpty()) {
            // uint for size
            size += 4;
            // uint per annotation_off
            size += classAnnotations.size() * 4;
        // TODO: should we add annotation_item size? what if it's shared?
        }
    }
    // static values and/or metadata
    int staticInitialValuesOffset = dexFile.getBuffer().readSmallUint(classDefOffset + ClassDefItem.STATIC_VALUES_OFFSET);
    if (staticInitialValuesOffset != 0) {
        DexReader reader = dexFile.getDataBuffer().readerAt(staticInitialValuesOffset);
        // encoded_array size field
        size += reader.peekSmallUleb128Size();
    }
    // class_data_item
    int classDataOffset = dexFile.getBuffer().readSmallUint(classDefOffset + ClassDefItem.CLASS_DATA_OFFSET);
    if (classDataOffset > 0) {
        DexReader reader = dexFile.getDataBuffer().readerAt(classDataOffset);
        // staticFieldCount
        reader.readSmallUleb128();
        // instanceFieldCount
        reader.readSmallUleb128();
        // directMethodCount
        reader.readSmallUleb128();
        // virtualMethodCount
        reader.readSmallUleb128();
        size += reader.getOffset() - classDataOffset;
    }
    for (DexBackedField dexBackedField : getFields()) {
        size += dexBackedField.getSize();
    }
    for (DexBackedMethod dexBackedMethod : getMethods()) {
        size += dexBackedMethod.getSize();
    }
    return size;
}
Also used : AnnotationsDirectory(org.jf.dexlib2.dexbacked.util.AnnotationsDirectory)

Aggregations

DexBackedMethod (org.jf.dexlib2.dexbacked.DexBackedMethod)6 File (java.io.File)4 Nonnull (javax.annotation.Nonnull)4 DexBackedClassDef (org.jf.dexlib2.dexbacked.DexBackedClassDef)4 AnnotationsDirectory (org.jf.dexlib2.dexbacked.util.AnnotationsDirectory)3 DexFile (org.jf.dexlib2.iface.DexFile)3 MethodReference (org.jf.dexlib2.iface.reference.MethodReference)3 AndFixFilterImpl (com.taobao.android.apatch.AndFixFilterImpl)2 FastBuild (com.taobao.android.apatch.FastBuild)2 MergePatch (com.taobao.android.apatch.MergePatch)2 DexDiffInfo (com.taobao.android.object.DexDiffInfo)2 FastPatchObject (com.taobao.android.repatch.FastPatchObject)2 InsTructionsReIClassDef (com.taobao.android.repatch.InsTructionsReIClassDef)2 MappingProcessor (com.taobao.android.repatch.mapping.MappingProcessor)2 MappingProcessorImpl (com.taobao.android.repatch.mapping.MappingProcessorImpl)2 MappingReader (com.taobao.android.repatch.mapping.MappingReader)2 MappingClassProcessor (com.taobao.android.repatch.processor.MappingClassProcessor)2 KeyStoreException (java.security.KeyStoreException)2 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)2 UnrecoverableEntryException (java.security.UnrecoverableEntryException)2