mirror of
https://github.com/revanced/smali.git
synced 2025-05-08 10:24:31 +02:00
Gracefully handle instructions with invalid references
This commit is contained in:
parent
f9bcf89674
commit
f7d6d5fade
@ -32,10 +32,13 @@ import org.jf.baksmali.Adaptors.MethodDefinition;
|
|||||||
import org.jf.baksmali.Adaptors.MethodItem;
|
import org.jf.baksmali.Adaptors.MethodItem;
|
||||||
import org.jf.baksmali.Adaptors.ReferenceFormatter;
|
import org.jf.baksmali.Adaptors.ReferenceFormatter;
|
||||||
import org.jf.baksmali.Renderers.LongRenderer;
|
import org.jf.baksmali.Renderers.LongRenderer;
|
||||||
|
import org.jf.dexlib2.ReferenceType;
|
||||||
import org.jf.dexlib2.VerificationError;
|
import org.jf.dexlib2.VerificationError;
|
||||||
|
import org.jf.dexlib2.dexbacked.DexBackedDexFile.InvalidItemIndex;
|
||||||
import org.jf.dexlib2.iface.instruction.*;
|
import org.jf.dexlib2.iface.instruction.*;
|
||||||
import org.jf.dexlib2.iface.instruction.formats.Instruction20bc;
|
import org.jf.dexlib2.iface.instruction.formats.Instruction20bc;
|
||||||
import org.jf.dexlib2.iface.instruction.formats.UnknownInstruction;
|
import org.jf.dexlib2.iface.instruction.formats.UnknownInstruction;
|
||||||
|
import org.jf.dexlib2.iface.reference.Reference;
|
||||||
import org.jf.util.IndentingWriter;
|
import org.jf.util.IndentingWriter;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
@ -58,6 +61,21 @@ public class InstructionMethodItem<T extends Instruction> extends MethodItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean writeTo(IndentingWriter writer) throws IOException {
|
public boolean writeTo(IndentingWriter writer) throws IOException {
|
||||||
|
boolean invalidReference = false;
|
||||||
|
if (instruction instanceof ReferenceInstruction) {
|
||||||
|
try {
|
||||||
|
Reference reference = ((ReferenceInstruction)instruction).getReference();
|
||||||
|
} catch (InvalidItemIndex ex) {
|
||||||
|
invalidReference = true;
|
||||||
|
|
||||||
|
writer.write("#invalid ");
|
||||||
|
writer.write(ReferenceType.toString(instruction.getOpcode().referenceType));
|
||||||
|
writer.write(" index: ");
|
||||||
|
writer.printSignedIntAsDec(ex.getInvalidIndex());
|
||||||
|
writer.write("\n#");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (instruction.getOpcode().format) {
|
switch (instruction.getOpcode().format) {
|
||||||
case Format10t:
|
case Format10t:
|
||||||
writeOpcode(writer);
|
writeOpcode(writer);
|
||||||
@ -336,8 +354,14 @@ public class InstructionMethodItem<T extends Instruction> extends MethodItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void writeReference(IndentingWriter writer) throws IOException {
|
protected void writeReference(IndentingWriter writer) throws IOException {
|
||||||
|
try {
|
||||||
ReferenceFormatter.writeReference(writer, instruction.getOpcode().referenceType,
|
ReferenceFormatter.writeReference(writer, instruction.getOpcode().referenceType,
|
||||||
((ReferenceInstruction)instruction).getReference());
|
((ReferenceInstruction)instruction).getReference());
|
||||||
|
} catch (InvalidItemIndex ex) {
|
||||||
|
writer.write(ReferenceType.toString(instruction.getOpcode().referenceType));
|
||||||
|
writer.write("@");
|
||||||
|
writer.printSignedIntAsDec(ex.getInvalidIndex());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void writeVerificationErrorType(IndentingWriter writer) throws IOException {
|
protected void writeVerificationErrorType(IndentingWriter writer) throws IOException {
|
||||||
|
@ -38,5 +38,20 @@ public final class ReferenceType {
|
|||||||
public static final int METHOD = 3;
|
public static final int METHOD = 3;
|
||||||
public static final int NONE = 4;
|
public static final int NONE = 4;
|
||||||
|
|
||||||
|
public static String toString(int referenceType) {
|
||||||
|
switch (referenceType) {
|
||||||
|
case STRING:
|
||||||
|
return "string";
|
||||||
|
case TYPE:
|
||||||
|
return "type";
|
||||||
|
case FIELD:
|
||||||
|
return "field";
|
||||||
|
case METHOD:
|
||||||
|
return "method";
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Invalid reference type: " + referenceType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private ReferenceType() {}
|
private ReferenceType() {}
|
||||||
}
|
}
|
@ -163,42 +163,42 @@ public class DexBackedDexFile extends BaseDexBuffer implements DexFile {
|
|||||||
|
|
||||||
public int getStringIdItemOffset(int stringIndex) {
|
public int getStringIdItemOffset(int stringIndex) {
|
||||||
if (stringIndex < 0 || stringIndex >= stringCount) {
|
if (stringIndex < 0 || stringIndex >= stringCount) {
|
||||||
throw new ExceptionWithContext("String index out of bounds: %d", stringIndex);
|
throw new InvalidItemIndex(stringIndex, "String index out of bounds: %d", stringIndex);
|
||||||
}
|
}
|
||||||
return stringStartOffset + stringIndex*StringIdItem.ITEM_SIZE;
|
return stringStartOffset + stringIndex*StringIdItem.ITEM_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTypeIdItemOffset(int typeIndex) {
|
public int getTypeIdItemOffset(int typeIndex) {
|
||||||
if (typeIndex < 0 || typeIndex >= typeCount) {
|
if (typeIndex < 0 || typeIndex >= typeCount) {
|
||||||
throw new ExceptionWithContext("Type index out of bounds: %d", typeIndex);
|
throw new InvalidItemIndex(typeIndex, "Type index out of bounds: %d", typeIndex);
|
||||||
}
|
}
|
||||||
return typeStartOffset + typeIndex*TypeIdItem.ITEM_SIZE;
|
return typeStartOffset + typeIndex*TypeIdItem.ITEM_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getFieldIdItemOffset(int fieldIndex) {
|
public int getFieldIdItemOffset(int fieldIndex) {
|
||||||
if (fieldIndex < 0 || fieldIndex >= fieldCount) {
|
if (fieldIndex < 0 || fieldIndex >= fieldCount) {
|
||||||
throw new ExceptionWithContext("Field index out of bounds: %d", fieldIndex);
|
throw new InvalidItemIndex(fieldIndex, "Field index out of bounds: %d", fieldIndex);
|
||||||
}
|
}
|
||||||
return fieldStartOffset + fieldIndex*FieldIdItem.ITEM_SIZE;
|
return fieldStartOffset + fieldIndex*FieldIdItem.ITEM_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMethodIdItemOffset(int methodIndex) {
|
public int getMethodIdItemOffset(int methodIndex) {
|
||||||
if (methodIndex < 0 || methodIndex >= methodCount) {
|
if (methodIndex < 0 || methodIndex >= methodCount) {
|
||||||
throw new ExceptionWithContext("Method index out of bounds: %d", methodIndex);
|
throw new InvalidItemIndex(methodIndex, "Method findex out of bounds: %d", methodIndex);
|
||||||
}
|
}
|
||||||
return methodStartOffset + methodIndex*MethodIdItem.ITEM_SIZE;
|
return methodStartOffset + methodIndex*MethodIdItem.ITEM_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getProtoIdItemOffset(int protoIndex) {
|
public int getProtoIdItemOffset(int protoIndex) {
|
||||||
if (protoIndex < 0 || protoIndex >= protoCount) {
|
if (protoIndex < 0 || protoIndex >= protoCount) {
|
||||||
throw new ExceptionWithContext("Proto index out of bounds: %d", protoIndex);
|
throw new InvalidItemIndex(protoIndex, "Proto index out of bounds: %d", protoIndex);
|
||||||
}
|
}
|
||||||
return protoStartOffset + protoIndex*ProtoIdItem.ITEM_SIZE;
|
return protoStartOffset + protoIndex*ProtoIdItem.ITEM_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getClassDefItemOffset(int classIndex) {
|
public int getClassDefItemOffset(int classIndex) {
|
||||||
if (classIndex < 0 || classIndex >= classCount) {
|
if (classIndex < 0 || classIndex >= classCount) {
|
||||||
throw new ExceptionWithContext("Class index out of bounds: %d", classIndex);
|
throw new InvalidItemIndex(classIndex, "Class index out of bounds: %d", classIndex);
|
||||||
}
|
}
|
||||||
return classStartOffset + classIndex*ClassDefItem.ITEM_SIZE;
|
return classStartOffset + classIndex*ClassDefItem.ITEM_SIZE;
|
||||||
}
|
}
|
||||||
@ -261,4 +261,22 @@ public class DexBackedDexFile extends BaseDexBuffer implements DexFile {
|
|||||||
super(message, cause);
|
super(message, cause);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class InvalidItemIndex extends ExceptionWithContext {
|
||||||
|
private final int itemIndex;
|
||||||
|
|
||||||
|
public InvalidItemIndex(int itemIndex) {
|
||||||
|
super("");
|
||||||
|
this.itemIndex = itemIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InvalidItemIndex(int itemIndex, String message, Object... formatArgs) {
|
||||||
|
super(message, formatArgs);
|
||||||
|
this.itemIndex = itemIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getInvalidIndex() {
|
||||||
|
return itemIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user