Ensure class permissions are valid when resolving a field while deodexing
diff --git a/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/DeodexUtil.java b/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/DeodexUtil.java
index f31ec56..d4cf3a8 100644
--- a/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/DeodexUtil.java
+++ b/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/DeodexUtil.java
@@ -64,20 +64,21 @@
         return inlineMethodResolver.resolveExecuteInline(instruction);
     }
 
-    public FieldIdItem lookupField(ClassPath.ClassDef classDef, int fieldOffset) {
-        ClassPath.FieldDef field = classDef.getInstanceField(fieldOffset);
+    public FieldIdItem lookupField(ClassPath.ClassDef accessingClass, ClassPath.ClassDef instanceClass,
+                                   int fieldOffset) {
+        ClassPath.FieldDef field = instanceClass.getInstanceField(fieldOffset);
         if (field == null) {
             return null;
         }
 
-        return parseAndResolveField(classDef, field);
+        return parseAndResolveField(accessingClass, instanceClass, field);
     }
 
     private static final Pattern shortMethodPattern = Pattern.compile("([^(]+)\\(([^)]*)\\)(.+)");
 
-    public MethodIdItem lookupVirtualMethod(ClassPath.ClassDef accessingClass, ClassPath.ClassDef definingClass,
+    public MethodIdItem lookupVirtualMethod(ClassPath.ClassDef accessingClass, ClassPath.ClassDef instanceClass,
                                             int methodIndex) {
-        String method = definingClass.getVirtualMethod(methodIndex);
+        String method = instanceClass.getVirtualMethod(methodIndex);
         if (method == null) {
             return null;
         }
@@ -92,16 +93,16 @@
         String methodParams = m.group(2);
         String methodRet = m.group(3);
 
-        if (definingClass instanceof ClassPath.UnresolvedClassDef) {
+        if (instanceClass instanceof ClassPath.UnresolvedClassDef) {
             //if this is an unresolved class, the only way getVirtualMethod could have found a method is if the virtual
             //method being looked up was a method on java.lang.Object.
-            definingClass = ClassPath.getClassDef("Ljava/lang/Object;");
-        } else if (definingClass.isInterface()) {
-            definingClass = definingClass.getSuperclass();
-            assert definingClass != null;
+            instanceClass = ClassPath.getClassDef("Ljava/lang/Object;");
+        } else if (instanceClass.isInterface()) {
+            instanceClass = instanceClass.getSuperclass();
+            assert instanceClass != null;
         }
 
-        return parseAndResolveMethod(accessingClass, definingClass, methodName, methodParams, methodRet);
+        return parseAndResolveMethod(accessingClass, instanceClass, methodName, methodParams, methodRet);
     }
 
     private MethodIdItem parseAndResolveMethod(ClassPath.ClassDef accessingClass, ClassPath.ClassDef definingClass,
@@ -203,7 +204,6 @@
         do {
             TypeIdItem classTypeItem = TypeIdItem.lookupTypeIdItem(dexFile, methodClassDef.getClassType());
 
-
             if (classTypeItem != null) {
                 MethodIdItem methodIdItem = MethodIdItem.lookupMethodIdItem(dexFile, classTypeItem, protoItem, methodNameItem);
                 if (methodIdItem != null && checkClassAccess(accessingClass, methodClassDef)) {
@@ -229,7 +229,15 @@
         return classRef.substring(1, lastSlash);
     }
 
-    private FieldIdItem parseAndResolveField(ClassPath.ClassDef classDef, ClassPath.FieldDef field) {
+    /**
+     *
+     * @param accessingClass The class that contains the field reference. I.e. the class being deodexed
+     * @param instanceClass The inferred class type  of the object that the field is being accessed on
+     * @param field The field being accessed
+     * @return The FieldIdItem of the resolved field
+     */
+    private FieldIdItem parseAndResolveField(ClassPath.ClassDef accessingClass, ClassPath.ClassDef instanceClass,
+                                             ClassPath.FieldDef field) {
         String definingClass = field.definingClass;
         String fieldName = field.name;
         String fieldType = field.type;
@@ -244,7 +252,7 @@
             return null;
         }
 
-        ClassPath.ClassDef fieldClass = classDef;
+        ClassPath.ClassDef fieldClass = instanceClass;
 
         ArrayList<ClassPath.ClassDef> parents = new ArrayList<ClassPath.ClassDef>();
         parents.add(fieldClass);
@@ -263,7 +271,7 @@
             }
 
             FieldIdItem fieldIdItem = FieldIdItem.lookupFieldIdItem(dexFile, classTypeItem, fieldTypeItem, fieldNameItem);
-            if (fieldIdItem != null) {
+            if (fieldIdItem != null && checkClassAccess(accessingClass, fieldClass)) {
                 return fieldIdItem;
             }
         }
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 64f8ab6..9edf37b 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
@@ -3578,7 +3578,14 @@
             return false;
         }
 
-        FieldIdItem fieldIdItem = deodexUtil.lookupField(objectRegisterType.type, fieldOffset);
+        ClassPath.ClassDef accessingClass =
+                ClassPath.getClassDef(this.encodedMethod.method.getContainingClass(), false);
+        if (accessingClass == null) {
+            throw new ExceptionWithContext(String.format("Could not find ClassDef for current class: %s",
+                    this.encodedMethod.method.getContainingClass()));
+        }
+
+        FieldIdItem fieldIdItem = deodexUtil.lookupField(accessingClass, objectRegisterType.type, fieldOffset);
         if (fieldIdItem == null) {
             throw new ValidationException(String.format("Could not resolve the field in class %s at offset %d",
                     objectRegisterType.type.getClassType(), fieldOffset));