Search in sources :

Example 6 with DexBackedField

use of org.jf.dexlib2.dexbacked.DexBackedField in project android-bundle-support by lizhangqu.

the class DexReferences method gatherBackReferences.

/**
 * Goes through all the classes, methods, and fields, and gathers all possible references from
 * one type/method/field to another.
 *
 * @param files dex file
 */
private void gatherBackReferences(@NonNull DexBackedDexFile[] files) {
    Map<Reference, ImmutableReference> immutableReferencesBin = new HashMap<>();
    for (DexBackedDexFile file : files) {
        // build a map from class names (String) to actual TypeReferences,
        // as this information is not readily available to query through
        // the dexlib2 API.
        Map<String, ImmutableTypeReference> typesByName = new HashMap<>();
        for (int i = 0, m = file.getTypeCount(); i < m; i++) {
            ImmutableTypeReference immutableTypeRef = ImmutableTypeReference.of(new DexBackedTypeReference(file, i));
            typesByName.put(immutableTypeRef.getType(), immutableTypeRef);
        }
        // loop through all methods referenced in the dex file, mapping the following:
        for (int i = 0, m = file.getMethodCount(); i < m; i++) {
            MethodReference methodReference = new DexBackedMethodReference(file, i);
            // - return type => method
            ImmutableReference typeRef = typesByName.get(methodReference.getReturnType());
            addReference(typeRef, methodReference, immutableReferencesBin);
            // - all parameter types => method
            for (CharSequence parameterType : methodReference.getParameterTypes()) {
                typeRef = typesByName.get(parameterType.toString());
                addReference(typeRef, methodReference, immutableReferencesBin);
            }
        }
        // loop through all classes defined in the dex file, mapping the following:
        for (DexBackedClassDef classDef : file.getClasses()) {
            // - superclass => class
            ImmutableReference typeRef = typesByName.get(classDef.getSuperclass());
            addReference(typeRef, classDef, immutableReferencesBin);
            // - all implemented interfaces => class
            for (String iface : classDef.getInterfaces()) {
                typeRef = typesByName.get(iface);
                addReference(typeRef, classDef, immutableReferencesBin);
            }
            // map annotations => class
            for (Annotation annotation : classDef.getAnnotations()) {
                addAnnotation(immutableReferencesBin, typesByName, classDef, annotation);
            }
            // loop through all the methods defined in this class
            for (DexBackedMethod method : classDef.getMethods()) {
                // if the method has an implementation, loop through the bytecode
                // mapping any references that exist in dex instructions to the method.
                // Fortunately, dexlib2 marks every bytecode instruction that accepts
                // a reference with one or two interfaces: ReferenceInstruction
                // and DualReferenceInstruction.
                DexBackedMethodImplementation impl = method.getImplementation();
                if (impl != null) {
                    for (Instruction instruction : impl.getInstructions()) {
                        if (instruction instanceof ReferenceInstruction) {
                            Reference reference = ((ReferenceInstruction) instruction).getReference();
                            addReferenceAndEnclosingClass(immutableReferencesBin, typesByName, method, reference);
                        }
                        if (instruction instanceof DualReferenceInstruction) {
                            Reference reference = ((DualReferenceInstruction) instruction).getReference2();
                            addReferenceAndEnclosingClass(immutableReferencesBin, typesByName, method, reference);
                        }
                    }
                }
                // map annotations => method
                for (Annotation annotation : method.getAnnotations()) {
                    addAnnotation(immutableReferencesBin, typesByName, method, annotation);
                }
            }
            for (DexBackedField field : classDef.getFields()) {
                // map annotations => field
                for (Annotation annotation : field.getAnnotations()) {
                    addAnnotation(immutableReferencesBin, typesByName, field, annotation);
                }
            }
        }
        // a mapping from the field type => field
        for (int i = 0, m = file.getFieldCount(); i < m; i++) {
            FieldReference fieldRef = new DexBackedFieldReference(file, i);
            ImmutableReference typeRef = typesByName.get(fieldRef.getType());
            addReference(typeRef, fieldRef, immutableReferencesBin);
        }
    }
}
Also used : DexBackedTypeReference(org.jf.dexlib2.dexbacked.reference.DexBackedTypeReference) DexBackedFieldReference(org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference) FieldReference(org.jf.dexlib2.iface.reference.FieldReference) DexBackedFieldReference(org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference) MethodReference(org.jf.dexlib2.iface.reference.MethodReference) DexBackedMethodReference(org.jf.dexlib2.dexbacked.reference.DexBackedMethodReference) DexBackedTypeReference(org.jf.dexlib2.dexbacked.reference.DexBackedTypeReference) TypeReference(org.jf.dexlib2.iface.reference.TypeReference) Reference(org.jf.dexlib2.iface.reference.Reference) FieldReference(org.jf.dexlib2.iface.reference.FieldReference) DexBackedFieldReference(org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference) DualReferenceInstruction(org.jf.dexlib2.iface.instruction.DualReferenceInstruction) ReferenceInstruction(org.jf.dexlib2.iface.instruction.ReferenceInstruction) Instruction(org.jf.dexlib2.iface.instruction.Instruction) DualReferenceInstruction(org.jf.dexlib2.iface.instruction.DualReferenceInstruction) ReferenceInstruction(org.jf.dexlib2.iface.instruction.ReferenceInstruction) DualReferenceInstruction(org.jf.dexlib2.iface.instruction.DualReferenceInstruction) Annotation(org.jf.dexlib2.iface.Annotation) DexBackedMethodReference(org.jf.dexlib2.dexbacked.reference.DexBackedMethodReference) MethodReference(org.jf.dexlib2.iface.reference.MethodReference) DexBackedMethodReference(org.jf.dexlib2.dexbacked.reference.DexBackedMethodReference)

