Search in sources :

Example 1 with DexBackedAnnotation

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

the class ApkPatch method getClassAnnotaionPrepareClasses.

public static void getClassAnnotaionPrepareClasses(DexBackedClassDef classDef, Set<String> prepareclasses, DexDiffInfo dexDiffInfo) {
    for (DexBackedClassDef modifyClasses : dexDiffInfo.getModifiedClasses()) {
        if (classDef.getType().equals(modifyClasses.getType())) {
            if (classDef.getAnnotations() != null) {
                Set<? extends DexBackedAnnotation> annotations = classDef.getAnnotations();
                for (DexBackedAnnotation 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 DexBackedAnnotationElement> elements = annotation.getElements();
                    for (DexBackedAnnotationElement 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);
                        } else if (dexBackedAnnotationElement.getValue() instanceof DexBackedAnnotationEncodedValue) {
                            String value = ((DexBackedAnnotationEncodedValue) dexBackedAnnotationElement.getValue()).getType();
                        }
                    }
                }
            }
        }
    }
}
Also used : DexBackedAnnotationElement(org.jf.dexlib2.dexbacked.DexBackedAnnotationElement) 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) DexBackedAnnotationEncodedValue(org.jf.dexlib2.dexbacked.value.DexBackedAnnotationEncodedValue) DexBackedAnnotation(org.jf.dexlib2.dexbacked.DexBackedAnnotation) DexBackedClassDef(org.jf.dexlib2.dexbacked.DexBackedClassDef) DexBackedTypeEncodedValue(org.jf.dexlib2.dexbacked.value.DexBackedTypeEncodedValue)

Example 2 with DexBackedAnnotation

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

the class AndFixFilterImpl method filterClass.

@Override
public boolean filterClass(ClassDiffInfo classDiffInfo) throws PatchException {
    boolean isInnerclass = false;
    DexBackedClassDef dexBackedClassDef = classDiffInfo.getClassDef();
    if (classDiffInfo.getType().equals(DiffType.ADD)) {
        return false;
    // if (dexBackedClassDef.getAnnotations().size() > 0) {
    // Set<? extends Annotation> annotations = dexBackedClassDef.getAnnotations();
    // for (Annotation dexBackedAnnotation : annotations) {
    // if (dexBackedAnnotation.getType().equals("dalvik/annotation/EnclosingClass;"))
    // throw new PatchException("can't add member class:" + dexBackedClassDef.getType());
    // }
    // }
    // String className = DexDiffer.getDalvikClassName(dexBackedClassDef.getType());
    // MappingParser mappingParser = new MappingParser(APatchTool.mappingFile);
    // String outterClassName = mappingParser.getOuterClass(className);
    // if (!className.equals(outterClassName)) {
    // isInnerclass = true;
    // if (SmaliDiffUtils.diff(diffInfo, outterClassName, className, outFile)) {
    // classDiffInfo.setType(DiffType.NONE);
    // return true;
    // } else {
    // throw new PatchException("can't add anonymous class;" + dexBackedClassDef.getType());
    // }
    // }
    // throw new PatchException("can't add class:" + dexBackedClassDef.getType());
    } else if (classDiffInfo.getType().equals(DiffType.MODIFY)) {
        if (classDiffInfo.getName().endsWith(".R") || classDiffInfo.getName().contains(".R$")) {
            return true;
        }
        Set<MethodDiffInfo> needFilterMethod = new HashSet<MethodDiffInfo>();
        Set<FieldDiffInfo> needFilterField = new HashSet<FieldDiffInfo>();
        if (classDiffInfo.getModifyMethods().size() > 0) {
            for (MethodDiffInfo methodDiffInfo : classDiffInfo.getModifyMethods()) {
                if (filterMethod(methodDiffInfo)) {
                    System.out.println(methodDiffInfo.getBackedMethod().getDefiningClass() + ":" + methodDiffInfo.getBackedMethod().getName() + " is filtered!");
                    needFilterMethod.add(methodDiffInfo);
                }
            }
        }
        classDiffInfo.getModifyMethods().removeAll(needFilterMethod);
        if (classDiffInfo.getModifyFields().size() > 0) {
            for (FieldDiffInfo fieldDiffInfo : classDiffInfo.getModifyFields()) {
                if (filterField(fieldDiffInfo)) {
                    needFilterField.add(fieldDiffInfo);
                }
            }
        }
        classDiffInfo.getModifyFields().removeAll(needFilterField);
        if (classDiffInfo.getModifyFields().size() == 0 && classDiffInfo.getModifyMethods().size() == 0) {
            classDiffInfo.setType(DiffType.NONE);
            return true;
        }
    }
    return false;
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) FieldDiffInfo(com.taobao.android.object.FieldDiffInfo) MethodDiffInfo(com.taobao.android.object.MethodDiffInfo) DexBackedClassDef(org.jf.dexlib2.dexbacked.DexBackedClassDef)

