From 9d92fd3748eab8f23502dc11aff06e6e7d29d1f3 Mon Sep 17 00:00:00 2001 From: "JesusFreke@JesusFreke.com" Date: Wed, 27 Jan 2010 01:53:53 +0000 Subject: [PATCH] Implemented verification for iget-wide git-svn-id: https://smali.googlecode.com/svn/trunk@594 55b6fa8a-2a1e-11de-a435-ffa8d773f76a --- .../dexlib/Code/Analysis/MethodAnalyzer.java | 41 +++++++++++++++++++ 1 file changed, 41 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 6f9b48aa..5fda8858 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 @@ -538,6 +538,8 @@ public class MethodAnalyzer { return handle32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Char); case IGET_SHORT: return handle32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Short); + case IGET_WIDE: + return handleIgetWide(analyzedInstruction); } assert false; @@ -1743,6 +1745,45 @@ public class MethodAnalyzer { return true; } + private boolean handleIgetWide(AnalyzedInstruction analyzedInstruction) { + TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; + + RegisterType objectRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); + assert objectRegisterType != null; + if (objectRegisterType.category == RegisterType.Category.Unknown) { + return false; + } + checkRegister(objectRegisterType, ReferenceCategories); + + getAndCheckWideSourcePair(analyzedInstruction, instruction.getRegisterB()); + + //TODO: check access + //TODO: allow an uninitialized "this" reference, if the current method is an method + Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); + assert referencedItem instanceof FieldIdItem; + FieldIdItem field = (FieldIdItem)referencedItem; + + if (objectRegisterType.category != RegisterType.Category.Null && + !objectRegisterType.type.extendsClass(ClassPath.getClassDef(field.getContainingClass()))) { + throw new ValidationException(String.format("Cannot access field %s through type %s", + field.getFieldString(), objectRegisterType.type.getClassType())); + } + + RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); + + try { + checkRegister(fieldType, WideLowCategories); + } catch (ValidationException ex) { + throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " + + "for the instruction.", analyzedInstruction.instruction.opcode.name, + field.getFieldString())); + } + + setWideDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, fieldType); + + return true; + } + private static boolean checkArrayFieldAssignment(RegisterType.Category arrayFieldCategory, RegisterType.Category instructionCategory) { if (arrayFieldCategory == instructionCategory) {