mirror of
https://github.com/revanced/smali.git
synced 2025-06-13 04:27:38 +02:00
Implemented verification for the literal binary operation instructions
git-svn-id: https://smali.googlecode.com/svn/trunk@619 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
@ -860,6 +860,45 @@ public class MethodAnalyzer {
|
|||||||
handleBinary2AddrOp(analyzedInstruction, WideLowCategories, WideLowCategories,
|
handleBinary2AddrOp(analyzedInstruction, WideLowCategories, WideLowCategories,
|
||||||
RegisterType.Category.DoubleLo, false);
|
RegisterType.Category.DoubleLo, false);
|
||||||
return;
|
return;
|
||||||
|
case ADD_INT_LIT16:
|
||||||
|
case RSUB_INT:
|
||||||
|
case MUL_INT_LIT16:
|
||||||
|
case DIV_INT_LIT16:
|
||||||
|
case REM_INT_LIT16:
|
||||||
|
handleLiteralBinaryOp(analyzedInstruction, Primitive32BitCategories, RegisterType.Category.Integer,
|
||||||
|
false);
|
||||||
|
return;
|
||||||
|
case AND_INT_LIT16:
|
||||||
|
case OR_INT_LIT16:
|
||||||
|
case XOR_INT_LIT16:
|
||||||
|
handleLiteralBinaryOp(analyzedInstruction, Primitive32BitCategories, RegisterType.Category.Integer,
|
||||||
|
true);
|
||||||
|
return;
|
||||||
|
case ADD_INT_LIT8:
|
||||||
|
case RSUB_INT_LIT8:
|
||||||
|
case MUL_INT_LIT8:
|
||||||
|
case DIV_INT_LIT8:
|
||||||
|
case REM_INT_LIT8:
|
||||||
|
case SHL_INT_LIT8:
|
||||||
|
handleLiteralBinaryOp(analyzedInstruction, Primitive32BitCategories, RegisterType.Category.Integer,
|
||||||
|
false);
|
||||||
|
return;
|
||||||
|
case AND_INT_LIT8:
|
||||||
|
case OR_INT_LIT8:
|
||||||
|
case XOR_INT_LIT8:
|
||||||
|
handleLiteralBinaryOp(analyzedInstruction, Primitive32BitCategories, RegisterType.Category.Integer,
|
||||||
|
true);
|
||||||
|
return;
|
||||||
|
case SHR_INT_LIT8:
|
||||||
|
handleLiteralBinaryOp(analyzedInstruction, Primitive32BitCategories,
|
||||||
|
getDestTypeForLiteralShiftRight(analyzedInstruction, true), false);
|
||||||
|
return;
|
||||||
|
case USHR_INT_LIT8:
|
||||||
|
handleLiteralBinaryOp(analyzedInstruction, Primitive32BitCategories,
|
||||||
|
getDestTypeForLiteralShiftRight(analyzedInstruction, false), false);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
assert false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2384,6 +2423,99 @@ public class MethodAnalyzer {
|
|||||||
RegisterType.getRegisterType(destRegisterCategory, null));
|
RegisterType.getRegisterType(destRegisterCategory, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleLiteralBinaryOp(AnalyzedInstruction analyzedInstruction, EnumSet validSourceCategories,
|
||||||
|
RegisterType.Category destRegisterCategory, boolean checkForBoolean) {
|
||||||
|
TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;
|
||||||
|
|
||||||
|
RegisterType sourceRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(),
|
||||||
|
validSourceCategories);
|
||||||
|
|
||||||
|
if (checkForBoolean) {
|
||||||
|
if (BooleanCategories.contains(sourceRegisterType.category)) {
|
||||||
|
long literal = ((LiteralInstruction)analyzedInstruction.instruction).getLiteral();
|
||||||
|
if (literal == 0 || literal == 1) {
|
||||||
|
destRegisterCategory = RegisterType.Category.Boolean;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction,
|
||||||
|
RegisterType.getRegisterType(destRegisterCategory, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
private RegisterType.Category getDestTypeForLiteralShiftRight(AnalyzedInstruction analyzedInstruction,
|
||||||
|
boolean signedShift) {
|
||||||
|
TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;
|
||||||
|
|
||||||
|
RegisterType sourceRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(),
|
||||||
|
Primitive32BitCategories);
|
||||||
|
long literalShift = ((LiteralInstruction)analyzedInstruction.instruction).getLiteral();
|
||||||
|
|
||||||
|
if (literalShift == 0) {
|
||||||
|
return sourceRegisterType.category;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegisterType.Category destRegisterCategory;
|
||||||
|
if (!signedShift) {
|
||||||
|
destRegisterCategory = RegisterType.Category.Integer;
|
||||||
|
} else {
|
||||||
|
destRegisterCategory = sourceRegisterType.category;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (literalShift >= 32) {
|
||||||
|
//TODO: add warning
|
||||||
|
return destRegisterCategory;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (sourceRegisterType.category) {
|
||||||
|
case Integer:
|
||||||
|
case Float:
|
||||||
|
if (!signedShift) {
|
||||||
|
if (literalShift > 24) {
|
||||||
|
return RegisterType.Category.PosByte;
|
||||||
|
}
|
||||||
|
if (literalShift >= 16) {
|
||||||
|
return RegisterType.Category.Char;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (literalShift >= 24) {
|
||||||
|
return RegisterType.Category.Byte;
|
||||||
|
}
|
||||||
|
if (literalShift >= 16) {
|
||||||
|
return RegisterType.Category.Short;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Short:
|
||||||
|
if (signedShift && literalShift >= 8) {
|
||||||
|
return RegisterType.Category.Byte;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PosShort:
|
||||||
|
if (literalShift >= 8) {
|
||||||
|
return RegisterType.Category.PosByte;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Char:
|
||||||
|
if (literalShift > 8) {
|
||||||
|
return RegisterType.Category.PosByte;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Byte:
|
||||||
|
break;
|
||||||
|
case PosByte:
|
||||||
|
return RegisterType.Category.PosByte;
|
||||||
|
case Null:
|
||||||
|
case One:
|
||||||
|
case Boolean:
|
||||||
|
return RegisterType.Category.Null;
|
||||||
|
default:
|
||||||
|
assert false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return destRegisterCategory;
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean checkArrayFieldAssignment(RegisterType.Category arrayFieldCategory,
|
private static boolean checkArrayFieldAssignment(RegisterType.Category arrayFieldCategory,
|
||||||
RegisterType.Category instructionCategory) {
|
RegisterType.Category instructionCategory) {
|
||||||
if (arrayFieldCategory == instructionCategory) {
|
if (arrayFieldCategory == instructionCategory) {
|
||||||
|
Reference in New Issue
Block a user