Search in sources :

Example 1 with DexBackedFieldReference

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

the class PackageTreeCreator method addFields.

private void addFields(@NonNull DexClassNode classNode, @NonNull Iterable<? extends FieldReference> fieldRefs, Path dexFilePath) {
    for (FieldReference fieldRef : fieldRefs) {
        String fieldName = decodeFieldName(fieldRef, proguardMap);
        String fieldType = decodeClassName(fieldRef.getType(), proguardMap);
        String fieldSig = fieldType + " " + fieldName;
        io.github.lizhangqu.intellij.android.bundle.analyzer.dex.tree.DexFieldNode fieldNode = classNode.getChildByType(fieldSig, io.github.lizhangqu.intellij.android.bundle.analyzer.dex.tree.DexFieldNode.class);
        if (fieldNode == null) {
            fieldNode = new io.github.lizhangqu.intellij.android.bundle.analyzer.dex.tree.DexFieldNode(fieldSig, ImmutableFieldReference.of(fieldRef));
            classNode.add(fieldNode);
        }
        if (fieldRef instanceof DexBackedField) {
            fieldNode.setDefined(true);
            fieldNode.setUserObject(dexFilePath);
            fieldNode.setSize(fieldNode.getSize() + ((DexBackedField) fieldRef).getSize());
        } else if (fieldRef instanceof DexBackedFieldReference) {
            fieldNode.setSize(fieldNode.getSize() + ((DexBackedFieldReference) fieldRef).getSize());
        }
    }
}
Also used : DexBackedFieldReference(org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference) FieldReference(org.jf.dexlib2.iface.reference.FieldReference) ImmutableFieldReference(org.jf.dexlib2.immutable.reference.ImmutableFieldReference) DexBackedFieldReference(org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference) DexBackedField(org.jf.dexlib2.dexbacked.DexBackedField)

Example 2 with DexBackedFieldReference

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

the class PackageTreeCreator method getAllFieldReferencesByClassName.

@NonNull
private static Multimap<String, FieldReference> getAllFieldReferencesByClassName(@NonNull DexBackedDexFile dexFile) {
    Multimap<String, FieldReference> fieldsByClass = ArrayListMultimap.create();
    for (int i = 0, m = dexFile.getFieldCount(); i < m; i++) {
        FieldReference fieldRef = new DexBackedFieldReference(dexFile, i);
        fieldsByClass.put(fieldRef.getDefiningClass(), fieldRef);
    }
    return fieldsByClass;
}
Also used : DexBackedFieldReference(org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference) FieldReference(org.jf.dexlib2.iface.reference.FieldReference) ImmutableFieldReference(org.jf.dexlib2.immutable.reference.ImmutableFieldReference) DexBackedFieldReference(org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference) NonNull(com.android.annotations.NonNull)

Example 3 with DexBackedFieldReference

use of org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference 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 4 with DexBackedFieldReference

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

the class DexBackedField method getSize.

/**
 * Calculate and return the private size of a field definition.
 *
 * Calculated as: field_idx_diff + access_flags + annotations overhead +
 * initial value size + field reference size
 *
 * @return size in bytes
 */
public int getSize() {
    int size = 0;
    DexReader reader = dexFile.getBuffer().readerAt(startOffset);
    // field_idx_diff
    reader.readLargeUleb128();
    // access_flags
    reader.readSmallUleb128();
    size += reader.getOffset() - startOffset;
    Set<? extends DexBackedAnnotation> annotations = getAnnotations();
    if (!annotations.isEmpty()) {
        // 2 * uint overhead from field_annotation
        size += 2 * 4;
    }
    if (initialValueOffset > 0) {
        reader.setOffset(initialValueOffset);
        if (initialValue != null) {
            DexBackedEncodedValue.skipFrom(reader);
            size += reader.getOffset() - initialValueOffset;
        }
    }
    DexBackedFieldReference fieldRef = new DexBackedFieldReference(dexFile, fieldIndex);
    size += fieldRef.getSize();
    return size;
}
Also used : DexBackedFieldReference(org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference)

Aggregations

DexBackedFieldReference (org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference)4 FieldReference (org.jf.dexlib2.iface.reference.FieldReference)3 ImmutableFieldReference (org.jf.dexlib2.immutable.reference.ImmutableFieldReference)2 NonNull (com.android.annotations.NonNull)1 DexBackedField (org.jf.dexlib2.dexbacked.DexBackedField)1 DexBackedMethodReference (org.jf.dexlib2.dexbacked.reference.DexBackedMethodReference)1 DexBackedTypeReference (org.jf.dexlib2.dexbacked.reference.DexBackedTypeReference)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 MethodReference (org.jf.dexlib2.iface.reference.MethodReference)1 Reference (org.jf.dexlib2.iface.reference.Reference)1 TypeReference (org.jf.dexlib2.iface.reference.TypeReference)1