mirror of
https://github.com/revanced/smali.git
synced 2025-06-13 04:27:38 +02:00
store types as strings, to allow for intermediate types that don't exist in the dex file
git-svn-id: https://smali.googlecode.com/svn/trunk@451 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
@ -262,7 +262,8 @@ public class DeodexUtil {
|
|||||||
insn nextInstruction = i.getInstructionAtOffset(i.offset + i.instruction.getSize()/2);
|
insn nextInstruction = i.getInstructionAtOffset(i.offset + i.instruction.getSize()/2);
|
||||||
assert nextInstruction != null;
|
assert nextInstruction != null;
|
||||||
if (nextInstruction.instruction.opcode == Opcode.MOVE_RESULT_OBJECT) {
|
if (nextInstruction.instruction.opcode == Opcode.MOVE_RESULT_OBJECT) {
|
||||||
nextInstruction.registerReferenceType = inlineMethod.methodIdItem.getPrototype().getReturnType();
|
nextInstruction.registerReferenceType =
|
||||||
|
inlineMethod.methodIdItem.getPrototype().getReturnType().getTypeDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -296,7 +297,7 @@ public class DeodexUtil {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeIdItem type = i.registerTypes[registerNum];
|
String type = i.registerTypes[registerNum];
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -304,7 +305,7 @@ public class DeodexUtil {
|
|||||||
FieldIdItem field = deodexerant.lookupField(type, ins.getFieldOffset());
|
FieldIdItem field = deodexerant.lookupField(type, ins.getFieldOffset());
|
||||||
if (field == null) {
|
if (field == null) {
|
||||||
throw new RuntimeException("Could not find the field with offset " + ins.getFieldOffset() +
|
throw new RuntimeException("Could not find the field with offset " + ins.getFieldOffset() +
|
||||||
" for class: " + type.getTypeDescriptor());
|
" for class: " + type);
|
||||||
}
|
}
|
||||||
String fieldType = field.getFieldType().getTypeDescriptor();
|
String fieldType = field.getFieldType().getTypeDescriptor();
|
||||||
|
|
||||||
@ -358,7 +359,7 @@ public class DeodexUtil {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeIdItem type = i.registerTypes[registerNum];
|
String type = i.registerTypes[registerNum];
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -366,7 +367,7 @@ public class DeodexUtil {
|
|||||||
FieldIdItem field = deodexerant.lookupField(type, ins.getFieldOffset());
|
FieldIdItem field = deodexerant.lookupField(type, ins.getFieldOffset());
|
||||||
if (field == null) {
|
if (field == null) {
|
||||||
throw new RuntimeException("Could not find the field with offset " + ins.getFieldOffset() +
|
throw new RuntimeException("Could not find the field with offset " + ins.getFieldOffset() +
|
||||||
" for class: " + type.getTypeDescriptor());
|
" for class: " + type);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert field.getFieldType().getTypeDescriptor().charAt(0) == 'J' ||
|
assert field.getFieldType().getTypeDescriptor().charAt(0) == 'J' ||
|
||||||
@ -399,7 +400,7 @@ public class DeodexUtil {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeIdItem type = i.registerTypes[registerNum];
|
String type = i.registerTypes[registerNum];
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -407,7 +408,7 @@ public class DeodexUtil {
|
|||||||
FieldIdItem field = deodexerant.lookupField(type, ins.getFieldOffset());
|
FieldIdItem field = deodexerant.lookupField(type, ins.getFieldOffset());
|
||||||
if (field == null) {
|
if (field == null) {
|
||||||
throw new RuntimeException("Could not find the field with offset " + ins.getFieldOffset() +
|
throw new RuntimeException("Could not find the field with offset " + ins.getFieldOffset() +
|
||||||
" for class: " + type.getTypeDescriptor());
|
" for class: " + type);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert field.getFieldType().getTypeDescriptor().charAt(0) == 'L' ||
|
assert field.getFieldType().getTypeDescriptor().charAt(0) == 'L' ||
|
||||||
@ -415,7 +416,7 @@ public class DeodexUtil {
|
|||||||
|
|
||||||
i.fixedInstruction = new Instruction22csf(Opcode.IGET_OBJECT, (Instruction22cs)i.instruction, field);
|
i.fixedInstruction = new Instruction22csf(Opcode.IGET_OBJECT, (Instruction22cs)i.instruction, field);
|
||||||
|
|
||||||
i.updateRegisterReferenceType(field.getFieldType());
|
i.updateRegisterReferenceType(field.getFieldType().getTypeDescriptor());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case IPUT_QUICK:
|
case IPUT_QUICK:
|
||||||
@ -442,7 +443,7 @@ public class DeodexUtil {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeIdItem type = i.registerTypes[registerNum];
|
String type = i.registerTypes[registerNum];
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -450,7 +451,7 @@ public class DeodexUtil {
|
|||||||
FieldIdItem field = deodexerant.lookupField(type, ins.getFieldOffset());
|
FieldIdItem field = deodexerant.lookupField(type, ins.getFieldOffset());
|
||||||
if (field == null) {
|
if (field == null) {
|
||||||
throw new RuntimeException("Could not find the field with offset " + ins.getFieldOffset() +
|
throw new RuntimeException("Could not find the field with offset " + ins.getFieldOffset() +
|
||||||
" for class: " + type.getTypeDescriptor());
|
" for class: " + type);
|
||||||
}
|
}
|
||||||
String fieldType = field.getFieldType().getTypeDescriptor();
|
String fieldType = field.getFieldType().getTypeDescriptor();
|
||||||
|
|
||||||
@ -504,7 +505,7 @@ public class DeodexUtil {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeIdItem type = i.registerTypes[registerNum];
|
String type = i.registerTypes[registerNum];
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -512,7 +513,7 @@ public class DeodexUtil {
|
|||||||
FieldIdItem field = deodexerant.lookupField(type, ins.getFieldOffset());
|
FieldIdItem field = deodexerant.lookupField(type, ins.getFieldOffset());
|
||||||
if (field == null) {
|
if (field == null) {
|
||||||
throw new RuntimeException("Could not find the field with offset " + ins.getFieldOffset() +
|
throw new RuntimeException("Could not find the field with offset " + ins.getFieldOffset() +
|
||||||
" for class: " + type.getTypeDescriptor());
|
" for class: " + type);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert field.getFieldType().getTypeDescriptor().charAt(0) == 'J' ||
|
assert field.getFieldType().getTypeDescriptor().charAt(0) == 'J' ||
|
||||||
@ -546,7 +547,7 @@ public class DeodexUtil {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeIdItem type = i.registerTypes[registerNum];
|
String type = i.registerTypes[registerNum];
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -554,7 +555,7 @@ public class DeodexUtil {
|
|||||||
FieldIdItem field = deodexerant.lookupField(type, ins.getFieldOffset());
|
FieldIdItem field = deodexerant.lookupField(type, ins.getFieldOffset());
|
||||||
if (field == null) {
|
if (field == null) {
|
||||||
throw new RuntimeException("Could not find the field with offset " + ins.getFieldOffset() +
|
throw new RuntimeException("Could not find the field with offset " + ins.getFieldOffset() +
|
||||||
" for class: " + type.getTypeDescriptor());
|
" for class: " + type);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert field.getFieldType().getTypeDescriptor().charAt(0) == 'L' ||
|
assert field.getFieldType().getTypeDescriptor().charAt(0) == 'L' ||
|
||||||
@ -588,7 +589,7 @@ public class DeodexUtil {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeIdItem type = i.registerTypes[registerNum];
|
String type = i.registerTypes[registerNum];
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -596,7 +597,7 @@ public class DeodexUtil {
|
|||||||
MethodIdItem method = deodexerant.lookupVirtualMethod(type, ins.getMethodIndex(), false);
|
MethodIdItem method = deodexerant.lookupVirtualMethod(type, ins.getMethodIndex(), false);
|
||||||
if (method == null) {
|
if (method == null) {
|
||||||
throw new RuntimeException("Could not find the virtual method with vtable index " +
|
throw new RuntimeException("Could not find the virtual method with vtable index " +
|
||||||
ins.getMethodIndex() + " for class: " + type.getTypeDescriptor());
|
ins.getMethodIndex() + " for class: " + type);
|
||||||
}
|
}
|
||||||
|
|
||||||
i.fixedInstruction = new Instruction35msf(Opcode.INVOKE_VIRTUAL, (Instruction35ms)i.instruction,
|
i.fixedInstruction = new Instruction35msf(Opcode.INVOKE_VIRTUAL, (Instruction35ms)i.instruction,
|
||||||
@ -605,7 +606,8 @@ public class DeodexUtil {
|
|||||||
insn nextInstruction = i.getInstructionAtOffset(i.offset + i.instruction.getSize()/2);
|
insn nextInstruction = i.getInstructionAtOffset(i.offset + i.instruction.getSize()/2);
|
||||||
assert nextInstruction != null;
|
assert nextInstruction != null;
|
||||||
if (nextInstruction.instruction.opcode == Opcode.MOVE_RESULT_OBJECT) {
|
if (nextInstruction.instruction.opcode == Opcode.MOVE_RESULT_OBJECT) {
|
||||||
nextInstruction.updateRegisterReferenceType(method.getPrototype().getReturnType());
|
nextInstruction.updateRegisterReferenceType(
|
||||||
|
method.getPrototype().getReturnType().getTypeDescriptor());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -633,7 +635,7 @@ public class DeodexUtil {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeIdItem type = i.registerTypes[registerNum];
|
String type = i.registerTypes[registerNum];
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -641,7 +643,7 @@ public class DeodexUtil {
|
|||||||
MethodIdItem method = deodexerant.lookupVirtualMethod(type, ins.getMethodIndex(), false);
|
MethodIdItem method = deodexerant.lookupVirtualMethod(type, ins.getMethodIndex(), false);
|
||||||
if (method == null) {
|
if (method == null) {
|
||||||
throw new RuntimeException("Could not find the virtual method with vtable index " +
|
throw new RuntimeException("Could not find the virtual method with vtable index " +
|
||||||
ins.getMethodIndex() + " for class: " + type.getTypeDescriptor());
|
ins.getMethodIndex() + " for class: " + type);
|
||||||
}
|
}
|
||||||
|
|
||||||
i.fixedInstruction = new Instruction3rmsf(Opcode.INVOKE_VIRTUAL_RANGE, (Instruction3rms)i.instruction,
|
i.fixedInstruction = new Instruction3rmsf(Opcode.INVOKE_VIRTUAL_RANGE, (Instruction3rms)i.instruction,
|
||||||
@ -650,7 +652,8 @@ public class DeodexUtil {
|
|||||||
insn nextInstruction = i.getInstructionAtOffset(i.offset + i.instruction.getSize()/2);
|
insn nextInstruction = i.getInstructionAtOffset(i.offset + i.instruction.getSize()/2);
|
||||||
assert nextInstruction != null;
|
assert nextInstruction != null;
|
||||||
if (nextInstruction.instruction.opcode == Opcode.MOVE_RESULT_OBJECT) {
|
if (nextInstruction.instruction.opcode == Opcode.MOVE_RESULT_OBJECT) {
|
||||||
nextInstruction.updateRegisterReferenceType(method.getPrototype().getReturnType());
|
nextInstruction.updateRegisterReferenceType(
|
||||||
|
method.getPrototype().getReturnType().getTypeDescriptor());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -678,7 +681,7 @@ public class DeodexUtil {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeIdItem type = i.registerTypes[registerNum];
|
String type = i.registerTypes[registerNum];
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -686,7 +689,7 @@ public class DeodexUtil {
|
|||||||
MethodIdItem method = deodexerant.lookupVirtualMethod(type, ins.getMethodIndex(), true);
|
MethodIdItem method = deodexerant.lookupVirtualMethod(type, ins.getMethodIndex(), true);
|
||||||
if (method == null) {
|
if (method == null) {
|
||||||
throw new RuntimeException("Could not find the super method with vtable index " +
|
throw new RuntimeException("Could not find the super method with vtable index " +
|
||||||
ins.getMethodIndex() + " for class: " + type.getTypeDescriptor());
|
ins.getMethodIndex() + " for class: " + type);
|
||||||
}
|
}
|
||||||
|
|
||||||
i.fixedInstruction = new Instruction35msf(Opcode.INVOKE_SUPER, (Instruction35ms)i.instruction,
|
i.fixedInstruction = new Instruction35msf(Opcode.INVOKE_SUPER, (Instruction35ms)i.instruction,
|
||||||
@ -695,7 +698,8 @@ public class DeodexUtil {
|
|||||||
insn nextInstruction = i.getInstructionAtOffset(i.offset + i.instruction.getSize()/2);
|
insn nextInstruction = i.getInstructionAtOffset(i.offset + i.instruction.getSize()/2);
|
||||||
assert nextInstruction != null;
|
assert nextInstruction != null;
|
||||||
if (nextInstruction.instruction.opcode == Opcode.MOVE_RESULT_OBJECT) {
|
if (nextInstruction.instruction.opcode == Opcode.MOVE_RESULT_OBJECT) {
|
||||||
nextInstruction.updateRegisterReferenceType(method.getPrototype().getReturnType());
|
nextInstruction.updateRegisterReferenceType(
|
||||||
|
method.getPrototype().getReturnType().getTypeDescriptor());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -723,7 +727,7 @@ public class DeodexUtil {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeIdItem type = i.registerTypes[registerNum];
|
String type = i.registerTypes[registerNum];
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -731,7 +735,7 @@ public class DeodexUtil {
|
|||||||
MethodIdItem method = deodexerant.lookupVirtualMethod(type, ins.getMethodIndex(), true);
|
MethodIdItem method = deodexerant.lookupVirtualMethod(type, ins.getMethodIndex(), true);
|
||||||
if (method == null) {
|
if (method == null) {
|
||||||
throw new RuntimeException("Could not find the super method with vtable index " +
|
throw new RuntimeException("Could not find the super method with vtable index " +
|
||||||
ins.getMethodIndex() + " for class: " + type.getTypeDescriptor());
|
ins.getMethodIndex() + " for class: " + type);
|
||||||
}
|
}
|
||||||
|
|
||||||
i.fixedInstruction = new Instruction3rmsf(Opcode.INVOKE_SUPER_RANGE, (Instruction3rms)i.instruction,
|
i.fixedInstruction = new Instruction3rmsf(Opcode.INVOKE_SUPER_RANGE, (Instruction3rms)i.instruction,
|
||||||
@ -740,7 +744,8 @@ public class DeodexUtil {
|
|||||||
insn nextInstruction = i.getInstructionAtOffset(i.offset + i.instruction.getSize()/2);
|
insn nextInstruction = i.getInstructionAtOffset(i.offset + i.instruction.getSize()/2);
|
||||||
assert nextInstruction != null;
|
assert nextInstruction != null;
|
||||||
if (nextInstruction.instruction.opcode == Opcode.MOVE_RESULT_OBJECT) {
|
if (nextInstruction.instruction.opcode == Opcode.MOVE_RESULT_OBJECT) {
|
||||||
nextInstruction.updateRegisterReferenceType(method.getPrototype().getReturnType());
|
nextInstruction.updateRegisterReferenceType(
|
||||||
|
method.getPrototype().getReturnType().getTypeDescriptor());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -826,7 +831,7 @@ public class DeodexUtil {
|
|||||||
* if setsRegister is true, and the register type is a reference, this is the
|
* if setsRegister is true, and the register type is a reference, this is the
|
||||||
* reference type of the register, or null if not known yet.
|
* reference type of the register, or null if not known yet.
|
||||||
*/
|
*/
|
||||||
public TypeIdItem registerReferenceType;
|
public String registerReferenceType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores a "fake" fixed instruction, which is included in the instruction list that deodexerizeCode produces
|
* Stores a "fake" fixed instruction, which is included in the instruction list that deodexerizeCode produces
|
||||||
@ -856,7 +861,7 @@ public class DeodexUtil {
|
|||||||
public boolean fixed = false;
|
public boolean fixed = false;
|
||||||
|
|
||||||
public final RegisterType[] registerMap;
|
public final RegisterType[] registerMap;
|
||||||
public final TypeIdItem[] registerTypes;
|
public final String[] registerTypes;
|
||||||
|
|
||||||
public insn(CodeItem codeItem, Instruction instruction, SparseArray<insn> insnsMap, int offset) {
|
public insn(CodeItem codeItem, Instruction instruction, SparseArray<insn> insnsMap, int offset) {
|
||||||
this.codeItem = codeItem;
|
this.codeItem = codeItem;
|
||||||
@ -889,7 +894,7 @@ public class DeodexUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
registerMap = new RegisterType[codeItem.getRegisterCount()];
|
registerMap = new RegisterType[codeItem.getRegisterCount()];
|
||||||
registerTypes = new TypeIdItem[codeItem.getRegisterCount()];
|
registerTypes = new String[codeItem.getRegisterCount()];
|
||||||
|
|
||||||
for (int i=0; i<registerMap.length; i++) {
|
for (int i=0; i<registerMap.length; i++) {
|
||||||
registerMap[i] = RegisterType.Unknown;
|
registerMap[i] = RegisterType.Unknown;
|
||||||
@ -1112,12 +1117,11 @@ public class DeodexUtil {
|
|||||||
registerType = RegisterType.Reference;
|
registerType = RegisterType.Reference;
|
||||||
//typically, there will only be a single exception type for a particular handler block, so optimize
|
//typically, there will only be a single exception type for a particular handler block, so optimize
|
||||||
//the array size for that case, but support the case of multiple exception types as well
|
//the array size for that case, but support the case of multiple exception types as well
|
||||||
List<TypeIdItem> exceptionTypes = new ArrayList<TypeIdItem>(1);
|
List<String> exceptionTypes = new ArrayList<String>(1);
|
||||||
for (CodeItem.TryItem tryItem: codeItem.getTries()) {
|
for (CodeItem.TryItem tryItem: codeItem.getTries()) {
|
||||||
if (tryItem.encodedCatchHandler.catchAllHandlerAddress == this.offset) {
|
if (tryItem.encodedCatchHandler.catchAllHandlerAddress == this.offset) {
|
||||||
//if this is a catch all handler, the only possible type is Ljava/lang/Throwable;
|
//if this is a catch all handler, the only possible type is Ljava/lang/Throwable;
|
||||||
registerReferenceType = TypeIdItem.getInternedTypeIdItem(codeItem.getDexFile(),
|
registerReferenceType = "Ljava/lang/Throwable;";
|
||||||
"Ljava/lang/Throwable;");
|
|
||||||
|
|
||||||
//it's possible that Ljava/lang/Throwable; hasn't be interned into the dex file. since
|
//it's possible that Ljava/lang/Throwable; hasn't be interned into the dex file. since
|
||||||
//we've turned off interning for the current dex file, we will just get a null back.
|
//we've turned off interning for the current dex file, we will just get a null back.
|
||||||
@ -1130,7 +1134,7 @@ public class DeodexUtil {
|
|||||||
|
|
||||||
for (CodeItem.EncodedTypeAddrPair handler: tryItem.encodedCatchHandler.handlers) {
|
for (CodeItem.EncodedTypeAddrPair handler: tryItem.encodedCatchHandler.handlers) {
|
||||||
if (handler.handlerAddress == this.offset) {
|
if (handler.handlerAddress == this.offset) {
|
||||||
exceptionTypes.add(handler.exceptionType);
|
exceptionTypes.add(handler.exceptionType.getTypeDescriptor());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1174,8 +1178,7 @@ public class DeodexUtil {
|
|||||||
setsRegister = true;
|
setsRegister = true;
|
||||||
registerNum = ((SingleRegisterInstruction)instruction).getRegisterA();
|
registerNum = ((SingleRegisterInstruction)instruction).getRegisterA();
|
||||||
registerType = RegisterType.Reference;
|
registerType = RegisterType.Reference;
|
||||||
registerReferenceType = TypeIdItem.getInternedTypeIdItem(this.codeItem.getDexFile(),
|
registerReferenceType = "Ljava/lang/String;";
|
||||||
"Ljava/lang/String;");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONST_CLASS:
|
case CONST_CLASS:
|
||||||
@ -1183,8 +1186,7 @@ public class DeodexUtil {
|
|||||||
setsRegister = true;
|
setsRegister = true;
|
||||||
registerNum = ((SingleRegisterInstruction)instruction).getRegisterA();
|
registerNum = ((SingleRegisterInstruction)instruction).getRegisterA();
|
||||||
registerType = RegisterType.Reference;
|
registerType = RegisterType.Reference;
|
||||||
registerReferenceType = TypeIdItem.getInternedTypeIdItem(this.codeItem.getDexFile(),
|
registerReferenceType = "Ljava/lang/Class;";
|
||||||
"Ljava/lang/Class;");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CHECK_CAST:
|
case CHECK_CAST:
|
||||||
@ -1194,7 +1196,8 @@ public class DeodexUtil {
|
|||||||
setsRegister = true;
|
setsRegister = true;
|
||||||
registerNum = ((SingleRegisterInstruction)instruction).getRegisterA();
|
registerNum = ((SingleRegisterInstruction)instruction).getRegisterA();
|
||||||
registerType = RegisterType.Reference;
|
registerType = RegisterType.Reference;
|
||||||
registerReferenceType = (TypeIdItem)((InstructionWithReference)instruction).getReferencedItem();
|
registerReferenceType =
|
||||||
|
((TypeIdItem)((InstructionWithReference)instruction).getReferencedItem()).getTypeDescriptor();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IGET_OBJECT:
|
case IGET_OBJECT:
|
||||||
@ -1204,7 +1207,7 @@ public class DeodexUtil {
|
|||||||
registerNum = ((SingleRegisterInstruction)instruction).getRegisterA();
|
registerNum = ((SingleRegisterInstruction)instruction).getRegisterA();
|
||||||
registerType = RegisterType.Reference;
|
registerType = RegisterType.Reference;
|
||||||
registerReferenceType = ((FieldIdItem)((InstructionWithReference)instruction).getReferencedItem())
|
registerReferenceType = ((FieldIdItem)((InstructionWithReference)instruction).getReferencedItem())
|
||||||
.getFieldType();
|
.getFieldType().getTypeDescriptor();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1214,59 +1217,31 @@ public class DeodexUtil {
|
|||||||
addSuccessor(getInstructionAtOffset(offset + instruction.getSize()/2));
|
addSuccessor(getInstructionAtOffset(offset + instruction.getSize()/2));
|
||||||
}
|
}
|
||||||
|
|
||||||
private TypeIdItem findCommonSuperclass(TypeIdItem item1, TypeIdItem item2) {
|
private String findCommonSuperclass(String type1, String type2) {
|
||||||
if (item1 == item2) {
|
if (type1 == null) {
|
||||||
return item1;
|
return type2;
|
||||||
}
|
}
|
||||||
if (item1 == null) {
|
if (type2 == null) {
|
||||||
return item2;
|
return type1;
|
||||||
}
|
|
||||||
if (item2 == null) {
|
|
||||||
return item1;
|
|
||||||
}
|
|
||||||
|
|
||||||
String superclass =
|
|
||||||
deodexerant.lookupCommonSuperclass(item1.getTypeDescriptor(), item2.getTypeDescriptor());
|
|
||||||
|
|
||||||
TypeIdItem superType = TypeIdItem.getInternedTypeIdItem(codeItem.getDexFile(), superclass);
|
|
||||||
//if the class isn't interned, let's see if we can find a superclass that is interned. This should be safe
|
|
||||||
//because there should be no fields or methods specific to this type being referenced.. otherwise it would
|
|
||||||
//already be interned
|
|
||||||
//TODO: array types need to be handled correctly
|
|
||||||
while (superType == null && superclass != null) {
|
|
||||||
superclass = deodexerant.lookupSuperclass(superclass);
|
|
||||||
if (superclass != null) {
|
|
||||||
superType = TypeIdItem.getInternedTypeIdItem(codeItem.getDexFile(), superclass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//we might not find anything. if so, just return null. This should be ok, due to the same reasoning as
|
|
||||||
//above
|
|
||||||
return superType;
|
|
||||||
}
|
|
||||||
|
|
||||||
private TypeIdItem findCommonSuperclass(List<TypeIdItem> exceptionTypes) {
|
|
||||||
assert exceptionTypes.size() > 1;
|
|
||||||
|
|
||||||
String superclass = exceptionTypes.get(0).getTypeDescriptor();
|
|
||||||
|
|
||||||
for (int i=1; i<exceptionTypes.size(); i++) {
|
|
||||||
superclass = deodexerant.lookupCommonSuperclass(superclass, exceptionTypes.get(i).getTypeDescriptor());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeIdItem superType = TypeIdItem.getInternedTypeIdItem(codeItem.getDexFile(), superclass);
|
if (type1.equals(type2)) {
|
||||||
//if the class isn't interned, let's see if we can find a superclass that is interned. This should be safe
|
return type1;
|
||||||
//because there should be no fields or methods specific to this type being referenced.. otherwise it would
|
|
||||||
//already be interned
|
|
||||||
//TODO: array types need to be handled correctly
|
|
||||||
while (superType == null && superclass != null) {
|
|
||||||
superclass = deodexerant.lookupSuperclass(superclass);
|
|
||||||
if (superclass != null) {
|
|
||||||
superType = TypeIdItem.getInternedTypeIdItem(codeItem.getDexFile(), superclass);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
//we might not find anything. if so, just return null. This should be ok, due to the same reasoning as
|
|
||||||
//above
|
return deodexerant.lookupCommonSuperclass(type1, type2);
|
||||||
return superType;
|
}
|
||||||
|
|
||||||
|
private String findCommonSuperclass(List<String> exceptionTypes) {
|
||||||
|
assert exceptionTypes.size() > 1;
|
||||||
|
|
||||||
|
String supertype = exceptionTypes.get(0);
|
||||||
|
|
||||||
|
for (int i=1; i<exceptionTypes.size(); i++) {
|
||||||
|
supertype = deodexerant.lookupCommonSuperclass(supertype, exceptionTypes.get(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return supertype;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addSuccessor(insn i) {
|
private void addSuccessor(insn i) {
|
||||||
@ -1281,7 +1256,7 @@ public class DeodexUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private TypeIdItem getReturnType(Instruction instruction) {
|
private String getReturnType(Instruction instruction) {
|
||||||
switch (instruction.opcode) {
|
switch (instruction.opcode) {
|
||||||
case INVOKE_DIRECT:
|
case INVOKE_DIRECT:
|
||||||
case INVOKE_INTERFACE:
|
case INVOKE_INTERFACE:
|
||||||
@ -1294,10 +1269,10 @@ public class DeodexUtil {
|
|||||||
case INVOKE_SUPER_RANGE:
|
case INVOKE_SUPER_RANGE:
|
||||||
case INVOKE_VIRTUAL_RANGE:
|
case INVOKE_VIRTUAL_RANGE:
|
||||||
return ((MethodIdItem)((InstructionWithReference)instruction).getReferencedItem()).getPrototype().
|
return ((MethodIdItem)((InstructionWithReference)instruction).getReferencedItem()).getPrototype().
|
||||||
getReturnType();
|
getReturnType().getTypeDescriptor();
|
||||||
case FILLED_NEW_ARRAY:
|
case FILLED_NEW_ARRAY:
|
||||||
case FILLED_NEW_ARRAY_RANGE:
|
case FILLED_NEW_ARRAY_RANGE:
|
||||||
return (TypeIdItem)((InstructionWithReference)instruction).getReferencedItem();
|
return ((TypeIdItem)((InstructionWithReference)instruction).getReferencedItem()).getTypeDescriptor();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -1312,7 +1287,7 @@ public class DeodexUtil {
|
|||||||
if ((codeItem.getParent().accessFlags & AccessFlags.STATIC.getValue()) == 0) {
|
if ((codeItem.getParent().accessFlags & AccessFlags.STATIC.getValue()) == 0) {
|
||||||
int thisRegister = methodRegisters - paramRegisters - 1;
|
int thisRegister = methodRegisters - paramRegisters - 1;
|
||||||
registerMap[thisRegister] = RegisterType.Reference;
|
registerMap[thisRegister] = RegisterType.Reference;
|
||||||
registerTypes[thisRegister] = method.getContainingClass();
|
registerTypes[thisRegister] = method.getContainingClass().getTypeDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
int paramRegister = methodRegisters - paramRegisters;
|
int paramRegister = methodRegisters - paramRegisters;
|
||||||
@ -1336,7 +1311,7 @@ public class DeodexUtil {
|
|||||||
case 'L':
|
case 'L':
|
||||||
case '[':
|
case '[':
|
||||||
registerMap[paramRegister] = RegisterType.Reference;
|
registerMap[paramRegister] = RegisterType.Reference;
|
||||||
registerTypes[paramRegister++] = paramType;
|
registerTypes[paramRegister++] = paramType.getTypeDescriptor();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert false;
|
assert false;
|
||||||
@ -1352,7 +1327,7 @@ public class DeodexUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateRegisterReferenceType(TypeIdItem type) {
|
public void updateRegisterReferenceType(String type) {
|
||||||
this.registerReferenceType = type;
|
this.registerReferenceType = type;
|
||||||
this.propogateRegisters();
|
this.propogateRegisters();
|
||||||
}
|
}
|
||||||
@ -1392,9 +1367,9 @@ public class DeodexUtil {
|
|||||||
nextInsn.registerMap[i] = regType;
|
nextInsn.registerMap[i] = regType;
|
||||||
}
|
}
|
||||||
if (regType == RegisterType.Reference) {
|
if (regType == RegisterType.Reference) {
|
||||||
TypeIdItem regReferenceType = findCommonSuperclass(registerTypes[i],
|
String regReferenceType = findCommonSuperclass(registerTypes[i],
|
||||||
nextInsn.registerTypes[i]);
|
nextInsn.registerTypes[i]);
|
||||||
if (regReferenceType != nextInsn.registerTypes[i]) {
|
if (!regReferenceType.equals(nextInsn.registerTypes[i])) {
|
||||||
//see comment above for loop
|
//see comment above for loop
|
||||||
if (i == nextInsn.objectRegisterNum) {
|
if (i == nextInsn.objectRegisterNum) {
|
||||||
nextInsn.fixedInstruction = null;
|
nextInsn.fixedInstruction = null;
|
||||||
@ -1413,7 +1388,7 @@ public class DeodexUtil {
|
|||||||
}
|
}
|
||||||
if (registerType == RegisterType.Reference) {
|
if (registerType == RegisterType.Reference) {
|
||||||
if (registerReferenceType != null) {
|
if (registerReferenceType != null) {
|
||||||
if (nextInsn.registerTypes[registerNum] != registerReferenceType) {
|
if (!registerReferenceType.equals(nextInsn.registerTypes[registerNum])) {
|
||||||
//see comment above for loop
|
//see comment above for loop
|
||||||
if (registerNum == nextInsn.objectRegisterNum) {
|
if (registerNum == nextInsn.objectRegisterNum) {
|
||||||
nextInsn.fixedInstruction = null;
|
nextInsn.fixedInstruction = null;
|
||||||
@ -1423,8 +1398,11 @@ public class DeodexUtil {
|
|||||||
nextInsn.registerTypes[registerNum] = registerReferenceType;
|
nextInsn.registerTypes[registerNum] = registerReferenceType;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TypeIdItem type = destRegisterType();
|
String type = destRegisterType();
|
||||||
if (type != nextInsn.registerTypes[registerNum]) {
|
String nextType = nextInsn.registerTypes[registerNum];
|
||||||
|
|
||||||
|
if ((type == null && nextType == null) ||
|
||||||
|
!type.equals(nextInsn.registerTypes[registerNum])) {
|
||||||
//see comment above for loop
|
//see comment above for loop
|
||||||
if (registerNum == nextInsn.objectRegisterNum) {
|
if (registerNum == nextInsn.objectRegisterNum) {
|
||||||
nextInsn.fixedInstruction = null;
|
nextInsn.fixedInstruction = null;
|
||||||
@ -1450,7 +1428,7 @@ public class DeodexUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private TypeIdItem destRegisterType() {
|
private String destRegisterType() {
|
||||||
if (registerReferenceType != null) {
|
if (registerReferenceType != null) {
|
||||||
return registerReferenceType;
|
return registerReferenceType;
|
||||||
}
|
}
|
||||||
@ -1471,16 +1449,13 @@ public class DeodexUtil {
|
|||||||
assert registerMap[registerNum] == RegisterType.Reference ||
|
assert registerMap[registerNum] == RegisterType.Reference ||
|
||||||
registerMap[registerNum] == RegisterType.Null;
|
registerMap[registerNum] == RegisterType.Null;
|
||||||
|
|
||||||
TypeIdItem type = registerTypes[registerNum];
|
String type = registerTypes[registerNum];
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String typeDescriptor = type.getTypeDescriptor();
|
assert type.charAt(0) == '[';
|
||||||
assert typeDescriptor.charAt(0) == '[';
|
return type.substring(1);
|
||||||
//TODO: probably need to try to lookup the supertype if not found
|
|
||||||
return TypeIdItem.getInternedTypeIdItem(codeItem.getDexFile(),
|
|
||||||
typeDescriptor.substring(1));
|
|
||||||
}
|
}
|
||||||
case MOVE_RESULT_OBJECT:
|
case MOVE_RESULT_OBJECT:
|
||||||
case IGET_OBJECT_QUICK:
|
case IGET_OBJECT_QUICK:
|
||||||
|
@ -45,7 +45,7 @@ public class Deodexerant {
|
|||||||
private final String host;
|
private final String host;
|
||||||
private final int port;
|
private final int port;
|
||||||
|
|
||||||
private final HashMap<TypeIdItem, ClassData> vtableMap = new HashMap<TypeIdItem, ClassData>();
|
private final HashMap<String, ClassData> vtableMap = new HashMap<String, ClassData>();
|
||||||
private final HashMap<CommonSuperclassLookup, String> cachedCommonSuperclassLookup =
|
private final HashMap<CommonSuperclassLookup, String> cachedCommonSuperclassLookup =
|
||||||
new HashMap<CommonSuperclassLookup, String>();
|
new HashMap<CommonSuperclassLookup, String>();
|
||||||
private InlineMethod[] inlineMethods;
|
private InlineMethod[] inlineMethods;
|
||||||
@ -101,13 +101,7 @@ public class Deodexerant {
|
|||||||
String methodParams = m.group(3);
|
String methodParams = m.group(3);
|
||||||
String methodRet = m.group(4);
|
String methodRet = m.group(4);
|
||||||
|
|
||||||
TypeIdItem classTypeItem = TypeIdItem.getInternedTypeIdItem(dexFile, classType);
|
MethodIdItem method = parseAndResolveMethod(classType, methodName, methodParams, methodRet);
|
||||||
if (classTypeItem == null) {
|
|
||||||
inlineMethods[i] = null;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
MethodIdItem method = parseAndResolveMethod(classTypeItem, methodName, methodParams, methodRet);
|
|
||||||
if (method == null) {
|
if (method == null) {
|
||||||
inlineMethods[i] = null;
|
inlineMethods[i] = null;
|
||||||
continue;
|
continue;
|
||||||
@ -129,13 +123,26 @@ public class Deodexerant {
|
|||||||
return inlineMethods[inlineMethodIndex];
|
return inlineMethods[inlineMethodIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
public FieldIdItem lookupField(TypeIdItem type, int fieldOffset) {
|
private TypeIdItem resolveTypeOrSupertype(String type) {
|
||||||
ClassData classData = getClassData(type);
|
TypeIdItem typeItem = TypeIdItem.getInternedTypeIdItem(dexFile, type);
|
||||||
|
|
||||||
|
while (typeItem == null) {
|
||||||
|
type = lookupSuperclass(type);
|
||||||
|
if (type == null) {
|
||||||
|
throw new RuntimeException("Could not find the type or a supertype of " + type + " in the dex file");
|
||||||
|
}
|
||||||
|
|
||||||
|
typeItem = TypeIdItem.getInternedTypeIdItem(dexFile, type);
|
||||||
|
}
|
||||||
|
return typeItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldIdItem lookupField(String type, int fieldOffset) {
|
||||||
|
ClassData classData = getClassData(type);
|
||||||
return classData.lookupField(fieldOffset);
|
return classData.lookupField(fieldOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClassData getClassData(TypeIdItem type) {
|
private ClassData getClassData(String type) {
|
||||||
ClassData classData = vtableMap.get(type);
|
ClassData classData = vtableMap.get(type);
|
||||||
if (classData == null) {
|
if (classData == null) {
|
||||||
classData = new ClassData(type);
|
classData = new ClassData(type);
|
||||||
@ -144,22 +151,12 @@ public class Deodexerant {
|
|||||||
return classData;
|
return classData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodIdItem lookupVirtualMethod(TypeIdItem type, int methodIndex, boolean lookupSuper) {
|
public MethodIdItem lookupVirtualMethod(String classType, int methodIndex, boolean lookupSuper) {
|
||||||
if (lookupSuper) {
|
if (lookupSuper) {
|
||||||
String classType = type.getTypeDescriptor();
|
classType = lookupSuperclass(classType);
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
classType = lookupSuperclass(type.getTypeDescriptor());
|
|
||||||
if (classType == null) {
|
|
||||||
throw new RuntimeException("Could not find any superclass for type " + type.getTypeDescriptor() +
|
|
||||||
" in the dex file");
|
|
||||||
}
|
|
||||||
type = TypeIdItem.getInternedTypeIdItem(dexFile, classType);
|
|
||||||
} while (type == null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ClassData classData = getClassData(type);
|
ClassData classData = getClassData(classType);
|
||||||
|
|
||||||
return classData.lookupMethod(methodIndex);
|
return classData.lookupMethod(methodIndex);
|
||||||
}
|
}
|
||||||
@ -260,8 +257,10 @@ public class Deodexerant {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private MethodIdItem parseAndResolveMethod(TypeIdItem classType, String methodName, String methodParams,
|
private MethodIdItem parseAndResolveMethod(String classType, String methodName, String methodParams,
|
||||||
String methodRet) {
|
String methodRet) {
|
||||||
|
TypeIdItem classTypeItem = resolveTypeOrSupertype(classType);
|
||||||
|
|
||||||
StringIdItem methodNameItem = StringIdItem.getInternedStringIdItem(dexFile, methodName);
|
StringIdItem methodNameItem = StringIdItem.getInternedStringIdItem(dexFile, methodName);
|
||||||
if (methodNameItem == null) {
|
if (methodNameItem == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -347,17 +346,17 @@ public class Deodexerant {
|
|||||||
MethodIdItem methodIdItem;
|
MethodIdItem methodIdItem;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
methodIdItem = MethodIdItem.getInternedMethodIdItem(dexFile, classType, protoItem, methodNameItem);
|
methodIdItem = MethodIdItem.getInternedMethodIdItem(dexFile, classTypeItem, protoItem, methodNameItem);
|
||||||
if (methodIdItem != null) {
|
if (methodIdItem != null) {
|
||||||
return methodIdItem;
|
return methodIdItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
String superclassDescriptor = lookupSuperclass(classType.getTypeDescriptor());
|
String superclassDescriptor = lookupSuperclass(classTypeItem.getTypeDescriptor());
|
||||||
classType = TypeIdItem.getInternedTypeIdItem(dexFile, superclassDescriptor);
|
classTypeItem = TypeIdItem.getInternedTypeIdItem(dexFile, superclassDescriptor);
|
||||||
|
|
||||||
while (classType == null && superclassDescriptor != null) {
|
while (classTypeItem == null && superclassDescriptor != null) {
|
||||||
superclassDescriptor = lookupSuperclass(superclassDescriptor);
|
superclassDescriptor = lookupSuperclass(superclassDescriptor);
|
||||||
classType = TypeIdItem.getInternedTypeIdItem(dexFile, superclassDescriptor);
|
classTypeItem = TypeIdItem.getInternedTypeIdItem(dexFile, superclassDescriptor);
|
||||||
}
|
}
|
||||||
} while (classType != null);
|
} while (classType != null);
|
||||||
throw new RuntimeException("Could not find method in dex file");
|
throw new RuntimeException("Could not find method in dex file");
|
||||||
@ -368,13 +367,14 @@ public class Deodexerant {
|
|||||||
//private static final Pattern fieldPattern = Pattern.compile("(\\[*L[^;]+;)->([^:]+):(.+)");
|
//private static final Pattern fieldPattern = Pattern.compile("(\\[*L[^;]+;)->([^:]+):(.+)");
|
||||||
|
|
||||||
|
|
||||||
private FieldIdItem parseAndResolveField(TypeIdItem classType, String field) {
|
private FieldIdItem parseAndResolveField(String classType, String field) {
|
||||||
//expecting a string like someField:Lfield/type;
|
//expecting a string like someField:Lfield/type;
|
||||||
String[] parts = field.split(":");
|
String[] parts = field.split(":");
|
||||||
if (parts.length != 2) {
|
if (parts.length != 2) {
|
||||||
throw new RuntimeException("Invalid field descriptor " + field);
|
throw new RuntimeException("Invalid field descriptor " + field);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TypeIdItem classTypeItem = resolveTypeOrSupertype(classType);
|
||||||
String fieldName = parts[0];
|
String fieldName = parts[0];
|
||||||
String fieldType = parts[1];
|
String fieldType = parts[1];
|
||||||
|
|
||||||
@ -391,17 +391,17 @@ public class Deodexerant {
|
|||||||
FieldIdItem fieldIdItem;
|
FieldIdItem fieldIdItem;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
fieldIdItem = FieldIdItem.getInternedFieldIdItem(dexFile, classType, fieldTypeItem, fieldNameItem);
|
fieldIdItem = FieldIdItem.getInternedFieldIdItem(dexFile, classTypeItem, fieldTypeItem, fieldNameItem);
|
||||||
if (fieldIdItem != null) {
|
if (fieldIdItem != null) {
|
||||||
return fieldIdItem;
|
return fieldIdItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
String superclassDescriptor = lookupSuperclass(classType.getTypeDescriptor());
|
String superclassDescriptor = lookupSuperclass(classTypeItem.getTypeDescriptor());
|
||||||
classType = TypeIdItem.getInternedTypeIdItem(dexFile, superclassDescriptor);
|
classTypeItem = TypeIdItem.getInternedTypeIdItem(dexFile, superclassDescriptor);
|
||||||
|
|
||||||
while (classType == null && superclassDescriptor != null) {
|
while (classTypeItem == null && superclassDescriptor != null) {
|
||||||
superclassDescriptor = lookupSuperclass(superclassDescriptor);
|
superclassDescriptor = lookupSuperclass(superclassDescriptor);
|
||||||
classType = TypeIdItem.getInternedTypeIdItem(dexFile, superclassDescriptor);
|
classTypeItem = TypeIdItem.getInternedTypeIdItem(dexFile, superclassDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
} while (classType != null);
|
} while (classType != null);
|
||||||
@ -434,7 +434,7 @@ public class Deodexerant {
|
|||||||
|
|
||||||
|
|
||||||
private class ClassData {
|
private class ClassData {
|
||||||
private final TypeIdItem ClassType;
|
private final String ClassType;
|
||||||
|
|
||||||
private boolean vtableLoaded = false;
|
private boolean vtableLoaded = false;
|
||||||
private String[] methodNames;
|
private String[] methodNames;
|
||||||
@ -447,7 +447,7 @@ public class Deodexerant {
|
|||||||
private SparseArray<FieldIdItem> resolvedFields;
|
private SparseArray<FieldIdItem> resolvedFields;
|
||||||
|
|
||||||
|
|
||||||
public ClassData(TypeIdItem classType) {
|
public ClassData(String classType) {
|
||||||
this.ClassType = classType;
|
this.ClassType = classType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -487,7 +487,7 @@ public class Deodexerant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void loadvtable() {
|
private void loadvtable() {
|
||||||
List<String> responseLines = sendMultilineCommand("V " + ClassType.getTypeDescriptor());
|
List<String> responseLines = sendMultilineCommand("V " + ClassType);
|
||||||
|
|
||||||
methodNames = new String[responseLines.size()];
|
methodNames = new String[responseLines.size()];
|
||||||
methodParams = new String[responseLines.size()];
|
methodParams = new String[responseLines.size()];
|
||||||
@ -516,7 +516,7 @@ public class Deodexerant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void loadFields() {
|
private void loadFields() {
|
||||||
List<String> responseLines = sendMultilineCommand("F " + ClassType.getTypeDescriptor());
|
List<String> responseLines = sendMultilineCommand("F " + ClassType);
|
||||||
|
|
||||||
instanceFields = new SparseArray<String>(responseLines.size());
|
instanceFields = new SparseArray<String>(responseLines.size());
|
||||||
resolvedFields = new SparseArray<FieldIdItem>(responseLines.size());
|
resolvedFields = new SparseArray<FieldIdItem>(responseLines.size());
|
||||||
|
Reference in New Issue
Block a user