mirror of
https://github.com/revanced/smali.git
synced 2025-05-04 08:34:25 +02:00
- Added the ability to sort the offsetted sections in a way that guarantees a unique order for a given set of items (helpful when trying to compare dex files)
- Fixed an issue with decodeLong in NumberUtils git-svn-id: https://smali.googlecode.com/svn/trunk@209 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
parent
6ccb8b3d2b
commit
ec857fcecd
@ -45,6 +45,14 @@ public class AnnotationDirectoryItem extends OffsettedItem<AnnotationDirectoryIt
|
|||||||
private final FieldListField<MethodAnnotation> methodAnnotationListField;
|
private final FieldListField<MethodAnnotation> methodAnnotationListField;
|
||||||
private final FieldListField<ParameterAnnotation> parameterAnnotationListField;
|
private final FieldListField<ParameterAnnotation> parameterAnnotationListField;
|
||||||
|
|
||||||
|
|
||||||
|
//typically each AnnotationDirectoryItem will have a distinct parent. The only case that isn't true is when
|
||||||
|
//the AnnotationDirectoryItem *only* contains class annotations, with no other type of annotation. In that
|
||||||
|
//case, the same AnnotationDirectoryItem could be references from multiple classes.
|
||||||
|
//This isn't a problem though, because this field is only used in compareTo to determine the sort order,
|
||||||
|
//which handles it as a special case
|
||||||
|
private ClassDefItem parent = null;
|
||||||
|
|
||||||
protected AnnotationDirectoryItem(final DexFile dexFile, int offset) {
|
protected AnnotationDirectoryItem(final DexFile dexFile, int offset) {
|
||||||
super(offset);
|
super(offset);
|
||||||
|
|
||||||
@ -135,6 +143,48 @@ public class AnnotationDirectoryItem extends OffsettedItem<AnnotationDirectoryIt
|
|||||||
return Collections.unmodifiableList(parameterAnnotationList);
|
return Collections.unmodifiableList(parameterAnnotationList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private boolean isInternable() {
|
||||||
|
//an instance is only internable if it has only class annotations, but
|
||||||
|
//no other type of annotation
|
||||||
|
if (classAnnotationsReferenceField.getReference() == null ||
|
||||||
|
fieldAnnotationList.size() > 0 ||
|
||||||
|
methodAnnotationList.size() > 0 ||
|
||||||
|
parameterAnnotationList.size() > 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
//an instance is only internable if it has only class annotations, but
|
||||||
|
//no other type of annotation
|
||||||
|
if (!isInternable()) {
|
||||||
|
return super.hashCode();
|
||||||
|
}
|
||||||
|
return classAnnotationsReferenceField.getReference().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setParent(ClassDefItem classDefItem) {
|
||||||
|
this.parent = classDefItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int compareTo(AnnotationDirectoryItem annotationDirectoryItem) {
|
||||||
|
if (!isInternable()) {
|
||||||
|
if (!annotationDirectoryItem.isInternable()) {
|
||||||
|
return parent.compareTo(annotationDirectoryItem.parent);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!annotationDirectoryItem.isInternable()) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return classAnnotationsReferenceField.getReference().compareTo(
|
||||||
|
annotationDirectoryItem.classAnnotationsReferenceField.getReference());
|
||||||
|
}
|
||||||
|
|
||||||
public static class FieldAnnotation extends CompositeField<FieldAnnotation>
|
public static class FieldAnnotation extends CompositeField<FieldAnnotation>
|
||||||
implements Comparable<FieldAnnotation> {
|
implements Comparable<FieldAnnotation> {
|
||||||
private final IndexedItemReference<FieldIdItem> fieldReferenceField;
|
private final IndexedItemReference<FieldIdItem> fieldReferenceField;
|
||||||
|
@ -69,6 +69,14 @@ public class AnnotationItem extends OffsettedItem<AnnotationItem> {
|
|||||||
return annotationField;
|
return annotationField;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int compareTo(AnnotationItem annotationItem) {
|
||||||
|
int comp = ((Integer)visibilityField.getCachedValue()).compareTo(annotationItem.visibilityField.getCachedValue());
|
||||||
|
if (comp == 0) {
|
||||||
|
comp = annotationField.compareTo(annotationItem.annotationField);
|
||||||
|
}
|
||||||
|
return comp;
|
||||||
|
}
|
||||||
|
|
||||||
public enum Visibility {
|
public enum Visibility {
|
||||||
build(0x00),
|
build(0x00),
|
||||||
runtime(0x01),
|
runtime(0x01),
|
||||||
|
@ -83,4 +83,22 @@ public class AnnotationSetItem extends OffsettedItem<AnnotationSetItem> {
|
|||||||
}
|
}
|
||||||
return annotationItems;
|
return annotationItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int compareTo(AnnotationSetItem annotationSetItem) {
|
||||||
|
if (annotationSetItem == null) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int comp = ((Integer)annotationReferences.size()).compareTo(annotationSetItem.annotationReferences.size());
|
||||||
|
if (comp == 0) {
|
||||||
|
for (int i=0; i<annotationReferences.size(); i++) {
|
||||||
|
comp = annotationReferences.get(i).getReference().compareTo(
|
||||||
|
annotationSetItem.annotationReferences.get(i).getReference());
|
||||||
|
if (comp != 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return comp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,4 +88,18 @@ public class AnnotationSetRefList extends OffsettedItem<AnnotationSetRefList> {
|
|||||||
|
|
||||||
return annotationSets;
|
return annotationSets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int compareTo(AnnotationSetRefList annotationSetRefList) {
|
||||||
|
int comp = ((Integer)annotationSetReferences.size()).compareTo(annotationSetRefList.annotationSetReferences.size());
|
||||||
|
if (comp == 0) {
|
||||||
|
for (int i=0; i<annotationSetReferences.size(); i++) {
|
||||||
|
comp = annotationSetReferences.get(i).getReference().compareTo(
|
||||||
|
annotationSetRefList.annotationSetReferences.get(i).getReference());
|
||||||
|
if (comp != 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return comp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,7 @@ public class ClassDataItem extends OffsettedItem<ClassDataItem> {
|
|||||||
private final EncodedMemberList<EncodedMethod> directMethodsListField;
|
private final EncodedMemberList<EncodedMethod> directMethodsListField;
|
||||||
private final EncodedMemberList<EncodedMethod> virtualMethodsListField;
|
private final EncodedMemberList<EncodedMethod> virtualMethodsListField;
|
||||||
|
|
||||||
|
private ClassDefItem parent = null;
|
||||||
|
|
||||||
public ClassDataItem(final DexFile dexFile, int offset) {
|
public ClassDataItem(final DexFile dexFile, int offset) {
|
||||||
super(offset);
|
super(offset);
|
||||||
@ -310,6 +311,10 @@ public class ClassDataItem extends OffsettedItem<ClassDataItem> {
|
|||||||
this.codeItemReferenceField = new OffsettedItemReference<CodeItem>(dexFile, codeItem,
|
this.codeItemReferenceField = new OffsettedItemReference<CodeItem>(dexFile, codeItem,
|
||||||
new Leb128Field(null), "code_off")
|
new Leb128Field(null), "code_off")
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (codeItem != null) {
|
||||||
|
codeItem.setParent(methodIdItem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setPreviousMember(EncodedMethod previousMethod) {
|
protected void setPreviousMember(EncodedMethod previousMethod) {
|
||||||
@ -329,6 +334,14 @@ public class ClassDataItem extends OffsettedItem<ClassDataItem> {
|
|||||||
AccessFlags.CONSTRUCTOR.getValue())) != 0);
|
AccessFlags.CONSTRUCTOR.getValue())) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void readFrom(Input in) {
|
||||||
|
super.readFrom(in);
|
||||||
|
CodeItem codeItem = codeItemReferenceField.getReference();
|
||||||
|
if (codeItem != null) {
|
||||||
|
codeItem.setParent(methodReferenceField.getReference());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public int getAccessFlags() {
|
public int getAccessFlags() {
|
||||||
return accessFlagsField.getCachedValue();
|
return accessFlagsField.getCachedValue();
|
||||||
}
|
}
|
||||||
@ -396,4 +409,21 @@ public class ClassDataItem extends OffsettedItem<ClassDataItem> {
|
|||||||
public String getConciseIdentity() {
|
public String getConciseIdentity() {
|
||||||
return "class_data_item @0x" + Integer.toHexString(getOffset());
|
return "class_data_item @0x" + Integer.toHexString(getOffset());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void setParent(ClassDefItem classDefItem) {
|
||||||
|
this.parent = classDefItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int compareTo(ClassDataItem other) {
|
||||||
|
if (parent == null) {
|
||||||
|
if (other.parent == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (other.parent == null) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return parent.compareTo(other.parent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,10 +31,9 @@ package org.jf.dexlib;
|
|||||||
import org.jf.dexlib.EncodedValue.EncodedValue;
|
import org.jf.dexlib.EncodedValue.EncodedValue;
|
||||||
import org.jf.dexlib.EncodedValue.EncodedValueSubField;
|
import org.jf.dexlib.EncodedValue.EncodedValueSubField;
|
||||||
import org.jf.dexlib.Util.TypeUtils;
|
import org.jf.dexlib.Util.TypeUtils;
|
||||||
|
import org.jf.dexlib.Util.Input;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ClassDefItem extends IndexedItem<ClassDefItem> {
|
public class ClassDefItem extends IndexedItem<ClassDefItem> {
|
||||||
private final IndexedItemReference<TypeIdItem> classTypeReferenceField;
|
private final IndexedItemReference<TypeIdItem> classTypeReferenceField;
|
||||||
@ -90,6 +89,10 @@ public class ClassDefItem extends IndexedItem<ClassDefItem> {
|
|||||||
classInterfacesListReferenceField.setReference(implementsList);
|
classInterfacesListReferenceField.setReference(implementsList);
|
||||||
sourceFileReferenceField.setReference(source);
|
sourceFileReferenceField.setReference(source);
|
||||||
classDataReferenceField.setReference(classDataItem);
|
classDataReferenceField.setReference(classDataItem);
|
||||||
|
|
||||||
|
if (classDataItem != null) {
|
||||||
|
classDataItem.setParent(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeIdItem getSuperclass() {
|
public TypeIdItem getSuperclass() {
|
||||||
@ -162,9 +165,10 @@ public class ClassDefItem extends IndexedItem<ClassDefItem> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int compareTo(ClassDefItem o) {
|
public int compareTo(ClassDefItem o) {
|
||||||
//sorting is implemented in SortClassDefItemSection, so this class doesn't
|
//The actual sorting for this class is implemented in SortClassDefItemSection.
|
||||||
//need an implementation of compareTo
|
//This method is just used for sorting the associated ClassDataItem items, so
|
||||||
return 0;
|
//we can just do the comparison based on the offsets of the items
|
||||||
|
return ((Integer)this.offset).compareTo(o.offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addField(ClassDataItem.EncodedField encodedField, EncodedValue initialValue) {
|
public void addField(ClassDataItem.EncodedField encodedField, EncodedValue initialValue) {
|
||||||
@ -205,10 +209,28 @@ public class ClassDefItem extends IndexedItem<ClassDefItem> {
|
|||||||
|
|
||||||
public void setAnnotations(AnnotationDirectoryItem annotations) {
|
public void setAnnotations(AnnotationDirectoryItem annotations) {
|
||||||
this.classAnnotationsReferenceField.setReference(annotations);
|
this.classAnnotationsReferenceField.setReference(annotations);
|
||||||
|
annotations.setParent(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClassDataItem(ClassDataItem classDataItem) {
|
public void setClassDataItem(ClassDataItem classDataItem) {
|
||||||
this.classDataReferenceField.setReference(classDataItem);
|
this.classDataReferenceField.setReference(classDataItem);
|
||||||
|
if (classDataItem != null) {
|
||||||
|
classDataItem.setParent(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readFrom(Input in, int index) {
|
||||||
|
super.readFrom(in, index);
|
||||||
|
|
||||||
|
ClassDataItem classDataItem = classDataReferenceField.getReference();
|
||||||
|
if (classDataItem != null) {
|
||||||
|
classDataItem.setParent(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
AnnotationDirectoryItem annotationDirectoryItem = classAnnotationsReferenceField.getReference();
|
||||||
|
if (annotationDirectoryItem != null) {
|
||||||
|
annotationDirectoryItem.setParent(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int placeClassDefItems(IndexedSection<ClassDefItem> section, int offset) {
|
public static int placeClassDefItems(IndexedSection<ClassDefItem> section, int offset) {
|
||||||
@ -238,6 +260,18 @@ public class ClassDefItem extends IndexedItem<ClassDefItem> {
|
|||||||
|
|
||||||
public int placeSection(int offset) {
|
public int placeSection(int offset) {
|
||||||
currentOffset = offset;
|
currentOffset = offset;
|
||||||
|
|
||||||
|
//presort the list, to guarantee a unique ordering
|
||||||
|
Collections.sort(section.items, new Comparator<ClassDefItem>() {
|
||||||
|
public int compare(ClassDefItem classDefItem, ClassDefItem classDefItem1) {
|
||||||
|
return classDefItem.getClassType().compareTo(classDefItem1.getClassType());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for (ClassDefItem classDefItem: section.items) {
|
||||||
|
classDefItem.offset = -1;
|
||||||
|
}
|
||||||
|
|
||||||
for (ClassDefItem classDefItem: section.items) {
|
for (ClassDefItem classDefItem: section.items) {
|
||||||
placeClass(classDefItem);
|
placeClass(classDefItem);
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,8 @@ public class CodeItem extends OffsettedItem<CodeItem> {
|
|||||||
private final FieldListField<TryItem> triesListField;
|
private final FieldListField<TryItem> triesListField;
|
||||||
private final EncodedCatchHandlerList catchHandlersListField;
|
private final EncodedCatchHandlerList catchHandlersListField;
|
||||||
|
|
||||||
|
private MethodIdItem parent = null;
|
||||||
|
|
||||||
public CodeItem(final DexFile dexFile, int offset) {
|
public CodeItem(final DexFile dexFile, int offset) {
|
||||||
super(offset);
|
super(offset);
|
||||||
|
|
||||||
@ -105,6 +107,10 @@ public class CodeItem extends OffsettedItem<CodeItem> {
|
|||||||
inArgumentCountField.cacheValue(inArguments);
|
inArgumentCountField.cacheValue(inArguments);
|
||||||
outArgumentCountField.cacheValue(instructionListField.getOutArguments());
|
outArgumentCountField.cacheValue(instructionListField.getOutArguments());
|
||||||
debugInfoReferenceField.setReference(debugInfo);
|
debugInfoReferenceField.setReference(debugInfo);
|
||||||
|
|
||||||
|
if (debugInfo != null) {
|
||||||
|
debugInfo.setParent(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int getAlignment() {
|
protected int getAlignment() {
|
||||||
@ -131,6 +137,10 @@ public class CodeItem extends OffsettedItem<CodeItem> {
|
|||||||
return debugInfoReferenceField.getReference();
|
return debugInfoReferenceField.getReference();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void setParent(MethodIdItem methodIdItem) {
|
||||||
|
this.parent = methodIdItem;
|
||||||
|
}
|
||||||
|
|
||||||
public void copyTo(DexFile dexFile, CodeItem copy)
|
public void copyTo(DexFile dexFile, CodeItem copy)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < fields.length-2; i++) {
|
for (int i = 0; i < fields.length-2; i++) {
|
||||||
@ -140,6 +150,20 @@ public class CodeItem extends OffsettedItem<CodeItem> {
|
|||||||
//the catchHandler copies will already exist
|
//the catchHandler copies will already exist
|
||||||
catchHandlersListField.copyTo(dexFile, copy.catchHandlersListField);
|
catchHandlersListField.copyTo(dexFile, copy.catchHandlersListField);
|
||||||
triesListField.copyTo(dexFile, copy.triesListField);
|
triesListField.copyTo(dexFile, copy.triesListField);
|
||||||
|
|
||||||
|
DebugInfoItem copyDebugInfo = copy.getDebugInfo();
|
||||||
|
if (copy != null) {
|
||||||
|
copyDebugInfo.setParent(copy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readFrom(Input in, int index) {
|
||||||
|
super.readFrom(in, index);
|
||||||
|
|
||||||
|
DebugInfoItem debugInfoItem = debugInfoReferenceField.getReference();
|
||||||
|
if (debugInfoItem != null) {
|
||||||
|
debugInfoItem.setParent(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getConciseIdentity() {
|
public String getConciseIdentity() {
|
||||||
@ -147,6 +171,19 @@ public class CodeItem extends OffsettedItem<CodeItem> {
|
|||||||
return "code_item @0x" + Integer.toHexString(getOffset());
|
return "code_item @0x" + Integer.toHexString(getOffset());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int compareTo(CodeItem other) {
|
||||||
|
if (parent == null) {
|
||||||
|
if (other.parent == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (other.parent == null) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return parent.compareTo(other.parent);
|
||||||
|
}
|
||||||
|
|
||||||
public static class TryItem extends CompositeField<TryItem> {
|
public static class TryItem extends CompositeField<TryItem> {
|
||||||
private final IntegerField startAddr;
|
private final IntegerField startAddr;
|
||||||
private final ShortIntegerField insnCount;
|
private final ShortIntegerField insnCount;
|
||||||
|
@ -49,6 +49,8 @@ public class DebugInfoItem extends OffsettedItem<DebugInfoItem> {
|
|||||||
private final FieldListField<IndexedItemReference<StringIdItem>> parameterNamesField;
|
private final FieldListField<IndexedItemReference<StringIdItem>> parameterNamesField;
|
||||||
private final DebugInstructionList debugInstructionListField;
|
private final DebugInstructionList debugInstructionListField;
|
||||||
|
|
||||||
|
private CodeItem parent = null;
|
||||||
|
|
||||||
public DebugInfoItem(final DexFile dexFile, int offset) {
|
public DebugInfoItem(final DexFile dexFile, int offset) {
|
||||||
super(offset);
|
super(offset);
|
||||||
|
|
||||||
@ -87,6 +89,10 @@ public class DebugInfoItem extends OffsettedItem<DebugInfoItem> {
|
|||||||
return ItemType.TYPE_DEBUG_INFO_ITEM;
|
return ItemType.TYPE_DEBUG_INFO_ITEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void setParent(CodeItem codeItem) {
|
||||||
|
this.parent = codeItem;
|
||||||
|
}
|
||||||
|
|
||||||
public String getConciseIdentity() {
|
public String getConciseIdentity() {
|
||||||
return "debug_info_item @0x" + Integer.toHexString(getOffset());
|
return "debug_info_item @0x" + Integer.toHexString(getOffset());
|
||||||
}
|
}
|
||||||
@ -113,6 +119,18 @@ public class DebugInfoItem extends OffsettedItem<DebugInfoItem> {
|
|||||||
return parameterNamesList;
|
return parameterNamesList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int compareTo(DebugInfoItem other) {
|
||||||
|
if (parent == null) {
|
||||||
|
if (other.parent == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (other.parent == null) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return parent.compareTo(other.parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private class DebugInstructionList implements Field<DebugInstructionList> {
|
private class DebugInstructionList implements Field<DebugInstructionList> {
|
||||||
|
@ -38,6 +38,7 @@ import java.security.DigestException;
|
|||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.zip.Adler32;
|
import java.util.zip.Adler32;
|
||||||
|
|
||||||
public class DexFile
|
public class DexFile
|
||||||
@ -90,10 +91,10 @@ public class DexFile
|
|||||||
AnnotationDirectoriesSection,
|
AnnotationDirectoriesSection,
|
||||||
TypeListsSection,
|
TypeListsSection,
|
||||||
StringDataSection,
|
StringDataSection,
|
||||||
DebugInfoItemsSection,
|
|
||||||
AnnotationsSection,
|
AnnotationsSection,
|
||||||
EncodedArraysSection,
|
EncodedArraysSection,
|
||||||
ClassDataSection
|
ClassDataSection,
|
||||||
|
DebugInfoItemsSection
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,9 +136,9 @@ public class DexFile
|
|||||||
ItemType.TYPE_ANNOTATION_SET_REF_LIST.getMapValue(),
|
ItemType.TYPE_ANNOTATION_SET_REF_LIST.getMapValue(),
|
||||||
ItemType.TYPE_ANNOTATIONS_DIRECTORY_ITEM.getMapValue(),
|
ItemType.TYPE_ANNOTATIONS_DIRECTORY_ITEM.getMapValue(),
|
||||||
ItemType.TYPE_TYPE_LIST.getMapValue(),
|
ItemType.TYPE_TYPE_LIST.getMapValue(),
|
||||||
ItemType.TYPE_DEBUG_INFO_ITEM.getMapValue(),
|
|
||||||
ItemType.TYPE_CODE_ITEM.getMapValue(),
|
ItemType.TYPE_CODE_ITEM.getMapValue(),
|
||||||
ItemType.TYPE_CLASS_DATA_ITEM.getMapValue(),
|
ItemType.TYPE_CLASS_DATA_ITEM.getMapValue(),
|
||||||
|
ItemType.TYPE_DEBUG_INFO_ITEM.getMapValue(),
|
||||||
ItemType.TYPE_MAP_LIST.getMapValue()
|
ItemType.TYPE_MAP_LIST.getMapValue()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -191,7 +192,7 @@ public class DexFile
|
|||||||
return forDumping;
|
return forDumping;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void place() {
|
public void place(boolean sort) {
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
offset = HeaderItemSection.place(offset);
|
offset = HeaderItemSection.place(offset);
|
||||||
@ -203,6 +204,9 @@ public class DexFile
|
|||||||
dataOffset = offset;
|
dataOffset = offset;
|
||||||
|
|
||||||
for (OffsettedSection offsettedSection: offsettedSections) {
|
for (OffsettedSection offsettedSection: offsettedSections) {
|
||||||
|
if (sort) {
|
||||||
|
offsettedSection.sortSection();
|
||||||
|
}
|
||||||
offset = offsettedSection.place(offset);
|
offset = offsettedSection.place(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,4 +72,8 @@ public class EncodedArrayItem extends OffsettedItem<EncodedArrayItem> {
|
|||||||
public ArrayEncodedValueSubField getEncodedArray() {
|
public ArrayEncodedValueSubField getEncodedArray() {
|
||||||
return encodedArray;
|
return encodedArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int compareTo(EncodedArrayItem encodedArrayItem) {
|
||||||
|
return encodedArray.compareTo(encodedArrayItem.encodedArray);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,11 @@ public class AnnotationElement extends CompositeField<AnnotationElement>
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int compareTo(AnnotationElement annotationElement) {
|
public int compareTo(AnnotationElement annotationElement) {
|
||||||
return elementName.compareTo(annotationElement.elementName);
|
int comp = elementName.compareTo(annotationElement.elementName);
|
||||||
|
if (comp == 0) {
|
||||||
|
comp = encodedValue.compareTo(annotationElement.encodedValue);
|
||||||
|
}
|
||||||
|
return comp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public StringIdItem getName() {
|
public StringIdItem getName() {
|
||||||
|
@ -35,7 +35,7 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class AnnotationEncodedValueSubField extends CompositeField<AnnotationEncodedValueSubField>
|
public class AnnotationEncodedValueSubField extends CompositeField<AnnotationEncodedValueSubField>
|
||||||
implements EncodedValueSubField<AnnotationEncodedValueSubField> {
|
implements EncodedValueSubField<AnnotationEncodedValueSubField>, Comparable<EncodedValueSubField> {
|
||||||
|
|
||||||
private final ArrayList<AnnotationElement> annotationElementList = new ArrayList<AnnotationElement>();
|
private final ArrayList<AnnotationElement> annotationElementList = new ArrayList<AnnotationElement>();
|
||||||
|
|
||||||
@ -88,4 +88,25 @@ public class AnnotationEncodedValueSubField extends CompositeField<AnnotationEnc
|
|||||||
public List<AnnotationElement> getAnnotationElements() {
|
public List<AnnotationElement> getAnnotationElements() {
|
||||||
return Collections.unmodifiableList(annotationElementList);
|
return Collections.unmodifiableList(annotationElementList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int compareTo(EncodedValueSubField t) {
|
||||||
|
int comp = getValueType().compareTo(t.getValueType());
|
||||||
|
if (comp == 0) {
|
||||||
|
AnnotationEncodedValueSubField other = (AnnotationEncodedValueSubField)t;
|
||||||
|
|
||||||
|
comp = annotationType.compareTo(other.annotationType);
|
||||||
|
if (comp == 0) {
|
||||||
|
comp = ((Integer)annotationElementList.size()).compareTo(other.annotationElementList.size());
|
||||||
|
if (comp == 0) {
|
||||||
|
for (int i=0; i<annotationElementList.size(); i++) {
|
||||||
|
comp = annotationElementList.get(i).compareTo(other.annotationElementList.get(i));
|
||||||
|
if (comp != 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return comp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ import java.util.List;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
public class ArrayEncodedValueSubField extends CompositeField<ArrayEncodedValueSubField>
|
public class ArrayEncodedValueSubField extends CompositeField<ArrayEncodedValueSubField>
|
||||||
implements EncodedValueSubField<ArrayEncodedValueSubField>
|
implements EncodedValueSubField<ArrayEncodedValueSubField>, Comparable<EncodedValueSubField>
|
||||||
{
|
{
|
||||||
|
|
||||||
private final ArrayList<EncodedValue> encodedValues;
|
private final ArrayList<EncodedValue> encodedValues;
|
||||||
@ -88,4 +88,22 @@ public class ArrayEncodedValueSubField extends CompositeField<ArrayEncodedValueS
|
|||||||
public List<EncodedValue> getValues() {
|
public List<EncodedValue> getValues() {
|
||||||
return Collections.unmodifiableList(encodedValues);
|
return Collections.unmodifiableList(encodedValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int compareTo(EncodedValueSubField t) {
|
||||||
|
int comp = getValueType().compareTo(t.getValueType());
|
||||||
|
if (comp == 0) {
|
||||||
|
ArrayEncodedValueSubField other = (ArrayEncodedValueSubField)t;
|
||||||
|
|
||||||
|
comp = ((Integer)encodedValues.size()).compareTo(other.encodedValues.size());
|
||||||
|
if (comp == 0) {
|
||||||
|
for (int i=0; i<encodedValues.size(); i++) {
|
||||||
|
comp = encodedValues.get(i).compareTo(other.encodedValues.get(i));
|
||||||
|
if (comp != 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return comp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ import org.jf.dexlib.Util.EncodedValueUtils;
|
|||||||
import org.jf.dexlib.Util.Input;
|
import org.jf.dexlib.Util.Input;
|
||||||
|
|
||||||
public class EncodedIndexedItemReference<T extends IndexedItem<T>>
|
public class EncodedIndexedItemReference<T extends IndexedItem<T>>
|
||||||
implements EncodedValueSubField<EncodedIndexedItemReference<T>> {
|
implements EncodedValueSubField<EncodedIndexedItemReference<T>>, Comparable<EncodedValueSubField> {
|
||||||
private int initialValueArg;
|
private int initialValueArg;
|
||||||
private ValueType valueType;
|
private ValueType valueType;
|
||||||
|
|
||||||
@ -140,4 +140,12 @@ public class EncodedIndexedItemReference<T extends IndexedItem<T>>
|
|||||||
return other.item == null;
|
return other.item == null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int compareTo(EncodedValueSubField t) {
|
||||||
|
int comp = getValueType().compareTo(t.getValueType());
|
||||||
|
if (comp == 0) {
|
||||||
|
return item.compareTo(((EncodedIndexedItemReference<T>)t).item);
|
||||||
|
}
|
||||||
|
return comp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ import org.jf.dexlib.Field;
|
|||||||
import org.jf.dexlib.Util.AnnotatedOutput;
|
import org.jf.dexlib.Util.AnnotatedOutput;
|
||||||
import org.jf.dexlib.Util.Input;
|
import org.jf.dexlib.Util.Input;
|
||||||
|
|
||||||
public class EncodedValue extends CompositeField<EncodedValue> {
|
public class EncodedValue extends CompositeField<EncodedValue> implements Comparable<EncodedValue> {
|
||||||
private class ValueTypeArgField implements Field<ValueTypeArgField> {
|
private class ValueTypeArgField implements Field<ValueTypeArgField> {
|
||||||
private ValueType valueType;
|
private ValueType valueType;
|
||||||
private byte valueArg;
|
private byte valueArg;
|
||||||
@ -89,7 +89,8 @@ public class EncodedValue extends CompositeField<EncodedValue> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class EncodedValueSubFieldWrapper implements Field<EncodedValueSubFieldWrapper> {
|
private class EncodedValueSubFieldWrapper
|
||||||
|
implements Field<EncodedValueSubFieldWrapper>, Comparable<EncodedValueSubFieldWrapper> {
|
||||||
private final DexFile dexFile;
|
private final DexFile dexFile;
|
||||||
private EncodedValueSubField subField;
|
private EncodedValueSubField subField;
|
||||||
|
|
||||||
@ -141,6 +142,10 @@ public class EncodedValue extends CompositeField<EncodedValue> {
|
|||||||
EncodedValueSubFieldWrapper other = (EncodedValueSubFieldWrapper)o;
|
EncodedValueSubFieldWrapper other = (EncodedValueSubFieldWrapper)o;
|
||||||
return subField.equals(other.subField);
|
return subField.equals(other.subField);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int compareTo(EncodedValueSubFieldWrapper encodedValueSubFieldWrapper) {
|
||||||
|
return subField.compareTo(encodedValueSubFieldWrapper.subField);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ValueTypeArgField valueTypeArg;
|
private final ValueTypeArgField valueTypeArg;
|
||||||
@ -181,4 +186,8 @@ public class EncodedValue extends CompositeField<EncodedValue> {
|
|||||||
public EncodedValueSubField getValue() {
|
public EncodedValueSubField getValue() {
|
||||||
return encodedValue.getEncodedValueSubField();
|
return encodedValue.getEncodedValueSubField();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int compareTo(EncodedValue encodedValue) {
|
||||||
|
return this.encodedValue.compareTo(encodedValue.encodedValue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,4 +35,5 @@ public interface EncodedValueSubField<T extends EncodedValueSubField> extends Fi
|
|||||||
public void setInitialValueArg(byte valueArg);
|
public void setInitialValueArg(byte valueArg);
|
||||||
public byte getValueArg();
|
public byte getValueArg();
|
||||||
public ValueType getValueType();
|
public ValueType getValueType();
|
||||||
|
public int compareTo(EncodedValueSubField encodedValueSubField);
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ import org.jf.dexlib.Util.AnnotatedOutput;
|
|||||||
import org.jf.dexlib.Util.Input;
|
import org.jf.dexlib.Util.Input;
|
||||||
|
|
||||||
public class NullEncodedValueSubField
|
public class NullEncodedValueSubField
|
||||||
extends SimpleEncodedValueSubField<Object, NullEncodedValueSubField>
|
extends SimpleEncodedValueSubField<Integer, NullEncodedValueSubField>
|
||||||
{
|
{
|
||||||
public NullEncodedValueSubField() {
|
public NullEncodedValueSubField() {
|
||||||
}
|
}
|
||||||
@ -55,4 +55,8 @@ public class NullEncodedValueSubField
|
|||||||
public ValueType getValueType() {
|
public ValueType getValueType() {
|
||||||
return ValueType.VALUE_NULL;
|
return ValueType.VALUE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int compareTo(EncodedValueSubField t) {
|
||||||
|
return getValueType().compareTo(t.getValueType());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,8 @@ package org.jf.dexlib.EncodedValue;
|
|||||||
|
|
||||||
import org.jf.dexlib.DexFile;
|
import org.jf.dexlib.DexFile;
|
||||||
|
|
||||||
public abstract class SimpleEncodedValueSubField<V, T extends SimpleEncodedValueSubField<V,T>> implements EncodedValueSubField<T>
|
public abstract class SimpleEncodedValueSubField<V extends Comparable<V>, T extends SimpleEncodedValueSubField<V,T>>
|
||||||
|
implements EncodedValueSubField<T>, Comparable<EncodedValueSubField>
|
||||||
{
|
{
|
||||||
protected V value;
|
protected V value;
|
||||||
protected byte valueArg = 0;
|
protected byte valueArg = 0;
|
||||||
@ -65,4 +66,12 @@ public abstract class SimpleEncodedValueSubField<V, T extends SimpleEncodedValue
|
|||||||
}
|
}
|
||||||
return value.equals(other.value);
|
return value.equals(other.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int compareTo(EncodedValueSubField t) {
|
||||||
|
int comp = getValueType().compareTo(t.getValueType());
|
||||||
|
if (comp == 0) {
|
||||||
|
return value.compareTo(((SimpleEncodedValueSubField<V, T>)t).value);
|
||||||
|
}
|
||||||
|
return comp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
package org.jf.dexlib;
|
package org.jf.dexlib;
|
||||||
|
|
||||||
public abstract class IndexedItem<T extends IndexedItem> extends Item<T> implements Comparable<T> {
|
public abstract class IndexedItem<T extends IndexedItem> extends Item<T> {
|
||||||
protected IndexedItem(int index) {
|
protected IndexedItem(int index) {
|
||||||
this.index = index;
|
this.index = index;
|
||||||
}
|
}
|
||||||
|
@ -77,10 +77,6 @@ public abstract class IndexedSection<T extends IndexedItem<T>> extends Section<T
|
|||||||
return itemToReturn;
|
return itemToReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void sortSection() {
|
|
||||||
Collections.sort(items);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int place(int offset) {
|
public int place(int offset) {
|
||||||
sortSection();
|
sortSection();
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ package org.jf.dexlib;
|
|||||||
import org.jf.dexlib.Util.AnnotatedOutput;
|
import org.jf.dexlib.Util.AnnotatedOutput;
|
||||||
import org.jf.dexlib.Util.Input;
|
import org.jf.dexlib.Util.Input;
|
||||||
|
|
||||||
public abstract class Item<T extends Item> {
|
public abstract class Item<T extends Item> implements Comparable<T> {
|
||||||
protected int offset = -1;
|
protected int offset = -1;
|
||||||
protected int index = -1;
|
protected int index = -1;
|
||||||
|
|
||||||
|
@ -33,6 +33,8 @@ import org.jf.dexlib.Util.Input;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
public abstract class Section<T extends Item> {
|
public abstract class Section<T extends Item> {
|
||||||
protected ArrayList<T> items;
|
protected ArrayList<T> items;
|
||||||
@ -112,6 +114,10 @@ public abstract class Section<T extends Item> {
|
|||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<T> getItems() {
|
||||||
|
return Collections.unmodifiableList(items);
|
||||||
|
}
|
||||||
|
|
||||||
protected T getInternedItem(T item) {
|
protected T getInternedItem(T item) {
|
||||||
if (uniqueItems == null) {
|
if (uniqueItems == null) {
|
||||||
buildInternedItemMap();
|
buildInternedItemMap();
|
||||||
@ -126,5 +132,9 @@ public abstract class Section<T extends Item> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void sortSection() {
|
||||||
|
Collections.sort(items);
|
||||||
|
}
|
||||||
|
|
||||||
public abstract T intern(DexFile dexFile, T item);
|
public abstract T intern(DexFile dexFile, T item);
|
||||||
}
|
}
|
||||||
|
@ -69,11 +69,17 @@ public class StringDataItem extends OffsettedItem<StringDataItem> implements Com
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte[] getStringBytes() {
|
||||||
|
return stringByteArray.value;
|
||||||
|
}
|
||||||
|
|
||||||
public String getConciseIdentity() {
|
public String getConciseIdentity() {
|
||||||
return "string_data_item: " + getStringValue();
|
return "string_data_item: " + Utf8Utils.escapeString(getStringValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
public int compareTo(StringDataItem o) {
|
public int compareTo(StringDataItem o) {
|
||||||
return getStringValue().compareTo(o.getStringValue());
|
return getStringValue().compareTo(o.getStringValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
|
|
||||||
package org.jf.dexlib;
|
package org.jf.dexlib;
|
||||||
|
|
||||||
|
import org.jf.dexlib.Util.Utf8Utils;
|
||||||
|
|
||||||
public class StringIdItem extends IndexedItem<StringIdItem> {
|
public class StringIdItem extends IndexedItem<StringIdItem> {
|
||||||
private final OffsettedItemReference<StringDataItem> stringDataReferenceField;
|
private final OffsettedItemReference<StringDataItem> stringDataReferenceField;
|
||||||
|
|
||||||
@ -57,13 +59,17 @@ public class StringIdItem extends IndexedItem<StringIdItem> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getConciseIdentity() {
|
public String getConciseIdentity() {
|
||||||
return "string_id_item: " + getStringValue();
|
return "string_id_item: " + Utf8Utils.escapeString(getStringValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getStringValue() {
|
public String getStringValue() {
|
||||||
return stringDataReferenceField.getReference().getStringValue();
|
return stringDataReferenceField.getReference().getStringValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public StringDataItem getStringData() {
|
||||||
|
return stringDataReferenceField.getReference();
|
||||||
|
}
|
||||||
|
|
||||||
public int compareTo(StringIdItem o) {
|
public int compareTo(StringIdItem o) {
|
||||||
//sort by the string value
|
//sort by the string value
|
||||||
return getStringValue().compareTo(o.getStringValue());
|
return getStringValue().compareTo(o.getStringValue());
|
||||||
|
@ -31,7 +31,7 @@ package org.jf.dexlib;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class TypeListItem extends OffsettedItem<TypeListItem> implements Comparable<TypeListItem> {
|
public class TypeListItem extends OffsettedItem<TypeListItem> {
|
||||||
private final ArrayList<IndexedItemReference<TypeIdItem>> typeList = new ArrayList<IndexedItemReference<TypeIdItem>>();
|
private final ArrayList<IndexedItemReference<TypeIdItem>> typeList = new ArrayList<IndexedItemReference<TypeIdItem>>();
|
||||||
|
|
||||||
private final ListSizeField sizeField;
|
private final ListSizeField sizeField;
|
||||||
|
@ -66,13 +66,13 @@ public class NumberUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static long decodeLong(byte[] array, int startIndex) {
|
public static long decodeLong(byte[] array, int startIndex) {
|
||||||
return array[startIndex++] |
|
return (array[startIndex++] & 0xffL) |
|
||||||
(array[startIndex++] >> 8) |
|
((array[startIndex++] & 0xffL) << 8) |
|
||||||
(array[startIndex++] >> 16) |
|
((array[startIndex++] & 0xffL) << 16) |
|
||||||
(array[startIndex++] >> 24) |
|
((array[startIndex++] & 0xffL) << 24) |
|
||||||
((long)array[startIndex++] >> 32) |
|
((array[startIndex++] & 0xffL) << 32) |
|
||||||
((long)array[startIndex++] >> 40) |
|
((array[startIndex++] & 0xffL) << 40) |
|
||||||
((long)array[startIndex++] >> 48) |
|
((array[startIndex++] & 0xffL) << 48) |
|
||||||
((long)array[startIndex++] >> 56);
|
((array[startIndex] & 0xffL) << 56);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,11 +33,13 @@ import org.antlr.runtime.CommonTokenStream;
|
|||||||
import org.antlr.runtime.tree.CommonTree;
|
import org.antlr.runtime.tree.CommonTree;
|
||||||
import org.antlr.runtime.tree.CommonTreeNodeStream;
|
import org.antlr.runtime.tree.CommonTreeNodeStream;
|
||||||
import org.jf.dexlib.DexFile;
|
import org.jf.dexlib.DexFile;
|
||||||
|
import org.jf.dexlib.AnnotationItem;
|
||||||
import org.jf.dexlib.Util.ByteArrayAnnotatedOutput;
|
import org.jf.dexlib.Util.ByteArrayAnnotatedOutput;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class smali
|
public class smali
|
||||||
{
|
{
|
||||||
@ -125,7 +127,7 @@ public class smali
|
|||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
dexFile.place();
|
dexFile.place(false);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput();
|
ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user