diff --git a/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/ClassPath.java b/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/ClassPath.java index 89273cdb..f3204624 100644 --- a/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/ClassPath.java +++ b/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/ClassPath.java @@ -566,6 +566,18 @@ public class ClassPath { } } + public static class FieldDef { + public final String definingClass; + public final String name; + public final String type; + + public FieldDef(String definingClass, String name, String type) { + this.definingClass = definingClass; + this.name = name; + this.type = type; + } + } + public static class ClassDef implements Comparable { private final String classType; private final ClassDef superclass; @@ -583,7 +595,7 @@ public class ClassPath { private final String[] vtable; private final HashMap virtualMethodLookup; - private final SparseArray instanceFields; + private final SparseArray instanceFields; public final static int ArrayClassDef = 0; public final static int PrimitiveClassDef = 1; @@ -736,7 +748,7 @@ public class ClassPath { return virtualMethodLookup.containsKey(method); } - public String getInstanceField(int fieldOffset) { + public FieldDef getInstanceField(int fieldOffset) { return this.instanceFields.get(fieldOffset, null); } @@ -747,12 +759,12 @@ public class ClassPath { return this.vtable[vtableIndex]; } - private void swap(byte[] fieldTypes, String[] fields, int position1, int position2) { + private void swap(byte[] fieldTypes, FieldDef[] fields, int position1, int position2) { byte tempType = fieldTypes[position1]; fieldTypes[position1] = fieldTypes[position2]; fieldTypes[position2] = tempType; - String tempField = fields[position1]; + FieldDef tempField = fields[position1]; fields[position1] = fields[position2]; fields[position2] = tempField; } @@ -915,11 +927,9 @@ public class ClassPath { int lastItemIndex = instanceFields.size()-1; int fieldOffset = instanceFields.keyAt(lastItemIndex); - String lastField = instanceFields.valueAt(lastItemIndex); + FieldDef lastField = instanceFields.valueAt(lastItemIndex); - int fieldTypeIndex = lastField.indexOf(":") + 1; - - switch (lastField.charAt(fieldTypeIndex)) { + switch (lastField.type.charAt(0)) { case 'J': case 'D': return fieldOffset + 8; @@ -928,7 +938,7 @@ public class ClassPath { } } - private SparseArray loadFields(TempClassInfo classInfo) { + private SparseArray loadFields(TempClassInfo classInfo) { //This is a bit of an "involved" operation. We need to follow the same algorithm that dalvik uses to //arrange fields, so that we end up with the same field offsets (which is needed for deodexing). //See mydroid/dalvik/vm/oo/Class.c - computeFieldOffsets() @@ -937,12 +947,12 @@ public class ClassPath { final byte WIDE = 1; final byte OTHER = 2; - String[] fields = null; + FieldDef[] fields = null; //the "type" for each field in fields. 0=reference,1=wide,2=other byte[] fieldTypes = null; if (classInfo.instanceFields != null) { - fields = new String[classInfo.instanceFields.length]; + fields = new FieldDef[classInfo.instanceFields.length]; fieldTypes = new byte[fields.length]; for (int i=0; i instanceFields = new SparseArray(totalFieldCount); + SparseArray instanceFields = new SparseArray(totalFieldCount); int fieldOffset; @@ -1052,10 +1061,8 @@ public class ClassPath { fieldOffset = instanceFields.keyAt(superFieldCount-1); - String lastSuperField = superclass.instanceFields.valueAt(superFieldCount-1); - assert lastSuperField.indexOf(':') >= 0; - assert lastSuperField.indexOf(':') < lastSuperField.length()-1; //the ':' shouldn't be the last char - char fieldType = lastSuperField.charAt(lastSuperField.indexOf(':') + 1); + FieldDef lastSuperField = superclass.instanceFields.valueAt(superFieldCount-1); + char fieldType = lastSuperField.type.charAt(0); if (fieldType == 'J' || fieldType == 'D') { fieldOffset += 8; } else { @@ -1068,7 +1075,7 @@ public class ClassPath { boolean gotDouble = false; for (int i=0; i parents = new ArrayList(); + parents.add(fieldClass); + + while (fieldClass != null && !fieldClass.getClassType().equals(definingClass)) { + fieldClass = fieldClass.getSuperclass(); + parents.add(fieldClass); + } + + for (int i=parents.size()-1; i>=0; i--) { + fieldClass = parents.get(i); + TypeIdItem classTypeItem = TypeIdItem.lookupTypeIdItem(dexFile, fieldClass.getClassType()); if (classTypeItem == null) { continue; @@ -236,10 +242,7 @@ public class DeodexUtil { if (fieldIdItem != null) { return fieldIdItem; } - - fieldClass = fieldClass.getSuperclass(); - } while (fieldClass != null); - + } return null; }