From 51cec00885cdc063ee27ee6b67680189be34f8f9 Mon Sep 17 00:00:00 2001 From: "JesusFreke@JesusFreke.com" Date: Wed, 27 Jan 2010 07:09:32 +0000 Subject: [PATCH] Implemented verification for sput-object git-svn-id: https://smali.googlecode.com/svn/trunk@605 55b6fa8a-2a1e-11de-a435-ffa8d773f76a --- .../dexlib/Code/Analysis/MethodAnalyzer.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/MethodAnalyzer.java b/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/MethodAnalyzer.java index dee20e93..2b8d0ad4 100644 --- a/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/MethodAnalyzer.java +++ b/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/MethodAnalyzer.java @@ -582,6 +582,8 @@ public class MethodAnalyzer { return handle32BitPrimitiveSput(analyzedInstruction, RegisterType.Category.Short); case SPUT_WIDE: return handleSputWide(analyzedInstruction); + case SPUT_OBJECT: + return handleSputObject(analyzedInstruction); } assert false; @@ -2133,6 +2135,40 @@ public class MethodAnalyzer { return true; } + private boolean handleSputObject(AnalyzedInstruction analyzedInstruction) { + SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction; + + RegisterType sourceRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterA()); + assert sourceRegisterType != null; + if (sourceRegisterType.category == RegisterType.Category.Unknown) { + return false; + } + checkRegister(sourceRegisterType, ReferenceCategories); + + //TODO: check access + Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); + assert referencedItem instanceof FieldIdItem; + FieldIdItem field = (FieldIdItem)referencedItem; + + RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); + + if (fieldType.category != RegisterType.Category.Reference) { + throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " + + "for the instruction.", analyzedInstruction.instruction.opcode.name, + field.getFieldString())); + } + + if (sourceRegisterType.category != RegisterType.Category.Null && + !fieldType.type.isInterface() && + !sourceRegisterType.type.extendsClass(fieldType.type)) { + + throw new ValidationException(String.format("Cannot store a value of type %s into a field of type %s", + sourceRegisterType.type.getClassType(), fieldType.type.getClassType())); + } + + return true; + } + private static boolean checkArrayFieldAssignment(RegisterType.Category arrayFieldCategory, RegisterType.Category instructionCategory) { if (arrayFieldCategory == instructionCategory) {