Example 7 with DexBackedField

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

the class DexBackedClassDef method getInstanceFields.

@Nonnull
public Iterable<? extends DexBackedField> getInstanceFields(final boolean skipDuplicates) {
    if (instanceFieldCount > 0) {
        DexReader reader = dexFile.getDataBuffer().readerAt(getInstanceFieldsOffset());
        final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory();
        final int fieldsStartOffset = reader.getOffset();
        Iterator<Integer> hiddenApiRestrictionIterator = hiddenApiRestrictionsReader == null ? null : hiddenApiRestrictionsReader.getRestrictionsForInstanceFields();
        return new Iterable<DexBackedField>() {

            @Nonnull
            @Override
            public Iterator<DexBackedField> iterator() {
                final AnnotationsDirectory.AnnotationIterator annotationIterator = annotationsDirectory.getFieldAnnotationIterator();
                return new VariableSizeLookaheadIterator<DexBackedField>(dexFile.getDataBuffer(), fieldsStartOffset) {

                    private int count;

                    @Nullable
                    private FieldReference previousField;

                    private int previousIndex;

                    @Nullable
                    @Override
                    protected DexBackedField readNextItem(@Nonnull DexReader reader) {
                        while (true) {
                            if (++count > instanceFieldCount) {
                                directMethodsOffset = reader.getOffset();
                                return endOfData();
                            }
                            int hiddenApiRestrictions = NO_HIDDEN_API_RESTRICTIONS;
                            if (hiddenApiRestrictionIterator != null) {
                                hiddenApiRestrictions = hiddenApiRestrictionIterator.next();
                            }
                            DexBackedField item = new DexBackedField(dexFile, reader, DexBackedClassDef.this, previousIndex, annotationIterator, hiddenApiRestrictions);
                            FieldReference currentField = previousField;
                            FieldReference nextField = ImmutableFieldReference.of(item);
                            previousField = nextField;
                            previousIndex = item.fieldIndex;
                            if (skipDuplicates && currentField != null && currentField.equals(nextField)) {
                                continue;
                            }
                            return item;
                        }
                    }
                };
            }
        };
    } else {
        if (instanceFieldsOffset > 0) {
            directMethodsOffset = instanceFieldsOffset;
        }
        return ImmutableSet.of();
    }
}
Also used : AnnotationsDirectory(org.jf.dexlib2.dexbacked.util.AnnotationsDirectory) ImmutableFieldReference(org.jf.dexlib2.immutable.reference.ImmutableFieldReference) FieldReference(org.jf.dexlib2.iface.reference.FieldReference) Nonnull(javax.annotation.Nonnull) VariableSizeLookaheadIterator(org.jf.dexlib2.dexbacked.util.VariableSizeLookaheadIterator) Nonnull(javax.annotation.Nonnull)

Aggregations

FieldReference (org.jf.dexlib2.iface.reference.FieldReference)5 ImmutableFieldReference (org.jf.dexlib2.immutable.reference.ImmutableFieldReference)4 DexBackedFieldReference (org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference)3 AnnotationsDirectory (org.jf.dexlib2.dexbacked.util.AnnotationsDirectory)3 Nonnull (javax.annotation.Nonnull)2 DexBackedField (org.jf.dexlib2.dexbacked.DexBackedField)2 DexBackedMethodReference (org.jf.dexlib2.dexbacked.reference.DexBackedMethodReference)2 DexBackedTypeReference (org.jf.dexlib2.dexbacked.reference.DexBackedTypeReference)2 VariableSizeLookaheadIterator (org.jf.dexlib2.dexbacked.util.VariableSizeLookaheadIterator)2 MethodReference (org.jf.dexlib2.iface.reference.MethodReference)2 TypeReference (org.jf.dexlib2.iface.reference.TypeReference)2 DexClassNode (io.github.lizhangqu.intellij.android.bundle.analyzer.dex.tree.DexClassNode)1 DexBackedClassDef (org.jf.dexlib2.dexbacked.DexBackedClassDef)1 DexBackedMethod (org.jf.dexlib2.dexbacked.DexBackedMethod)1 EncodedArrayItemIterator (org.jf.dexlib2.dexbacked.util.EncodedArrayItemIterator)1 Annotation (org.jf.dexlib2.iface.Annotation)1 DualReferenceInstruction (org.jf.dexlib2.iface.instruction.DualReferenceInstruction)1 Instruction (org.jf.dexlib2.iface.instruction.Instruction)1 ReferenceInstruction (org.jf.dexlib2.iface.instruction.ReferenceInstruction)1 Reference (org.jf.dexlib2.iface.reference.Reference)1