mirror of
https://github.com/revanced/smali.git
synced 2025-05-05 09:04:25 +02:00
Implemented verification for fill-array-data
git-svn-id: https://smali.googlecode.com/svn/trunk@577 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
parent
ac8785e5d5
commit
472d3ea584
@ -2,6 +2,8 @@ package org.jf.dexlib.Code.Analysis;
|
||||
|
||||
import org.jf.dexlib.*;
|
||||
import org.jf.dexlib.Code.*;
|
||||
import org.jf.dexlib.Code.Format.ArrayDataPseudoInstruction;
|
||||
import org.jf.dexlib.Code.Format.Format;
|
||||
import org.jf.dexlib.Util.*;
|
||||
|
||||
import java.util.*;
|
||||
@ -462,6 +464,8 @@ public class MethodAnalyzer {
|
||||
return handleFilledNewArray(analyzedInstruction);
|
||||
case FILLED_NEW_ARRAY_RANGE:
|
||||
return handleFilledNewArrayRange(analyzedInstruction);
|
||||
case FILL_ARRAY_DATA:
|
||||
return handleFillArrayData(analyzedInstruction);
|
||||
}
|
||||
assert false;
|
||||
return false;
|
||||
@ -1058,6 +1062,75 @@ public class MethodAnalyzer {
|
||||
});
|
||||
}
|
||||
|
||||
private boolean handleFillArrayData(AnalyzedInstruction analyzedInstruction) {
|
||||
SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction;
|
||||
|
||||
int register = instruction.getRegisterA();
|
||||
RegisterType registerType = analyzedInstruction.getPreInstructionRegisterType(register);
|
||||
assert registerType != null;
|
||||
|
||||
if (registerType.category == RegisterType.Category.Unknown ||
|
||||
registerType.category == RegisterType.Category.Null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (registerType.category != RegisterType.Category.Reference) {
|
||||
throw new ValidationException(String.format("Cannot use fill-array-data with non-array register v%d of " +
|
||||
"type %s", register, registerType.toString()));
|
||||
}
|
||||
|
||||
assert registerType.type instanceof ClassPath.ArrayClassDef;
|
||||
ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)registerType.type;
|
||||
|
||||
if (arrayClassDef.getArrayDimensions() != 1) {
|
||||
throw new ValidationException(String.format("Cannot use fill-array-data with array type %s. It can only " +
|
||||
"be used with a one-dimensional array of primitives.", arrayClassDef.getClassType()));
|
||||
}
|
||||
|
||||
int elementWidth;
|
||||
switch (arrayClassDef.getBaseElementClass().getClassType().charAt(0)) {
|
||||
case 'Z':
|
||||
case 'B':
|
||||
elementWidth = 1;
|
||||
break;
|
||||
case 'C':
|
||||
case 'S':
|
||||
elementWidth = 2;
|
||||
break;
|
||||
case 'I':
|
||||
case 'F':
|
||||
elementWidth = 4;
|
||||
break;
|
||||
case 'J':
|
||||
case 'D':
|
||||
elementWidth = 8;
|
||||
break;
|
||||
default:
|
||||
throw new ValidationException(String.format("Cannot use fill-array-data with array type %s. It can " +
|
||||
"only be used with a one-dimensional array of primitives.", arrayClassDef.getClassType()));
|
||||
}
|
||||
|
||||
|
||||
int arrayDataOffset = ((OffsetInstruction)analyzedInstruction.instruction).getTargetAddressOffset();
|
||||
AnalyzedInstruction arrayDataInstruction = this.instructions.get(arrayDataOffset);
|
||||
if (arrayDataInstruction == null || arrayDataInstruction.instruction.getFormat() != Format.ArrayData) {
|
||||
throw new ValidationException(String.format("Could not find an array data structure at code address 0x%x",
|
||||
arrayDataOffset));
|
||||
}
|
||||
|
||||
ArrayDataPseudoInstruction arrayDataPseudoInstruction =
|
||||
(ArrayDataPseudoInstruction)arrayDataInstruction.instruction;
|
||||
|
||||
if (elementWidth != arrayDataPseudoInstruction.getElementWidth()) {
|
||||
throw new ValidationException(String.format("The array data at code address 0x%x does not have the " +
|
||||
"correct element width for array type %s. Expecting element width %d, got element width %d.",
|
||||
arrayDataOffset, arrayClassDef.getClassType(), elementWidth,
|
||||
arrayDataPseudoInstruction.getElementWidth()));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void checkRegister(RegisterType registerType, EnumSet validCategories) {
|
||||
if (!validCategories.contains(registerType.category)) {
|
||||
//TODO: add expected categories to error message
|
||||
|
Loading…
x
Reference in New Issue
Block a user