mirror of
https://github.com/revanced/smali.git
synced 2025-05-20 16:07:05 +02:00
Refactor how information about indexed items are exposed in DexBackedDexFile
This adds a unified IndexedSection/OptionalIndexedSection class for all indexed items
This commit is contained in:
parent
2412f1f741
commit
8faa4b31ec
@ -63,7 +63,7 @@ public class DisassemblyTest extends DexTest {
|
|||||||
protected void runTest(@Nonnull String testName, @Nonnull BaksmaliOptions options) {
|
protected void runTest(@Nonnull String testName, @Nonnull BaksmaliOptions options) {
|
||||||
try {
|
try {
|
||||||
DexBackedDexFile inputDex = getInputDexFile(testName, options);
|
DexBackedDexFile inputDex = getInputDexFile(testName, options);
|
||||||
Assert.assertEquals(1, inputDex.getClassCount());
|
Assert.assertEquals(1, inputDex.getClassSection().size());
|
||||||
ClassDef inputClass = Iterables.getFirst(inputDex.getClasses(), null);
|
ClassDef inputClass = Iterables.getFirst(inputDex.getClasses(), null);
|
||||||
Assert.assertNotNull(inputClass);
|
Assert.assertNotNull(inputClass);
|
||||||
String input = BaksmaliTestUtils.getNormalizedSmali(inputClass, options, true);
|
String input = BaksmaliTestUtils.getNormalizedSmali(inputClass, options, true);
|
||||||
|
@ -36,8 +36,8 @@ import org.jf.util.ExceptionWithContext;
|
|||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public class BaseDexBuffer {
|
public class BaseDexBuffer {
|
||||||
@Nonnull /* package private */ final byte[] buf;
|
@Nonnull final byte[] buf;
|
||||||
/* package private */ final int baseOffset;
|
final int baseOffset;
|
||||||
|
|
||||||
public BaseDexBuffer(@Nonnull byte[] buf) {
|
public BaseDexBuffer(@Nonnull byte[] buf) {
|
||||||
this(buf, 0);
|
this(buf, 0);
|
||||||
|
@ -55,7 +55,7 @@ public class DexBackedAnnotation extends BaseAnnotation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override public int getVisibility() { return visibility; }
|
@Override public int getVisibility() { return visibility; }
|
||||||
@Nonnull @Override public String getType() { return dexFile.getType(typeIndex); }
|
@Nonnull @Override public String getType() { return dexFile.getTypeSection().get(typeIndex); }
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
|
@ -48,6 +48,6 @@ public class DexBackedAnnotationElement extends BaseAnnotationElement {
|
|||||||
this.value = DexBackedEncodedValue.readFrom(reader);
|
this.value = DexBackedEncodedValue.readFrom(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull @Override public String getName() { return dexFile.getString(nameIndex); }
|
@Nonnull @Override public String getName() { return dexFile.getStringSection().get(nameIndex); }
|
||||||
@Nonnull @Override public EncodedValue getValue() { return value; }
|
@Nonnull @Override public EncodedValue getValue() { return value; }
|
||||||
}
|
}
|
||||||
|
@ -95,13 +95,13 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return dexFile.getType(dexFile.readSmallUint(classDefOffset + ClassDefItem.CLASS_OFFSET));
|
return dexFile.getTypeSection().get(dexFile.readSmallUint(classDefOffset + ClassDefItem.CLASS_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public String getSuperclass() {
|
public String getSuperclass() {
|
||||||
return dexFile.getOptionalType(dexFile.readOptionalUint(classDefOffset + ClassDefItem.SUPERCLASS_OFFSET));
|
return dexFile.getTypeSection().getOptional(dexFile.readOptionalUint(classDefOffset + ClassDefItem.SUPERCLASS_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -112,7 +112,8 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
|
|||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public String getSourceFile() {
|
public String getSourceFile() {
|
||||||
return dexFile.getOptionalString(dexFile.readOptionalUint(classDefOffset + ClassDefItem.SOURCE_FILE_OFFSET));
|
return dexFile.getStringSection().getOptional(
|
||||||
|
dexFile.readOptionalUint(classDefOffset + ClassDefItem.SOURCE_FILE_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@ -125,7 +126,7 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
|
|||||||
@Override
|
@Override
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public String get(int index) {
|
public String get(int index) {
|
||||||
return dexFile.getType(dexFile.readUshort(interfacesOffset + 4 + (2*index)));
|
return dexFile.getTypeSection().get(dexFile.readUshort(interfacesOffset + 4 + (2*index)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int size() { return size; }
|
@Override public int size() { return size; }
|
||||||
|
@ -35,16 +35,12 @@ import com.google.common.io.ByteStreams;
|
|||||||
import org.jf.dexlib2.Opcodes;
|
import org.jf.dexlib2.Opcodes;
|
||||||
import org.jf.dexlib2.ReferenceType;
|
import org.jf.dexlib2.ReferenceType;
|
||||||
import org.jf.dexlib2.dexbacked.raw.*;
|
import org.jf.dexlib2.dexbacked.raw.*;
|
||||||
import org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference;
|
import org.jf.dexlib2.dexbacked.reference.*;
|
||||||
import org.jf.dexlib2.dexbacked.reference.DexBackedMethodReference;
|
|
||||||
import org.jf.dexlib2.dexbacked.reference.DexBackedStringReference;
|
|
||||||
import org.jf.dexlib2.dexbacked.reference.DexBackedTypeReference;
|
|
||||||
import org.jf.dexlib2.dexbacked.util.FixedSizeList;
|
import org.jf.dexlib2.dexbacked.util.FixedSizeList;
|
||||||
import org.jf.dexlib2.dexbacked.util.FixedSizeSet;
|
import org.jf.dexlib2.dexbacked.util.FixedSizeSet;
|
||||||
import org.jf.dexlib2.iface.DexFile;
|
import org.jf.dexlib2.iface.DexFile;
|
||||||
import org.jf.dexlib2.iface.reference.Reference;
|
import org.jf.dexlib2.iface.reference.*;
|
||||||
import org.jf.dexlib2.util.DexUtil;
|
import org.jf.dexlib2.util.DexUtil;
|
||||||
import org.jf.util.ExceptionWithContext;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@ -123,7 +119,7 @@ public class DexBackedDexFile extends BaseDexBuffer implements DexFile {
|
|||||||
return new DexBackedDexFile(opcodes, buf, 0, false);
|
return new DexBackedDexFile(opcodes, buf, 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override @Nonnull public Opcodes getOpcodes() {
|
@Nonnull public Opcodes getOpcodes() {
|
||||||
return opcodes;
|
return opcodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,13 +128,12 @@ public class DexBackedDexFile extends BaseDexBuffer implements DexFile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
|
||||||
public Set<? extends DexBackedClassDef> getClasses() {
|
public Set<? extends DexBackedClassDef> getClasses() {
|
||||||
return new FixedSizeSet<DexBackedClassDef>() {
|
return new FixedSizeSet<DexBackedClassDef>() {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public DexBackedClassDef readItem(int index) {
|
public DexBackedClassDef readItem(int index) {
|
||||||
return new DexBackedClassDef(DexBackedDexFile.this, getClassDefItemOffset(index));
|
return getClassSection().get(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -148,192 +143,32 @@ public class DexBackedDexFile extends BaseDexBuffer implements DexFile {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getStringIdItemOffset(int stringIndex) {
|
public List<DexBackedStringReference> getStringReferences() {
|
||||||
if (stringIndex < 0 || stringIndex >= stringCount) {
|
|
||||||
throw new InvalidItemIndex(stringIndex, "String index out of bounds: %d", stringIndex);
|
|
||||||
}
|
|
||||||
return stringStartOffset + stringIndex*StringIdItem.ITEM_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTypeIdItemOffset(int typeIndex) {
|
|
||||||
if (typeIndex < 0 || typeIndex >= typeCount) {
|
|
||||||
throw new InvalidItemIndex(typeIndex, "Type index out of bounds: %d", typeIndex);
|
|
||||||
}
|
|
||||||
return typeStartOffset + typeIndex*TypeIdItem.ITEM_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getFieldIdItemOffset(int fieldIndex) {
|
|
||||||
if (fieldIndex < 0 || fieldIndex >= fieldCount) {
|
|
||||||
throw new InvalidItemIndex(fieldIndex, "Field index out of bounds: %d", fieldIndex);
|
|
||||||
}
|
|
||||||
return fieldStartOffset + fieldIndex*FieldIdItem.ITEM_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMethodIdItemOffset(int methodIndex) {
|
|
||||||
if (methodIndex < 0 || methodIndex >= methodCount) {
|
|
||||||
throw new InvalidItemIndex(methodIndex, "Method index out of bounds: %d", methodIndex);
|
|
||||||
}
|
|
||||||
return methodStartOffset + methodIndex*MethodIdItem.ITEM_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getProtoIdItemOffset(int protoIndex) {
|
|
||||||
if (protoIndex < 0 || protoIndex >= protoCount) {
|
|
||||||
throw new InvalidItemIndex(protoIndex, "Proto index out of bounds: %d", protoIndex);
|
|
||||||
}
|
|
||||||
return protoStartOffset + protoIndex*ProtoIdItem.ITEM_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getClassDefItemOffset(int classIndex) {
|
|
||||||
if (classIndex < 0 || classIndex >= classCount) {
|
|
||||||
throw new InvalidItemIndex(classIndex, "Class index out of bounds: %d", classIndex);
|
|
||||||
}
|
|
||||||
return classStartOffset + classIndex*ClassDefItem.ITEM_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCallSiteIdItemOffset(int callSiteIndex) {
|
|
||||||
MapItem mapItem = getMapItemForSection(ItemType.CALL_SITE_ID_ITEM);
|
|
||||||
if (mapItem == null || callSiteIndex >= mapItem.getItemCount()) {
|
|
||||||
throw new InvalidItemIndex(callSiteIndex, "Call site index out of bounds: %d", callSiteIndex);
|
|
||||||
}
|
|
||||||
return mapItem.getOffset() + callSiteIndex * CallSiteIdItem.ITEM_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMethodHandleItemOffset(int methodHandleIndex) {
|
|
||||||
MapItem mapItem = getMapItemForSection(ItemType.METHOD_HANDLE_ITEM);
|
|
||||||
if (mapItem == null || methodHandleIndex >= mapItem.getItemCount()) {
|
|
||||||
throw new InvalidItemIndex(methodHandleIndex , "Method handle index out of bounds: %d", methodHandleIndex);
|
|
||||||
}
|
|
||||||
return mapItem.getOffset() + methodHandleIndex * MethodHandleItem.ITEM_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getClassCount() {
|
|
||||||
return classCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getStringCount() {
|
|
||||||
return stringCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTypeCount() {
|
|
||||||
return typeCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getProtoCount() {
|
|
||||||
return protoCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getFieldCount() {
|
|
||||||
return fieldCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMethodCount() {
|
|
||||||
return methodCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCallSiteCount() {
|
|
||||||
MapItem mapItem = getMapItemForSection(ItemType.CALL_SITE_ID_ITEM);
|
|
||||||
if (mapItem == null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return mapItem.getItemCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMethodHandleCount() {
|
|
||||||
MapItem mapItem = getMapItemForSection(ItemType.METHOD_HANDLE_ITEM);
|
|
||||||
if (mapItem == null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return mapItem.getItemCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
public String getString(int stringIndex) {
|
|
||||||
int stringOffset = getStringIdItemOffset(stringIndex);
|
|
||||||
int stringDataOffset = readSmallUint(stringOffset);
|
|
||||||
DexReader reader = readerAt(stringDataOffset);
|
|
||||||
int utf16Length = reader.readSmallUleb128();
|
|
||||||
return reader.readString(utf16Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public String getOptionalString(int stringIndex) {
|
|
||||||
if (stringIndex == -1) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return getString(stringIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
public String getType(int typeIndex) {
|
|
||||||
int typeOffset = getTypeIdItemOffset(typeIndex);
|
|
||||||
int stringIndex = readSmallUint(typeOffset);
|
|
||||||
return getString(stringIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public String getOptionalType(int typeIndex) {
|
|
||||||
if (typeIndex == -1) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return getType(typeIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<DexBackedStringReference> getStrings() {
|
|
||||||
return new AbstractList<DexBackedStringReference>() {
|
return new AbstractList<DexBackedStringReference>() {
|
||||||
@Override public DexBackedStringReference get(int index) {
|
@Override public DexBackedStringReference get(int index) {
|
||||||
if (index < 0 || index >= getStringCount()) {
|
if (index < 0 || index >= getStringSection().size()) {
|
||||||
throw new IndexOutOfBoundsException();
|
throw new IndexOutOfBoundsException();
|
||||||
}
|
}
|
||||||
return new DexBackedStringReference(DexBackedDexFile.this, index);
|
return new DexBackedStringReference(DexBackedDexFile.this, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int size() {
|
@Override public int size() {
|
||||||
return getStringCount();
|
return getStringSection().size();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<DexBackedTypeReference> getTypes() {
|
public List<DexBackedTypeReference> getTypeReferences() {
|
||||||
return new AbstractList<DexBackedTypeReference>() {
|
return new AbstractList<DexBackedTypeReference>() {
|
||||||
@Override public DexBackedTypeReference get(int index) {
|
@Override public DexBackedTypeReference get(int index) {
|
||||||
if (index < 0 || index >= getTypeCount()) {
|
if (index < 0 || index >= getTypeSection().size()) {
|
||||||
throw new IndexOutOfBoundsException();
|
throw new IndexOutOfBoundsException();
|
||||||
}
|
}
|
||||||
return new DexBackedTypeReference(DexBackedDexFile.this, index);
|
return new DexBackedTypeReference(DexBackedDexFile.this, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int size() {
|
@Override public int size() {
|
||||||
return getTypeCount();
|
return getTypeSection().size();
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<DexBackedMethodReference> getMethods() {
|
|
||||||
return new AbstractList<DexBackedMethodReference>() {
|
|
||||||
@Override public DexBackedMethodReference get(int index) {
|
|
||||||
if (index < 0 || index >= getMethodCount()) {
|
|
||||||
throw new IndexOutOfBoundsException();
|
|
||||||
}
|
|
||||||
return new DexBackedMethodReference(DexBackedDexFile.this, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public int size() {
|
|
||||||
return getMethodCount();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<DexBackedFieldReference> getFields() {
|
|
||||||
return new AbstractList<DexBackedFieldReference>() {
|
|
||||||
@Override public DexBackedFieldReference get(int index) {
|
|
||||||
if (index < 0 || index >= getFieldCount()) {
|
|
||||||
throw new IndexOutOfBoundsException();
|
|
||||||
}
|
|
||||||
return new DexBackedFieldReference(DexBackedDexFile.this, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public int size() {
|
|
||||||
return getFieldCount();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -341,13 +176,13 @@ public class DexBackedDexFile extends BaseDexBuffer implements DexFile {
|
|||||||
public List<? extends Reference> getReferences(int referenceType) {
|
public List<? extends Reference> getReferences(int referenceType) {
|
||||||
switch (referenceType) {
|
switch (referenceType) {
|
||||||
case ReferenceType.STRING:
|
case ReferenceType.STRING:
|
||||||
return getStrings();
|
return getStringReferences();
|
||||||
case ReferenceType.TYPE:
|
case ReferenceType.TYPE:
|
||||||
return getTypes();
|
return getTypeReferences();
|
||||||
case ReferenceType.METHOD:
|
case ReferenceType.METHOD:
|
||||||
return getMethods();
|
return getMethodSection();
|
||||||
case ReferenceType.FIELD:
|
case ReferenceType.FIELD:
|
||||||
return getFields();
|
return getFieldSection();
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException(String.format("Invalid reference type: %d", referenceType));
|
throw new IllegalArgumentException(String.format("Invalid reference type: %d", referenceType));
|
||||||
}
|
}
|
||||||
@ -402,21 +237,259 @@ public class DexBackedDexFile extends BaseDexBuffer implements DexFile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class InvalidItemIndex extends ExceptionWithContext {
|
private OptionalIndexedSection<String> stringSection = new OptionalIndexedSection<String>() {
|
||||||
private final int itemIndex;
|
@Override
|
||||||
|
public String get(int index) {
|
||||||
public InvalidItemIndex(int itemIndex) {
|
int stringOffset = getOffset(index);
|
||||||
super("");
|
int stringDataOffset = readSmallUint(stringOffset);
|
||||||
this.itemIndex = itemIndex;
|
DexReader reader = readerAt(stringDataOffset);
|
||||||
|
int utf16Length = reader.readSmallUleb128();
|
||||||
|
return reader.readString(utf16Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public InvalidItemIndex(int itemIndex, String message, Object... formatArgs) {
|
@Override
|
||||||
super(message, formatArgs);
|
public int size() {
|
||||||
this.itemIndex = itemIndex;
|
return stringCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getInvalidIndex() {
|
@Nullable
|
||||||
return itemIndex;
|
@Override
|
||||||
}
|
public String getOptional(int index) {
|
||||||
|
if (index == -1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOffset(int index) {
|
||||||
|
if (index < 0 || index >= size()) {
|
||||||
|
throw new IndexOutOfBoundsException(
|
||||||
|
String.format("Invalid string index %d, not in [0, %d)", index, size()));
|
||||||
|
}
|
||||||
|
return stringStartOffset + index*StringIdItem.ITEM_SIZE;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public OptionalIndexedSection<String> getStringSection() {
|
||||||
|
return stringSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
private OptionalIndexedSection<String> typeSection = new OptionalIndexedSection<String>() {
|
||||||
|
@Override
|
||||||
|
public String get(int index) {
|
||||||
|
int typeOffset = getOffset(index);
|
||||||
|
int stringIndex = readSmallUint(typeOffset);
|
||||||
|
return getStringSection().get(stringIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return typeCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public String getOptional(int index) {
|
||||||
|
if (index == -1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOffset(int index) {
|
||||||
|
if (index < 0 || index >= size()) {
|
||||||
|
throw new IndexOutOfBoundsException(
|
||||||
|
String.format("Invalid type index %d, not in [0, %d)", index, size()));
|
||||||
|
}
|
||||||
|
return typeStartOffset + index * TypeIdItem.ITEM_SIZE;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public OptionalIndexedSection<String> getTypeSection() {
|
||||||
|
return typeSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IndexedSection<FieldReference> fieldSection = new IndexedSection<FieldReference>() {
|
||||||
|
@Override
|
||||||
|
public FieldReference get(int index) {
|
||||||
|
return new DexBackedFieldReference(DexBackedDexFile.this, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return fieldCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOffset(int index) {
|
||||||
|
if (index < 0 || index >= size()) {
|
||||||
|
throw new IndexOutOfBoundsException(
|
||||||
|
String.format("Invalid field index %d, not in [0, %d)", index, size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return fieldStartOffset + index * FieldIdItem.ITEM_SIZE;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public IndexedSection<FieldReference> getFieldSection() {
|
||||||
|
return fieldSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IndexedSection<MethodReference> methodSection = new IndexedSection<MethodReference>() {
|
||||||
|
@Override
|
||||||
|
public MethodReference get(int index) {
|
||||||
|
return new DexBackedMethodReference(DexBackedDexFile.this, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return methodCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOffset(int index) {
|
||||||
|
if (index < 0 || index >= size()) {
|
||||||
|
throw new IndexOutOfBoundsException(
|
||||||
|
String.format("Invalid method index %d, not in [0, %d)", index, size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return methodStartOffset + index * MethodIdItem.ITEM_SIZE;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public IndexedSection<MethodReference> getMethodSection() {
|
||||||
|
return methodSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IndexedSection<MethodProtoReference> protoSection = new IndexedSection<MethodProtoReference>() {
|
||||||
|
@Override
|
||||||
|
public MethodProtoReference get(int index) {
|
||||||
|
return new DexBackedMethodProtoReference(DexBackedDexFile.this, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return protoCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOffset(int index) {
|
||||||
|
if (index < 0 || index >= size()) {
|
||||||
|
throw new IndexOutOfBoundsException(
|
||||||
|
String.format("Invalid proto index %d, not in [0, %d)", index, size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return protoStartOffset + index * ProtoIdItem.ITEM_SIZE;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public IndexedSection<MethodProtoReference> getProtoSection() {
|
||||||
|
return protoSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IndexedSection<DexBackedClassDef> classSection = new IndexedSection<DexBackedClassDef>() {
|
||||||
|
@Override
|
||||||
|
public DexBackedClassDef get(int index) {
|
||||||
|
return new DexBackedClassDef(DexBackedDexFile.this, getOffset(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return classCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOffset(int index) {
|
||||||
|
if (index < 0 || index >= size()) {
|
||||||
|
throw new IndexOutOfBoundsException(
|
||||||
|
String.format("Invalid class index %d, not in [0, %d)", index, size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return classStartOffset + index * ClassDefItem.ITEM_SIZE;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public IndexedSection<DexBackedClassDef> getClassSection() {
|
||||||
|
return classSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IndexedSection<CallSiteReference> callSiteSection = new IndexedSection<CallSiteReference>() {
|
||||||
|
@Override
|
||||||
|
public CallSiteReference get(int index) {
|
||||||
|
return new DexBackedCallSiteReference(DexBackedDexFile.this, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
MapItem mapItem = getMapItemForSection(ItemType.CALL_SITE_ID_ITEM);
|
||||||
|
if (mapItem == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return mapItem.getItemCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOffset(int index) {
|
||||||
|
MapItem mapItem = getMapItemForSection(ItemType.CALL_SITE_ID_ITEM);
|
||||||
|
if (index < 0 || index >= size()) {
|
||||||
|
throw new IndexOutOfBoundsException(
|
||||||
|
String.format("Invalid callsite index %d, not in [0, %d)", index, size()));
|
||||||
|
}
|
||||||
|
return mapItem.getOffset() + index * CallSiteIdItem.ITEM_SIZE;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public IndexedSection<CallSiteReference> getCallSiteSection() {
|
||||||
|
return callSiteSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IndexedSection<MethodHandleReference> methodHandleSection = new IndexedSection<MethodHandleReference>() {
|
||||||
|
@Override
|
||||||
|
public MethodHandleReference get(int index) {
|
||||||
|
return new DexBackedMethodHandleReference(DexBackedDexFile.this, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
MapItem mapItem = getMapItemForSection(ItemType.METHOD_HANDLE_ITEM);
|
||||||
|
if (mapItem == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return mapItem.getItemCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOffset(int index) {
|
||||||
|
MapItem mapItem = getMapItemForSection(ItemType.METHOD_HANDLE_ITEM);
|
||||||
|
if (index < 0 || index >= size()) {
|
||||||
|
throw new IndexOutOfBoundsException(
|
||||||
|
String.format("Invalid method handle index %d, not in [0, %d)", index, size()));
|
||||||
|
}
|
||||||
|
return mapItem.getOffset() + index * MethodHandleItem.ITEM_SIZE;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public IndexedSection<MethodHandleReference> getMethodHandleSection() {
|
||||||
|
return methodHandleSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static abstract class OptionalIndexedSection<T> extends IndexedSection<T> {
|
||||||
|
/**
|
||||||
|
* @param index The index of the item, or -1 for a null item.
|
||||||
|
* @return The value at the given index, or null if index is -1.
|
||||||
|
* @throws IndexOutOfBoundsException if the index is out of bounds and is not -1.
|
||||||
|
*/
|
||||||
|
@Nullable public abstract T getOptional(int index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static abstract class IndexedSection<T> extends AbstractList<T> {
|
||||||
|
/**
|
||||||
|
* @param index The index of the item to get the offset for.
|
||||||
|
* @return The offset from the beginning of the dex file to the specified item.
|
||||||
|
* @throws IndexOutOfBoundsException if the index is out of bounds.
|
||||||
|
*/
|
||||||
|
public abstract int getOffset(int index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,13 +101,13 @@ public class DexBackedField extends BaseFieldReference implements Field {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return dexFile.getString(dexFile.readSmallUint(getFieldIdItemOffset() + FieldIdItem.NAME_OFFSET));
|
return dexFile.getStringSection().get(dexFile.readSmallUint(getFieldIdItemOffset() + FieldIdItem.NAME_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return dexFile.getType(dexFile.readUshort(getFieldIdItemOffset() + FieldIdItem.TYPE_OFFSET));
|
return dexFile.getTypeSection().get(dexFile.readUshort(getFieldIdItemOffset() + FieldIdItem.TYPE_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull @Override public String getDefiningClass() { return classDef.getType(); }
|
@Nonnull @Override public String getDefiningClass() { return classDef.getType(); }
|
||||||
@ -135,7 +135,7 @@ public class DexBackedField extends BaseFieldReference implements Field {
|
|||||||
|
|
||||||
private int getFieldIdItemOffset() {
|
private int getFieldIdItemOffset() {
|
||||||
if (fieldIdItemOffset == 0) {
|
if (fieldIdItemOffset == 0) {
|
||||||
fieldIdItemOffset = dexFile.getFieldIdItemOffset(fieldIndex);
|
fieldIdItemOffset = dexFile.getFieldSection().getOffset(fieldIndex);
|
||||||
}
|
}
|
||||||
return fieldIdItemOffset;
|
return fieldIdItemOffset;
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,6 @@ import org.jf.dexlib2.dexbacked.util.FixedSizeList;
|
|||||||
import org.jf.dexlib2.dexbacked.util.ParameterIterator;
|
import org.jf.dexlib2.dexbacked.util.ParameterIterator;
|
||||||
import org.jf.dexlib2.iface.Annotation;
|
import org.jf.dexlib2.iface.Annotation;
|
||||||
import org.jf.dexlib2.iface.Method;
|
import org.jf.dexlib2.iface.Method;
|
||||||
import org.jf.dexlib2.iface.MethodImplementation;
|
|
||||||
import org.jf.dexlib2.iface.MethodParameter;
|
import org.jf.dexlib2.iface.MethodParameter;
|
||||||
import org.jf.util.AbstractForwardSequentialList;
|
import org.jf.util.AbstractForwardSequentialList;
|
||||||
|
|
||||||
@ -115,13 +114,14 @@ public class DexBackedMethod extends BaseMethodReference implements Method {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return dexFile.getString(dexFile.readSmallUint(getMethodIdItemOffset() + MethodIdItem.NAME_OFFSET));
|
return dexFile.getStringSection().get(dexFile.readSmallUint(getMethodIdItemOffset() + MethodIdItem.NAME_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String getReturnType() {
|
public String getReturnType() {
|
||||||
return dexFile.getType(dexFile.readSmallUint(getProtoIdItemOffset() + ProtoIdItem.RETURN_TYPE_OFFSET));
|
return dexFile.getTypeSection().get(
|
||||||
|
dexFile.readSmallUint(getProtoIdItemOffset() + ProtoIdItem.RETURN_TYPE_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@ -171,7 +171,7 @@ public class DexBackedMethod extends BaseMethodReference implements Method {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String readItem(final int index) {
|
public String readItem(final int index) {
|
||||||
return dexFile.getType(dexFile.readUshort(paramListStart + 2*index));
|
return dexFile.getTypeSection().get(dexFile.readUshort(paramListStart + 2*index));
|
||||||
}
|
}
|
||||||
@Override public int size() { return parameterCount; }
|
@Override public int size() { return parameterCount; }
|
||||||
};
|
};
|
||||||
@ -196,7 +196,7 @@ public class DexBackedMethod extends BaseMethodReference implements Method {
|
|||||||
|
|
||||||
private int getMethodIdItemOffset() {
|
private int getMethodIdItemOffset() {
|
||||||
if (methodIdItemOffset == 0) {
|
if (methodIdItemOffset == 0) {
|
||||||
methodIdItemOffset = dexFile.getMethodIdItemOffset(methodIndex);
|
methodIdItemOffset = dexFile.getMethodSection().getOffset(methodIndex);
|
||||||
}
|
}
|
||||||
return methodIdItemOffset;
|
return methodIdItemOffset;
|
||||||
}
|
}
|
||||||
@ -204,7 +204,7 @@ public class DexBackedMethod extends BaseMethodReference implements Method {
|
|||||||
private int getProtoIdItemOffset() {
|
private int getProtoIdItemOffset() {
|
||||||
if (protoIdItemOffset == 0) {
|
if (protoIdItemOffset == 0) {
|
||||||
int protoIndex = dexFile.readUshort(getMethodIdItemOffset() + MethodIdItem.PROTO_OFFSET);
|
int protoIndex = dexFile.readUshort(getMethodIdItemOffset() + MethodIdItem.PROTO_OFFSET);
|
||||||
protoIdItemOffset = dexFile.getProtoIdItemOffset(protoIndex);
|
protoIdItemOffset = dexFile.getProtoSection().getOffset(protoIndex);
|
||||||
}
|
}
|
||||||
return protoIdItemOffset;
|
return protoIdItemOffset;
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,6 @@ public class DexBackedTypedExceptionHandler extends DexBackedExceptionHandler {
|
|||||||
this.handlerCodeAddress = reader.readSmallUleb128();
|
this.handlerCodeAddress = reader.readSmallUleb128();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull @Override public String getExceptionType() { return dexFile.getType(typeId); }
|
@Nonnull @Override public String getExceptionType() { return dexFile.getTypeSection().get(typeId); }
|
||||||
@Override public int getHandlerCodeAddress() { return handlerCodeAddress; }
|
@Override public int getHandlerCodeAddress() { return handlerCodeAddress; }
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ public class AnnotationItem {
|
|||||||
DexReader reader = dexFile.readerAt(annotationItemOffset);
|
DexReader reader = dexFile.readerAt(annotationItemOffset);
|
||||||
reader.readUbyte();
|
reader.readUbyte();
|
||||||
int typeIndex = reader.readSmallUleb128();
|
int typeIndex = reader.readSmallUleb128();
|
||||||
String annotationType = dexFile.getType(typeIndex);
|
String annotationType = dexFile.getTypeSection().get(typeIndex);
|
||||||
return String.format("annotation_item[0x%x]: %s", annotationItemOffset, annotationType);
|
return String.format("annotation_item[0x%x]: %s", annotationItemOffset, annotationType);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
ex.printStackTrace(System.err);
|
ex.printStackTrace(System.err);
|
||||||
|
@ -98,7 +98,7 @@ public class ClassDefItem {
|
|||||||
out.annotate(4, "class_data_off = class_data_item[NO_OFFSET]");
|
out.annotate(4, "class_data_off = class_data_item[NO_OFFSET]");
|
||||||
} else {
|
} else {
|
||||||
out.annotate(4, "class_data_off = class_data_item[0x%x]", classDataOffset);
|
out.annotate(4, "class_data_off = class_data_item[0x%x]", classDataOffset);
|
||||||
addClassDataIdentity(classDataOffset, dexFile.getType(classIndex));
|
addClassDataIdentity(classDataOffset, dexFile.getTypeSection().get(classIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
int staticValuesOffset = dexFile.readSmallUint(out.getCursor());
|
int staticValuesOffset = dexFile.readSmallUint(out.getCursor());
|
||||||
@ -119,9 +119,9 @@ public class ClassDefItem {
|
|||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static String asString(@Nonnull DexBackedDexFile dexFile, int classIndex) {
|
public static String asString(@Nonnull DexBackedDexFile dexFile, int classIndex) {
|
||||||
int offset = dexFile.getClassDefItemOffset(classIndex);
|
int offset = dexFile.getClassSection().getOffset(classIndex);
|
||||||
int typeIndex = dexFile.readSmallUint(offset + CLASS_OFFSET);
|
int typeIndex = dexFile.readSmallUint(offset + CLASS_OFFSET);
|
||||||
return dexFile.getType(typeIndex);
|
return dexFile.getTypeSection().get(typeIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String[] getClasses(@Nonnull RawDexFile dexFile) {
|
public static String[] getClasses(@Nonnull RawDexFile dexFile) {
|
||||||
|
@ -68,15 +68,15 @@ public class FieldIdItem {
|
|||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static String asString(@Nonnull DexBackedDexFile dexFile, int fieldIndex) {
|
public static String asString(@Nonnull DexBackedDexFile dexFile, int fieldIndex) {
|
||||||
int fieldOffset = dexFile.getFieldIdItemOffset(fieldIndex);
|
int fieldOffset = dexFile.getFieldSection().getOffset(fieldIndex);
|
||||||
int classIndex = dexFile.readUshort(fieldOffset + CLASS_OFFSET);
|
int classIndex = dexFile.readUshort(fieldOffset + CLASS_OFFSET);
|
||||||
String classType = dexFile.getType(classIndex);
|
String classType = dexFile.getTypeSection().get(classIndex);
|
||||||
|
|
||||||
int typeIndex = dexFile.readUshort(fieldOffset + TYPE_OFFSET);
|
int typeIndex = dexFile.readUshort(fieldOffset + TYPE_OFFSET);
|
||||||
String fieldType = dexFile.getType(typeIndex);
|
String fieldType = dexFile.getTypeSection().get(typeIndex);
|
||||||
|
|
||||||
int nameIndex = dexFile.readSmallUint(fieldOffset + NAME_OFFSET);
|
int nameIndex = dexFile.readSmallUint(fieldOffset + NAME_OFFSET);
|
||||||
String fieldName = dexFile.getString(nameIndex);
|
String fieldName = dexFile.getStringSection().get(nameIndex);
|
||||||
|
|
||||||
return String.format("%s->%s:%s", classType, fieldName, fieldType);
|
return String.format("%s->%s:%s", classType, fieldName, fieldType);
|
||||||
}
|
}
|
||||||
|
@ -68,15 +68,15 @@ public class MethodIdItem {
|
|||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static String asString(@Nonnull DexBackedDexFile dexFile, int methodIndex) {
|
public static String asString(@Nonnull DexBackedDexFile dexFile, int methodIndex) {
|
||||||
int methodOffset = dexFile.getMethodIdItemOffset(methodIndex);
|
int methodOffset = dexFile.getMethodSection().getOffset(methodIndex);
|
||||||
int classIndex = dexFile.readUshort(methodOffset + CLASS_OFFSET);
|
int classIndex = dexFile.readUshort(methodOffset + CLASS_OFFSET);
|
||||||
String classType = dexFile.getType(classIndex);
|
String classType = dexFile.getTypeSection().get(classIndex);
|
||||||
|
|
||||||
int protoIndex = dexFile.readUshort(methodOffset + PROTO_OFFSET);
|
int protoIndex = dexFile.readUshort(methodOffset + PROTO_OFFSET);
|
||||||
String protoString = ProtoIdItem.asString(dexFile, protoIndex);
|
String protoString = ProtoIdItem.asString(dexFile, protoIndex);
|
||||||
|
|
||||||
int nameIndex = dexFile.readSmallUint(methodOffset + NAME_OFFSET);
|
int nameIndex = dexFile.readSmallUint(methodOffset + NAME_OFFSET);
|
||||||
String methodName = dexFile.getString(nameIndex);
|
String methodName = dexFile.getStringSection().get(nameIndex);
|
||||||
|
|
||||||
return String.format("%s->%s%s", classType, methodName, protoString);
|
return String.format("%s->%s%s", classType, methodName, protoString);
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ public class ProtoIdItem {
|
|||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static String asString(@Nonnull DexBackedDexFile dexFile, int protoIndex) {
|
public static String asString(@Nonnull DexBackedDexFile dexFile, int protoIndex) {
|
||||||
int offset = dexFile.getProtoIdItemOffset(protoIndex);
|
int offset = dexFile.getProtoSection().getOffset(protoIndex);
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append("(");
|
sb.append("(");
|
||||||
@ -89,7 +89,7 @@ public class ProtoIdItem {
|
|||||||
sb.append(")");
|
sb.append(")");
|
||||||
|
|
||||||
int returnTypeIndex = dexFile.readSmallUint(offset + RETURN_TYPE_OFFSET);
|
int returnTypeIndex = dexFile.readSmallUint(offset + RETURN_TYPE_OFFSET);
|
||||||
String returnType = dexFile.getType(returnTypeIndex);
|
String returnType = dexFile.getTypeSection().get(returnTypeIndex);
|
||||||
sb.append(returnType);
|
sb.append(returnType);
|
||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
|
@ -53,7 +53,7 @@ public class StringIdItem {
|
|||||||
public void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
public void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
|
||||||
int stringDataOffset = dexFile.readSmallUint(out.getCursor());
|
int stringDataOffset = dexFile.readSmallUint(out.getCursor());
|
||||||
try {
|
try {
|
||||||
String stringValue = dexFile.getString(itemIndex);
|
String stringValue = dexFile.getStringSection().get(itemIndex);
|
||||||
out.annotate(4, "string_data_item[0x%x]: \"%s\"", stringDataOffset,
|
out.annotate(4, "string_data_item[0x%x]: \"%s\"", stringDataOffset,
|
||||||
StringUtils.escapeString(stringValue));
|
StringUtils.escapeString(stringValue));
|
||||||
return;
|
return;
|
||||||
@ -76,7 +76,7 @@ public class StringIdItem {
|
|||||||
|
|
||||||
public static String getReferenceAnnotation(@Nonnull DexBackedDexFile dexFile, int stringIndex, boolean quote) {
|
public static String getReferenceAnnotation(@Nonnull DexBackedDexFile dexFile, int stringIndex, boolean quote) {
|
||||||
try {
|
try {
|
||||||
String string = dexFile.getString(stringIndex);
|
String string = dexFile.getStringSection().get(stringIndex);
|
||||||
if (quote) {
|
if (quote) {
|
||||||
string = String.format("\"%s\"", StringUtils.escapeString(string));
|
string = String.format("\"%s\"", StringUtils.escapeString(string));
|
||||||
}
|
}
|
||||||
@ -101,18 +101,4 @@ public class StringIdItem {
|
|||||||
}
|
}
|
||||||
return getReferenceAnnotation(dexFile, stringIndex, quote);
|
return getReferenceAnnotation(dexFile, stringIndex, quote);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String[] getStrings(@Nonnull RawDexFile dexFile) {
|
|
||||||
MapItem mapItem = dexFile.getMapItemForSection(ItemType.STRING_ID_ITEM);
|
|
||||||
if (mapItem == null) {
|
|
||||||
return new String[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
int stringCount = mapItem.getItemCount();
|
|
||||||
String[] ret = new String[stringCount];
|
|
||||||
for (int i=0; i<stringCount; i++) {
|
|
||||||
ret[i] = dexFile.getString(i);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ public class TypeIdItem {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
public static String getReferenceAnnotation(@Nonnull DexBackedDexFile dexFile, int typeIndex) {
|
public static String getReferenceAnnotation(@Nonnull DexBackedDexFile dexFile, int typeIndex) {
|
||||||
try {
|
try {
|
||||||
String typeString = dexFile.getType(typeIndex);
|
String typeString = dexFile.getTypeSection().get(typeIndex);
|
||||||
return String.format("type_id_item[%d]: %s", typeIndex, typeString);
|
return String.format("type_id_item[%d]: %s", typeIndex, typeString);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
ex.printStackTrace(System.err);
|
ex.printStackTrace(System.err);
|
||||||
@ -74,18 +74,4 @@ public class TypeIdItem {
|
|||||||
}
|
}
|
||||||
return getReferenceAnnotation(dexFile, typeIndex);
|
return getReferenceAnnotation(dexFile, typeIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String[] getTypes(@Nonnull RawDexFile dexFile) {
|
|
||||||
MapItem mapItem = dexFile.getMapItemForSection(ItemType.TYPE_ID_ITEM);
|
|
||||||
if (mapItem == null) {
|
|
||||||
return new String[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
int typeCount = mapItem.getItemCount();
|
|
||||||
String[] ret = new String[typeCount];
|
|
||||||
for (int i=0; i<typeCount; i++) {
|
|
||||||
ret[i] = dexFile.getType(i);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,7 @@ public class TypeListItem {
|
|||||||
int size = dexFile.readSmallUint(typeListOffset);
|
int size = dexFile.readSmallUint(typeListOffset);
|
||||||
for (int i=0; i<size; i++) {
|
for (int i=0; i<size; i++) {
|
||||||
int typeIndex = dexFile.readUshort(typeListOffset + 4 + i*2);
|
int typeIndex = dexFile.readUshort(typeListOffset + 4 + i*2);
|
||||||
String type = dexFile.getType(typeIndex);
|
String type = dexFile.getTypeSection().get(typeIndex);
|
||||||
sb.append(type);
|
sb.append(type);
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
|
@ -56,7 +56,7 @@ public class DexBackedCallSiteReference extends BaseCallSiteReference {
|
|||||||
public DexBackedCallSiteReference(DexBackedDexFile dexFile, int callSiteIndex) {
|
public DexBackedCallSiteReference(DexBackedDexFile dexFile, int callSiteIndex) {
|
||||||
this.dexFile = dexFile;
|
this.dexFile = dexFile;
|
||||||
this.callSiteIndex = callSiteIndex;
|
this.callSiteIndex = callSiteIndex;
|
||||||
this.callSiteIdOffset = dexFile.getCallSiteIdItemOffset(callSiteIndex);
|
this.callSiteIdOffset = dexFile.getCallSiteSection().getOffset(callSiteIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@ -160,7 +160,7 @@ public class DexBackedCallSiteReference extends BaseCallSiteReference {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void validateReference() throws InvalidReferenceException {
|
public void validateReference() throws InvalidReferenceException {
|
||||||
if (callSiteIndex < 0 || callSiteIndex >= dexFile.getCallSiteCount()) {
|
if (callSiteIndex < 0 || callSiteIndex >= dexFile.getCallSiteSection().size()) {
|
||||||
throw new InvalidReferenceException("callsite@" + callSiteIndex);
|
throw new InvalidReferenceException("callsite@" + callSiteIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,20 +49,22 @@ public class DexBackedFieldReference extends BaseFieldReference {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String getDefiningClass() {
|
public String getDefiningClass() {
|
||||||
return dexFile.getType(dexFile.readUshort(dexFile.getFieldIdItemOffset(fieldIndex) + FieldIdItem.CLASS_OFFSET));
|
return dexFile.getTypeSection().get(
|
||||||
|
dexFile.readUshort(dexFile.getFieldSection().getOffset(fieldIndex) + FieldIdItem.CLASS_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return dexFile.getString(dexFile.readSmallUint(dexFile.getFieldIdItemOffset(fieldIndex) +
|
return dexFile.getStringSection().get(dexFile.readSmallUint(dexFile.getFieldSection().getOffset(fieldIndex) +
|
||||||
FieldIdItem.NAME_OFFSET));
|
FieldIdItem.NAME_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return dexFile.getType(dexFile.readUshort(dexFile.getFieldIdItemOffset(fieldIndex) + FieldIdItem.TYPE_OFFSET));
|
return dexFile.getTypeSection().get(
|
||||||
|
dexFile.readUshort(dexFile.getFieldSection().getOffset(fieldIndex) + FieldIdItem.TYPE_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -78,7 +80,7 @@ public class DexBackedFieldReference extends BaseFieldReference {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void validateReference() throws InvalidReferenceException {
|
public void validateReference() throws InvalidReferenceException {
|
||||||
if (fieldIndex < 0 || fieldIndex >= dexFile.getFieldCount()) {
|
if (fieldIndex < 0 || fieldIndex >= dexFile.getFieldSection().size()) {
|
||||||
throw new InvalidReferenceException("field@" + fieldIndex);
|
throw new InvalidReferenceException("field@" + fieldIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ public class DexBackedMethodHandleReference extends BaseMethodHandleReference {
|
|||||||
public DexBackedMethodHandleReference(DexBackedDexFile dexFile, int methodHandleIndex) {
|
public DexBackedMethodHandleReference(DexBackedDexFile dexFile, int methodHandleIndex) {
|
||||||
this.dexFile = dexFile;
|
this.dexFile = dexFile;
|
||||||
this.methodHandleIndex = methodHandleIndex;
|
this.methodHandleIndex = methodHandleIndex;
|
||||||
this.methodHandleOffset = dexFile.getMethodHandleItemOffset(methodHandleIndex);
|
this.methodHandleOffset = dexFile.getMethodHandleSection().getOffset(methodHandleIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -79,7 +79,7 @@ public class DexBackedMethodHandleReference extends BaseMethodHandleReference {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void validateReference() throws InvalidReferenceException {
|
public void validateReference() throws InvalidReferenceException {
|
||||||
if (methodHandleIndex < 0 || methodHandleIndex >= dexFile.getMethodHandleCount()) {
|
if (methodHandleIndex < 0 || methodHandleIndex >= dexFile.getMethodHandleSection().size()) {
|
||||||
throw new InvalidReferenceException("methodhandle@" + methodHandleIndex);
|
throw new InvalidReferenceException("methodhandle@" + methodHandleIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ public class DexBackedMethodProtoReference extends BaseMethodProtoReference {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public List<String> getParameterTypes() {
|
public List<String> getParameterTypes() {
|
||||||
final int parametersOffset = dexFile.readSmallUint(dexFile.getProtoIdItemOffset(protoIndex) +
|
final int parametersOffset = dexFile.readSmallUint(dexFile.getProtoSection().getOffset(protoIndex) +
|
||||||
ProtoIdItem.PARAMETERS_OFFSET);
|
ProtoIdItem.PARAMETERS_OFFSET);
|
||||||
if (parametersOffset > 0) {
|
if (parametersOffset > 0) {
|
||||||
final int parameterCount = dexFile.readSmallUint(parametersOffset + TypeListItem.SIZE_OFFSET);
|
final int parameterCount = dexFile.readSmallUint(parametersOffset + TypeListItem.SIZE_OFFSET);
|
||||||
@ -62,7 +62,7 @@ public class DexBackedMethodProtoReference extends BaseMethodProtoReference {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String readItem(final int index) {
|
public String readItem(final int index) {
|
||||||
return dexFile.getType(dexFile.readUshort(paramListStart + 2*index));
|
return dexFile.getTypeSection().get(dexFile.readUshort(paramListStart + 2*index));
|
||||||
}
|
}
|
||||||
@Override public int size() { return parameterCount; }
|
@Override public int size() { return parameterCount; }
|
||||||
};
|
};
|
||||||
@ -73,7 +73,7 @@ public class DexBackedMethodProtoReference extends BaseMethodProtoReference {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String getReturnType() {
|
public String getReturnType() {
|
||||||
return dexFile.getType(dexFile.readSmallUint(dexFile.getProtoIdItemOffset(protoIndex) +
|
return dexFile.getTypeSection().get(dexFile.readSmallUint(dexFile.getProtoSection().getOffset(protoIndex) +
|
||||||
ProtoIdItem.RETURN_TYPE_OFFSET));
|
ProtoIdItem.RETURN_TYPE_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ public class DexBackedMethodProtoReference extends BaseMethodProtoReference {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void validateReference() throws InvalidReferenceException {
|
public void validateReference() throws InvalidReferenceException {
|
||||||
if (protoIndex < 0 || protoIndex >= dexFile.getProtoCount()) {
|
if (protoIndex < 0 || protoIndex >= dexFile.getProtoSection().size()) {
|
||||||
throw new InvalidReferenceException("proto@" + protoIndex);
|
throw new InvalidReferenceException("proto@" + protoIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,14 +55,14 @@ public class DexBackedMethodReference extends BaseMethodReference {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String getDefiningClass() {
|
public String getDefiningClass() {
|
||||||
return dexFile.getType(dexFile.readUshort(dexFile.getMethodIdItemOffset(methodIndex) +
|
return dexFile.getTypeSection().get(dexFile.readUshort(dexFile.getMethodSection().getOffset(methodIndex) +
|
||||||
MethodIdItem.CLASS_OFFSET));
|
MethodIdItem.CLASS_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return dexFile.getString(dexFile.readSmallUint(dexFile.getMethodIdItemOffset(methodIndex) +
|
return dexFile.getStringSection().get(dexFile.readSmallUint(dexFile.getMethodSection().getOffset(methodIndex) +
|
||||||
MethodIdItem.NAME_OFFSET));
|
MethodIdItem.NAME_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ public class DexBackedMethodReference extends BaseMethodReference {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String readItem(final int index) {
|
public String readItem(final int index) {
|
||||||
return dexFile.getType(dexFile.readUshort(paramListStart + 2*index));
|
return dexFile.getTypeSection().get(dexFile.readUshort(paramListStart + 2*index));
|
||||||
}
|
}
|
||||||
@Override public int size() { return parameterCount; }
|
@Override public int size() { return parameterCount; }
|
||||||
};
|
};
|
||||||
@ -90,13 +90,13 @@ public class DexBackedMethodReference extends BaseMethodReference {
|
|||||||
@Override
|
@Override
|
||||||
public String getReturnType() {
|
public String getReturnType() {
|
||||||
int protoIdItemOffset = getProtoIdItemOffset();
|
int protoIdItemOffset = getProtoIdItemOffset();
|
||||||
return dexFile.getType(dexFile.readSmallUint(protoIdItemOffset + ProtoIdItem.RETURN_TYPE_OFFSET));
|
return dexFile.getTypeSection().get(dexFile.readSmallUint(protoIdItemOffset + ProtoIdItem.RETURN_TYPE_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getProtoIdItemOffset() {
|
private int getProtoIdItemOffset() {
|
||||||
if (protoIdItemOffset == 0) {
|
if (protoIdItemOffset == 0) {
|
||||||
protoIdItemOffset = dexFile.getProtoIdItemOffset(
|
protoIdItemOffset = dexFile.getProtoSection().getOffset(
|
||||||
dexFile.readUshort(dexFile.getMethodIdItemOffset(methodIndex) + MethodIdItem.PROTO_OFFSET));
|
dexFile.readUshort(dexFile.getMethodSection().getOffset(methodIndex) + MethodIdItem.PROTO_OFFSET));
|
||||||
}
|
}
|
||||||
return protoIdItemOffset;
|
return protoIdItemOffset;
|
||||||
}
|
}
|
||||||
@ -114,7 +114,7 @@ public class DexBackedMethodReference extends BaseMethodReference {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void validateReference() throws InvalidReferenceException {
|
public void validateReference() throws InvalidReferenceException {
|
||||||
if (methodIndex < 0 || methodIndex >= dexFile.getMethodCount()) {
|
if (methodIndex < 0 || methodIndex >= dexFile.getMethodSection().size()) {
|
||||||
throw new InvalidReferenceException("method@" + methodIndex);
|
throw new InvalidReferenceException("method@" + methodIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,10 +50,9 @@ public class DexBackedStringReference extends BaseStringReference {
|
|||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public String getString() {
|
public String getString() {
|
||||||
return dexFile.getString(stringIndex);
|
return dexFile.getStringSection().get(stringIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate and return the private size of a string reference.
|
* Calculate and return the private size of a string reference.
|
||||||
*
|
*
|
||||||
@ -64,7 +63,7 @@ public class DexBackedStringReference extends BaseStringReference {
|
|||||||
public int getSize() {
|
public int getSize() {
|
||||||
int size = StringIdItem.ITEM_SIZE; //uint for string_data_off
|
int size = StringIdItem.ITEM_SIZE; //uint for string_data_off
|
||||||
//add the string data length:
|
//add the string data length:
|
||||||
int stringOffset = dexFile.getStringIdItemOffset(stringIndex);
|
int stringOffset = dexFile.getStringSection().getOffset(stringIndex);
|
||||||
int stringDataOffset = dexFile.readSmallUint(stringOffset);
|
int stringDataOffset = dexFile.readSmallUint(stringOffset);
|
||||||
DexReader reader = dexFile.readerAt(stringDataOffset);
|
DexReader reader = dexFile.readerAt(stringDataOffset);
|
||||||
size += reader.peekSmallUleb128Size();
|
size += reader.peekSmallUleb128Size();
|
||||||
@ -76,7 +75,7 @@ public class DexBackedStringReference extends BaseStringReference {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void validateReference() throws InvalidReferenceException {
|
public void validateReference() throws InvalidReferenceException {
|
||||||
if (stringIndex < 0 || stringIndex >= dexFile.getStringCount()) {
|
if (stringIndex < 0 || stringIndex >= dexFile.getStringSection().size()) {
|
||||||
throw new InvalidReferenceException("string@" + stringIndex);
|
throw new InvalidReferenceException("string@" + stringIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ public class DexBackedTypeReference extends BaseTypeReference {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull public String getType() {
|
@Nonnull public String getType() {
|
||||||
return dexFile.getType(typeIndex);
|
return dexFile.getTypeSection().get(typeIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ public class DexBackedTypeReference extends BaseTypeReference {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void validateReference() throws InvalidReferenceException {
|
public void validateReference() throws InvalidReferenceException {
|
||||||
if (typeIndex < 0 || typeIndex >= dexFile.getTypeCount()) {
|
if (typeIndex < 0 || typeIndex >= dexFile.getTypeSection().size()) {
|
||||||
throw new InvalidReferenceException("type@" + typeIndex);
|
throw new InvalidReferenceException("type@" + typeIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -190,8 +190,8 @@ public abstract class DebugInfo implements Iterable<DebugItem> {
|
|||||||
}
|
}
|
||||||
case DebugItemType.START_LOCAL: {
|
case DebugItemType.START_LOCAL: {
|
||||||
int register = reader.readSmallUleb128();
|
int register = reader.readSmallUleb128();
|
||||||
String name = dexFile.getOptionalString(reader.readSmallUleb128() - 1);
|
String name = dexFile.getStringSection().getOptional(reader.readSmallUleb128() - 1);
|
||||||
String type = dexFile.getOptionalType(reader.readSmallUleb128() - 1);
|
String type = dexFile.getTypeSection().getOptional(reader.readSmallUleb128() - 1);
|
||||||
ImmutableStartLocal startLocal =
|
ImmutableStartLocal startLocal =
|
||||||
new ImmutableStartLocal(codeAddress, register, name, type, null);
|
new ImmutableStartLocal(codeAddress, register, name, type, null);
|
||||||
if (register >= 0 && register < locals.length) {
|
if (register >= 0 && register < locals.length) {
|
||||||
@ -201,9 +201,10 @@ public abstract class DebugInfo implements Iterable<DebugItem> {
|
|||||||
}
|
}
|
||||||
case DebugItemType.START_LOCAL_EXTENDED: {
|
case DebugItemType.START_LOCAL_EXTENDED: {
|
||||||
int register = reader.readSmallUleb128();
|
int register = reader.readSmallUleb128();
|
||||||
String name = dexFile.getOptionalString(reader.readSmallUleb128() - 1);
|
String name = dexFile.getStringSection().getOptional(reader.readSmallUleb128() - 1);
|
||||||
String type = dexFile.getOptionalType(reader.readSmallUleb128() - 1);
|
String type = dexFile.getTypeSection().getOptional(reader.readSmallUleb128() - 1);
|
||||||
String signature = dexFile.getOptionalString(reader.readSmallUleb128() - 1);
|
String signature = dexFile.getStringSection().getOptional(
|
||||||
|
reader.readSmallUleb128() - 1);
|
||||||
ImmutableStartLocal startLocal =
|
ImmutableStartLocal startLocal =
|
||||||
new ImmutableStartLocal(codeAddress, register, name, type, signature);
|
new ImmutableStartLocal(codeAddress, register, name, type, signature);
|
||||||
if (register >= 0 && register < locals.length) {
|
if (register >= 0 && register < locals.length) {
|
||||||
@ -261,7 +262,8 @@ public abstract class DebugInfo implements Iterable<DebugItem> {
|
|||||||
return new ImmutableEpilogueBegin(codeAddress);
|
return new ImmutableEpilogueBegin(codeAddress);
|
||||||
}
|
}
|
||||||
case DebugItemType.SET_SOURCE_FILE: {
|
case DebugItemType.SET_SOURCE_FILE: {
|
||||||
String sourceFile = dexFile.getOptionalString(reader.readSmallUleb128() - 1);
|
String sourceFile = dexFile.getStringSection().getOptional(
|
||||||
|
reader.readSmallUleb128() - 1);
|
||||||
return new ImmutableSetSourceFile(codeAddress, sourceFile);
|
return new ImmutableSetSourceFile(codeAddress, sourceFile);
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@ -287,7 +289,7 @@ public abstract class DebugInfo implements Iterable<DebugItem> {
|
|||||||
final int parameterNameCount = reader.readSmallUleb128();
|
final int parameterNameCount = reader.readSmallUleb128();
|
||||||
return new VariableSizeIterator<String>(reader, parameterNameCount) {
|
return new VariableSizeIterator<String>(reader, parameterNameCount) {
|
||||||
@Override protected String readNextItem(@Nonnull DexReader reader, int index) {
|
@Override protected String readNextItem(@Nonnull DexReader reader, int index) {
|
||||||
return dexFile.getOptionalString(reader.readSmallUleb128() - 1);
|
return dexFile.getStringSection().getOptional(reader.readSmallUleb128() - 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ public class DexBackedAnnotationEncodedValue extends BaseAnnotationEncodedValue
|
|||||||
|
|
||||||
public DexBackedAnnotationEncodedValue(@Nonnull DexReader reader) {
|
public DexBackedAnnotationEncodedValue(@Nonnull DexReader reader) {
|
||||||
this.dexFile = reader.dexBuf;
|
this.dexFile = reader.dexBuf;
|
||||||
this.type = dexFile.getType(reader.readSmallUleb128());
|
this.type = dexFile.getTypeSection().get(reader.readSmallUleb128());
|
||||||
this.elementCount = reader.readSmallUleb128();
|
this.elementCount = reader.readSmallUleb128();
|
||||||
this.elementsOffset = reader.getOffset();
|
this.elementsOffset = reader.getOffset();
|
||||||
skipElements(reader, elementCount);
|
skipElements(reader, elementCount);
|
||||||
|
@ -47,6 +47,6 @@ public class DexBackedStringEncodedValue extends BaseStringEncodedValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull @Override public String getValue() {
|
@Nonnull @Override public String getValue() {
|
||||||
return dexFile.getString(stringIndex);
|
return dexFile.getStringSection().get(stringIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,6 @@ public class DexBackedTypeEncodedValue extends BaseTypeEncodedValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull @Override public String getValue() {
|
@Nonnull @Override public String getValue() {
|
||||||
return dexFile.getType(typeIndex);
|
return dexFile.getTypeSection().get(typeIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user