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();
}
}
}
}
}
}
}
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;
}
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;
}
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;
}
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;
}
Aggregations