Example 3 with DexBackedAnnotation

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

the class DexDiffer method compareFields.

/**
 * compare filed in two dex Files
 *
 * @param baseClassDef
 * @param newClassDef
 * @param classDiffInfo
 */
private boolean compareFields(DexBackedClassDef baseClassDef, DexBackedClassDef newClassDef, ClassDiffInfo classDiffInfo) throws PatchException {
    Map<String, DexBackedField> baseFieldMaps = Maps.newHashMap();
    for (DexBackedField backedField : baseClassDef.getFields()) {
        baseFieldMaps.put(ReferenceUtil.getFieldDescriptor(backedField), backedField);
    }
    for (DexBackedField newField : newClassDef.getFields()) {
        FieldDiffInfo fieldDiffInfo = new FieldDiffInfo();
        fieldDiffInfo.setBackedField(newField);
        String fieldDesc = ReferenceUtil.getFieldDescriptor(newField);
        DexBackedField baseField = baseFieldMaps.get(fieldDesc);
        if (null == baseField) {
            fieldDiffInfo.setType(DiffType.ADD);
            classDiffInfo.getModifyFields().add(fieldDiffInfo);
            continue;
        }
        // init value
        EncodedValue baseInitaValue = baseField.getInitialValue();
        EncodedValue newInitaValue = newField.getInitialValue();
        if (!Objects.equal(baseInitaValue, newInitaValue)) {
            fieldDiffInfo.setType(DiffType.MODIFY);
            classDiffInfo.getModifyFields().add(fieldDiffInfo);
            baseFieldMaps.remove(fieldDesc);
            continue;
        }
        // annotation
        Set<? extends DexBackedAnnotation> backedAnnotations = baseField.getAnnotations();
        if (!equalsImpl(backedAnnotations, newField.getAnnotations())) {
            fieldDiffInfo.setType(DiffType.MODIFY);
            classDiffInfo.getModifyFields().add(fieldDiffInfo);
            baseFieldMaps.remove(fieldDesc);
            continue;
        }
        // type
        if (!baseField.getType().equals(newField.getType())) {
            fieldDiffInfo.setType(DiffType.MODIFY);
            classDiffInfo.getModifyFields().add(fieldDiffInfo);
            baseFieldMaps.remove(fieldDesc);
            continue;
        }
        if (baseField.getAccessFlags() != newField.getAccessFlags()) {
            fieldDiffInfo.setType(DiffType.MODIFY);
            classDiffInfo.getModifyFields().add(fieldDiffInfo);
            baseFieldMaps.remove(fieldDesc);
            continue;
        }
        baseFieldMaps.remove(fieldDesc);
    }
    // if member is removed
    if (baseFieldMaps.size() > 0) {
        for (Map.Entry<String, DexBackedField> entry : baseFieldMaps.entrySet()) {
            FieldDiffInfo fieldDiffInfo = new FieldDiffInfo();
            fieldDiffInfo.setBackedField(entry.getValue());
            fieldDiffInfo.setType(DiffType.REMOVE);
            classDiffInfo.getModifyFields().add(fieldDiffInfo);
        }
    }
    if (classDiffInfo.getModifyFields().size() > 0) {
        return true;
    }
    return false;
}
Also used : EncodedValue(org.jf.dexlib2.iface.value.EncodedValue)

Example 4 with DexBackedAnnotation

use of org.jf.dexlib2.dexbacked.DexBackedAnnotation 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)

Example 5 with DexBackedAnnotation

use of org.jf.dexlib2.dexbacked.DexBackedAnnotation 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

DexBackedClassDef (org.jf.dexlib2.dexbacked.DexBackedClassDef)2 EncodedValue (org.jf.dexlib2.iface.value.EncodedValue)2 FieldDiffInfo (com.taobao.android.object.FieldDiffInfo)1 MethodDiffInfo (com.taobao.android.object.MethodDiffInfo)1 HashSet (java.util.HashSet)1 Set (java.util.Set)1 DexBackedAnnotation (org.jf.dexlib2.dexbacked.DexBackedAnnotation)1 DexBackedAnnotationElement (org.jf.dexlib2.dexbacked.DexBackedAnnotationElement)1 DexBackedFieldReference (org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference)1 AnnotationsDirectory (org.jf.dexlib2.dexbacked.util.AnnotationsDirectory)1 DexBackedAnnotationEncodedValue (org.jf.dexlib2.dexbacked.value.DexBackedAnnotationEncodedValue)1 DexBackedArrayEncodedValue (org.jf.dexlib2.dexbacked.value.DexBackedArrayEncodedValue)1 DexBackedTypeEncodedValue (org.jf.dexlib2.dexbacked.value.DexBackedTypeEncodedValue)1 TypeEncodedValue (org.jf.dexlib2.iface.value.TypeEncodedValue)1