mirror of
https://github.com/revanced/smali.git
synced 2025-06-01 05:00:12 +02:00
Get rid of the separate DexBackedDexFile.Impl class
This commit is contained in:
parent
132eeaedf7
commit
12659ec7db
@ -93,7 +93,7 @@ public final class DexFileFactory {
|
|||||||
dexBytes = Files.toByteArray(dexFile);
|
dexBytes = Files.toByteArray(dexFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DexBackedDexFile.Impl(dexBytes);
|
return new DexBackedDexFile(dexBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void writeDexFile(String path, DexFile dexFile) throws IOException {
|
public static void writeDexFile(String path, DexFile dexFile) throws IOException {
|
||||||
|
@ -40,197 +40,170 @@ import javax.annotation.Nonnull;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public abstract class DexBackedDexFile extends BaseDexBuffer implements DexFile {
|
public class DexBackedDexFile extends BaseDexBuffer implements DexFile {
|
||||||
public DexBackedDexFile(@Nonnull byte[] buf) {
|
private final int stringCount;
|
||||||
super(buf);
|
private final int stringStartOffset;
|
||||||
|
private final int typeCount;
|
||||||
|
private final int typeStartOffset;
|
||||||
|
private final int protoCount;
|
||||||
|
private final int protoStartOffset;
|
||||||
|
private final int fieldCount;
|
||||||
|
private final int fieldStartOffset;
|
||||||
|
private final int methodCount;
|
||||||
|
private final int methodStartOffset;
|
||||||
|
private final int classCount;
|
||||||
|
private final int classStartOffset;
|
||||||
|
|
||||||
|
public DexBackedDexFile (@Nonnull BaseDexBuffer buf) {
|
||||||
|
this(buf.buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull public abstract String getString(int stringIndex);
|
public DexBackedDexFile (@Nonnull byte[] buf) {
|
||||||
@Nullable public abstract String getOptionalString(int stringIndex);
|
super(buf);
|
||||||
@Nonnull public abstract String getType(int typeIndex);
|
|
||||||
@Nullable public abstract String getOptionalType(int typeIndex);
|
|
||||||
|
|
||||||
// TODO: refactor how dex items are read
|
verifyMagic();
|
||||||
public abstract int getMethodIdItemOffset(int methodIndex);
|
verifyEndian();
|
||||||
public abstract int getProtoIdItemOffset(int protoIndex);
|
stringCount = readSmallUint(HeaderItem.STRING_COUNT_OFFSET);
|
||||||
public abstract int getFieldIdItemOffset(int fieldIndex);
|
stringStartOffset = readSmallUint(HeaderItem.STRING_START_OFFSET);
|
||||||
public abstract int getClassDefItemOffset(int classIndex);
|
typeCount = readSmallUint(HeaderItem.TYPE_COUNT_OFFSET);
|
||||||
|
typeStartOffset = readSmallUint(HeaderItem.TYPE_START_OFFSET);
|
||||||
|
protoCount = readSmallUint(HeaderItem.PROTO_COUNT_OFFSET);
|
||||||
|
protoStartOffset = readSmallUint(HeaderItem.PROTO_START_OFFSET);
|
||||||
|
fieldCount = readSmallUint(HeaderItem.FIELD_COUNT_OFFSET);
|
||||||
|
fieldStartOffset = readSmallUint(HeaderItem.FIELD_START_OFFSET);
|
||||||
|
methodCount = readSmallUint(HeaderItem.METHOD_COUNT_OFFSET);
|
||||||
|
methodStartOffset = readSmallUint(HeaderItem.METHOD_START_OFFSET);
|
||||||
|
classCount = readSmallUint(HeaderItem.CLASS_COUNT_OFFSET);
|
||||||
|
classStartOffset = readSmallUint(HeaderItem.CLASS_START_OFFSET);
|
||||||
|
}
|
||||||
|
|
||||||
@Override @Nonnull public abstract DexReader readerAt(int offset);
|
@Nonnull
|
||||||
|
@Override
|
||||||
public static class Impl extends DexBackedDexFile {
|
public Set<? extends DexBackedClassDef> getClasses() {
|
||||||
private final int stringCount;
|
return new FixedSizeSet<DexBackedClassDef>() {
|
||||||
private final int stringStartOffset;
|
@Nonnull
|
||||||
private final int typeCount;
|
@Override
|
||||||
private final int typeStartOffset;
|
public DexBackedClassDef readItem(int index) {
|
||||||
private final int protoCount;
|
return new DexBackedClassDef(DexBackedDexFile.this, getClassDefItemOffset(index));
|
||||||
private final int protoStartOffset;
|
|
||||||
private final int fieldCount;
|
|
||||||
private final int fieldStartOffset;
|
|
||||||
private final int methodCount;
|
|
||||||
private final int methodStartOffset;
|
|
||||||
private final int classCount;
|
|
||||||
private final int classStartOffset;
|
|
||||||
|
|
||||||
public Impl(@Nonnull BaseDexBuffer buf) {
|
|
||||||
this(buf.buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Impl(@Nonnull byte[] buf) {
|
|
||||||
super(buf);
|
|
||||||
|
|
||||||
verifyMagic();
|
|
||||||
verifyEndian();
|
|
||||||
stringCount = readSmallUint(HeaderItem.STRING_COUNT_OFFSET);
|
|
||||||
stringStartOffset = readSmallUint(HeaderItem.STRING_START_OFFSET);
|
|
||||||
typeCount = readSmallUint(HeaderItem.TYPE_COUNT_OFFSET);
|
|
||||||
typeStartOffset = readSmallUint(HeaderItem.TYPE_START_OFFSET);
|
|
||||||
protoCount = readSmallUint(HeaderItem.PROTO_COUNT_OFFSET);
|
|
||||||
protoStartOffset = readSmallUint(HeaderItem.PROTO_START_OFFSET);
|
|
||||||
fieldCount = readSmallUint(HeaderItem.FIELD_COUNT_OFFSET);
|
|
||||||
fieldStartOffset = readSmallUint(HeaderItem.FIELD_START_OFFSET);
|
|
||||||
methodCount = readSmallUint(HeaderItem.METHOD_COUNT_OFFSET);
|
|
||||||
methodStartOffset = readSmallUint(HeaderItem.METHOD_START_OFFSET);
|
|
||||||
classCount = readSmallUint(HeaderItem.CLASS_COUNT_OFFSET);
|
|
||||||
classStartOffset = readSmallUint(HeaderItem.CLASS_START_OFFSET);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public Set<? extends DexBackedClassDef> getClasses() {
|
|
||||||
return new FixedSizeSet<DexBackedClassDef>() {
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public DexBackedClassDef readItem(int index) {
|
|
||||||
return new DexBackedClassDef(Impl.this, getClassDefItemOffset(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int size() {
|
|
||||||
return classCount;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private void verifyMagic() {
|
|
||||||
outer: for (byte[] magic: HeaderItem.MAGIC_VALUES) {
|
|
||||||
for (int i=0; i<magic.length; i++) {
|
|
||||||
if (buf[i] != magic[i]) {
|
|
||||||
continue outer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
StringBuilder sb = new StringBuilder("Invalid magic value:");
|
|
||||||
for (int i=0; i<8; i++) {
|
@Override
|
||||||
sb.append(String.format(" %02x", buf[i]));
|
public int size() {
|
||||||
|
return classCount;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyMagic() {
|
||||||
|
outer: for (byte[] magic: HeaderItem.MAGIC_VALUES) {
|
||||||
|
for (int i=0; i<magic.length; i++) {
|
||||||
|
if (buf[i] != magic[i]) {
|
||||||
|
continue outer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
StringBuilder sb = new StringBuilder("Invalid magic value:");
|
||||||
|
for (int i=0; i<8; i++) {
|
||||||
|
sb.append(String.format(" %02x", buf[i]));
|
||||||
|
}
|
||||||
|
throw new ExceptionWithContext(sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyEndian() {
|
||||||
|
int endian = readInt(HeaderItem.ENDIAN_TAG_OFFSET);
|
||||||
|
if (endian == HeaderItem.BIG_ENDIAN_TAG) {
|
||||||
|
throw new ExceptionWithContext("dexlib does not currently support big endian dex files.");
|
||||||
|
} else if (endian != HeaderItem.LITTLE_ENDIAN_TAG) {
|
||||||
|
StringBuilder sb = new StringBuilder("Invalid endian tag:");
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
sb.append(String.format(" %02x", buf[HeaderItem.ENDIAN_TAG_OFFSET+i]));
|
||||||
}
|
}
|
||||||
throw new ExceptionWithContext(sb.toString());
|
throw new ExceptionWithContext(sb.toString());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void verifyEndian() {
|
public int getStringIdItemOffset(int stringIndex) {
|
||||||
int endian = readInt(HeaderItem.ENDIAN_TAG_OFFSET);
|
if (stringIndex < 0 || stringIndex >= stringCount) {
|
||||||
if (endian == HeaderItem.BIG_ENDIAN_TAG) {
|
throw new ExceptionWithContext("String index out of bounds: %d", stringIndex);
|
||||||
throw new ExceptionWithContext("dexlib does not currently support big endian dex files.");
|
|
||||||
} else if (endian != HeaderItem.LITTLE_ENDIAN_TAG) {
|
|
||||||
StringBuilder sb = new StringBuilder("Invalid endian tag:");
|
|
||||||
for (int i=0; i<4; i++) {
|
|
||||||
sb.append(String.format(" %02x", buf[HeaderItem.ENDIAN_TAG_OFFSET+i]));
|
|
||||||
}
|
|
||||||
throw new ExceptionWithContext(sb.toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return stringStartOffset + stringIndex*StringIdItem.ITEM_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
public int getStringIdItemOffset(int stringIndex) {
|
public int getTypeIdItemOffset(int typeIndex) {
|
||||||
if (stringIndex < 0 || stringIndex >= stringCount) {
|
if (typeIndex < 0 || typeIndex >= typeCount) {
|
||||||
throw new ExceptionWithContext("String index out of bounds: %d", stringIndex);
|
throw new ExceptionWithContext("Type index out of bounds: %d", typeIndex);
|
||||||
}
|
|
||||||
return stringStartOffset + stringIndex*StringIdItem.ITEM_SIZE;
|
|
||||||
}
|
}
|
||||||
|
return typeStartOffset + typeIndex*TypeIdItem.ITEM_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
public int getTypeIdItemOffset(int typeIndex) {
|
public int getFieldIdItemOffset(int fieldIndex) {
|
||||||
if (typeIndex < 0 || typeIndex >= typeCount) {
|
if (fieldIndex < 0 || fieldIndex >= fieldCount) {
|
||||||
throw new ExceptionWithContext("Type index out of bounds: %d", typeIndex);
|
throw new ExceptionWithContext("Field index out of bounds: %d", fieldIndex);
|
||||||
}
|
|
||||||
return typeStartOffset + typeIndex*TypeIdItem.ITEM_SIZE;
|
|
||||||
}
|
}
|
||||||
|
return fieldStartOffset + fieldIndex*FieldIdItem.ITEM_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
public int getMethodIdItemOffset(int methodIndex) {
|
||||||
public int getFieldIdItemOffset(int fieldIndex) {
|
if (methodIndex < 0 || methodIndex >= methodCount) {
|
||||||
if (fieldIndex < 0 || fieldIndex >= fieldCount) {
|
throw new ExceptionWithContext("Method index out of bounds: %d", methodIndex);
|
||||||
throw new ExceptionWithContext("Field index out of bounds: %d", fieldIndex);
|
|
||||||
}
|
|
||||||
return fieldStartOffset + fieldIndex*FieldIdItem.ITEM_SIZE;
|
|
||||||
}
|
}
|
||||||
|
return methodStartOffset + methodIndex*MethodIdItem.ITEM_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
public int getProtoIdItemOffset(int protoIndex) {
|
||||||
public int getMethodIdItemOffset(int methodIndex) {
|
if (protoIndex < 0 || protoIndex >= protoCount) {
|
||||||
if (methodIndex < 0 || methodIndex >= methodCount) {
|
throw new ExceptionWithContext("Proto index out of bounds: %d", protoIndex);
|
||||||
throw new ExceptionWithContext("Method index out of bounds: %d", methodIndex);
|
|
||||||
}
|
|
||||||
return methodStartOffset + methodIndex*MethodIdItem.ITEM_SIZE;
|
|
||||||
}
|
}
|
||||||
|
return protoStartOffset + protoIndex*ProtoIdItem.ITEM_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
public int getClassDefItemOffset(int classIndex) {
|
||||||
public int getProtoIdItemOffset(int protoIndex) {
|
if (classIndex < 0 || classIndex >= classCount) {
|
||||||
if (protoIndex < 0 || protoIndex >= protoCount) {
|
throw new ExceptionWithContext("Class index out of bounds: %d", classIndex);
|
||||||
throw new ExceptionWithContext("Proto index out of bounds: %d", protoIndex);
|
|
||||||
}
|
|
||||||
return protoStartOffset + protoIndex*ProtoIdItem.ITEM_SIZE;
|
|
||||||
}
|
}
|
||||||
|
return classStartOffset + classIndex*ClassDefItem.ITEM_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
public int getClassCount() {
|
||||||
public int getClassDefItemOffset(int classIndex) {
|
return classCount;
|
||||||
if (classIndex < 0 || classIndex >= classCount) {
|
}
|
||||||
throw new ExceptionWithContext("Class index out of bounds: %d", classIndex);
|
|
||||||
}
|
|
||||||
return classStartOffset + classIndex*ClassDefItem.ITEM_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getClassCount() {
|
@Nonnull
|
||||||
return classCount;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Nullable
|
||||||
@Nonnull
|
public String getOptionalString(int stringIndex) {
|
||||||
public String getString(int stringIndex) {
|
if (stringIndex == -1) {
|
||||||
int stringOffset = getStringIdItemOffset(stringIndex);
|
return null;
|
||||||
int stringDataOffset = readSmallUint(stringOffset);
|
|
||||||
DexReader reader = readerAt(stringDataOffset);
|
|
||||||
int utf16Length = reader.readSmallUleb128();
|
|
||||||
return reader.readString(utf16Length);
|
|
||||||
}
|
}
|
||||||
|
return getString(stringIndex);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Nonnull
|
||||||
@Nullable
|
public String getType(int typeIndex) {
|
||||||
public String getOptionalString(int stringIndex) {
|
int typeOffset = getTypeIdItemOffset(typeIndex);
|
||||||
if (stringIndex == -1) {
|
int stringIndex = readSmallUint(typeOffset);
|
||||||
return null;
|
return getString(stringIndex);
|
||||||
}
|
}
|
||||||
return getString(stringIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Nullable
|
||||||
@Nonnull
|
public String getOptionalType(int typeIndex) {
|
||||||
public String getType(int typeIndex) {
|
if (typeIndex == -1) {
|
||||||
int typeOffset = getTypeIdItemOffset(typeIndex);
|
return null;
|
||||||
int stringIndex = readSmallUint(typeOffset);
|
|
||||||
return getString(stringIndex);
|
|
||||||
}
|
}
|
||||||
|
return getType(typeIndex);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nonnull
|
||||||
public String getOptionalType(int typeIndex) {
|
public DexReader readerAt(int offset) {
|
||||||
if (typeIndex == -1) {
|
return new DexReader(this, offset);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return getType(typeIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nonnull
|
|
||||||
public DexReader readerAt(int offset) {
|
|
||||||
return new DexReader(this, offset);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ import java.io.Writer;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class RawDexFile extends DexBackedDexFile.Impl {
|
public class RawDexFile extends DexBackedDexFile {
|
||||||
@Nonnull public final HeaderItem headerItem;
|
@Nonnull public final HeaderItem headerItem;
|
||||||
|
|
||||||
public RawDexFile(BaseDexBuffer buf) {
|
public RawDexFile(BaseDexBuffer buf) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user