public void parse() throws IOException { setDexOptimizationData(dexSignatureBlock.getDexOptimizationData()); int classSize = (int) dexPointerBlock.getClassDefsSize(); file.seek(dexPointerBlock.getClassDefsOffset()); classMap = new HashMap<Integer, ClassHolder>(); HashMap<Integer, TempClassHolder> tempClassMap = new HashMap<Integer, TempClassHolder>(); for (int i = 0; i < classSize; ++i) { int classIdx = (int) read32Bit(); ClassHolder classHolder = new ClassHolder(); TempClassHolder tempClassHolder = new TempClassHolder(); classHolder.access = (int) read32Bit(); classHolder.superclassTypeId = (int) read32Bit(); tempClassHolder.interfacesOffset = readFileOffset(); classHolder.sourceFileNameStringId = (int) read32Bit(); tempClassHolder.annotationsOffset = readFileOffset(); tempClassHolder.classDataOffset = readFileOffset(); tempClassHolder.staticValuesOffset = readFileOffset(); Integer mapKey = new Integer(classIdx); classMap.put(mapKey, classHolder); tempClassMap.put(mapKey, tempClassHolder); dump( accessFlagsToString(classHolder.access, ItemType.CLASS) + dexTypeIdsBlock.getClassName(classIdx)); } // Now process the auxiliary data blocks according to the offsets stored // in TempClassHolder instances for (Iterator<Integer> it = classMap.keySet().iterator(); it.hasNext(); ) { Integer key = it.next(); // if(dexTypeIdsBlock.getClassName(key.intValue()).startsWith("es/ugr/decsai/lazy/Metauser")){ System.out.println("---------->" + dexTypeIdsBlock.getClassName(key.intValue())); ClassHolder classHolder = classMap.get(key); dump( "// " + accessFlagsToString(classHolder.access, ItemType.CLASS) + " class " + dexTypeIdsBlock.getClassName(key.intValue()) + ":"); if (classHolder.superclassTypeId >= 0) dump("// super: " + dexTypeIdsBlock.getClassName(classHolder.superclassTypeId)); if (classHolder.sourceFileNameStringId >= 0) dump("// source: " + dexStringIdsBlock.getString(classHolder.sourceFileNameStringId)); TempClassHolder tempClassHolder = tempClassMap.get(key); // Build the interface type table for the class if (tempClassHolder.interfacesOffset != 0L) { file.seek(tempClassHolder.interfacesOffset); int interfacesSize = (int) read32Bit(); classHolder.interfaceTypes = new int[interfacesSize]; for (int i = 0; i < interfacesSize; ++i) { classHolder.interfaceTypes[i] = read16Bit(); dump("// implements " + dexTypeIdsBlock.getType(classHolder.interfaceTypes[i])); } } // Build the class data table if (tempClassHolder.classDataOffset != 0L) { file.seek(tempClassHolder.classDataOffset); int staticFieldsSize = (int) readVLN(); dump("static fields size: " + staticFieldsSize); int instanceFieldsSize = (int) readVLN(); dump("instance fields size: " + instanceFieldsSize); int directMethodsSize = (int) readVLN(); dump("direct methods size: " + directMethodsSize); int virtualMethodsSize = (int) readVLN(); dump("virtual methods size: " + virtualMethodsSize); // Process the static fields if (staticFieldsSize > 0) { classHolder.staticFields = new FieldHolder[staticFieldsSize]; int fieldIdCounter = 0; for (int i = 0; i < staticFieldsSize; ++i) { FieldHolder staticFieldHolder = new FieldHolder(); fieldIdCounter += (int) readVLN(); staticFieldHolder.fieldId = fieldIdCounter; staticFieldHolder.access = (int) readVLN(); classHolder.staticFields[i] = staticFieldHolder; dump( "// static field[" + i + "]: " + dexFieldIdsBlock.getFieldShortName(staticFieldHolder.fieldId)); } } // Process the instance fields if (instanceFieldsSize > 0) { classHolder.instanceFields = new FieldHolder[instanceFieldsSize]; int fieldIdCounter = 0; for (int i = 0; i < instanceFieldsSize; ++i) { FieldHolder instanceFieldHolder = new FieldHolder(); fieldIdCounter += (int) readVLN(); instanceFieldHolder.fieldId = fieldIdCounter; instanceFieldHolder.access = (int) readVLN(); classHolder.instanceFields[i] = instanceFieldHolder; dump( "// instance field[" + i + "]: " + dexFieldIdsBlock.getFieldShortName(instanceFieldHolder.fieldId)); } } // Process the direct methods if (directMethodsSize > 0) { classHolder.directMethods = new MethodHolder[directMethodsSize]; int methodIdCounter = 0; for (int i = 0; i < directMethodsSize; ++i) { MethodHolder directMethodHolder = new MethodHolder(); methodIdCounter += (int) readVLN(); directMethodHolder.methodId = methodIdCounter; directMethodHolder.access = (int) readVLN(); directMethodHolder.offset = readFileOffsetVLN(); classHolder.directMethods[i] = directMethodHolder; dump( "// direct method[" + i + "]: " + dexMethodIdsBlock.getProto(directMethodHolder.methodId)); } } // Process the virtual methods if (virtualMethodsSize > 0) { classHolder.virtualMethods = new MethodHolder[virtualMethodsSize]; int methodIdCounter = 0; for (int i = 0; i < virtualMethodsSize; ++i) { MethodHolder virtualMethodHolder = new MethodHolder(); methodIdCounter += (int) readVLN(); virtualMethodHolder.methodId = methodIdCounter; virtualMethodHolder.access = (int) readVLN(); virtualMethodHolder.offset = readFileOffsetVLN(); classHolder.virtualMethods[i] = virtualMethodHolder; dump( "// virtual method[" + i + "]: " + dexMethodIdsBlock.getProto(virtualMethodHolder.methodId)); } } } if (tempClassHolder.staticValuesOffset != 0L) { DexEncodedArrayParser deap = new DexEncodedArrayParser(); deap.setRandomAccessFile(file); deap.setDumpFile(dump); deap.setDexStringIdsBlock(dexStringIdsBlock); deap.setDexTypeIdsBlock(dexTypeIdsBlock); deap.setDexFieldIdsBlock(dexFieldIdsBlock); deap.setDexMethodIdsBlock(dexMethodIdsBlock); deap.setFilePosition(tempClassHolder.staticValuesOffset); deap.parse(); for (int i = 0; i < deap.getArraySize(); ++i) { if (i < classHolder.staticFields.length) { // paranoia, it has to be smaller FieldHolder fieldHolder = classHolder.staticFields[i]; fieldHolder.initialValue = deap.getArrayElement(i); } } } if (tempClassHolder.annotationsOffset != 0L) { DexAnnotationParser dexAnnotationParser = new DexAnnotationParser(); dexAnnotationParser.setRandomAccessFile(file); dexAnnotationParser.setDumpFile(dump); dexAnnotationParser.setDexTypeIdsBlock(dexTypeIdsBlock); dexAnnotationParser.setDexStringIdsBlock(dexStringIdsBlock); dexAnnotationParser.setDexFieldIdsBlock(dexFieldIdsBlock); dexAnnotationParser.setDexMethodIdsBlock(dexMethodIdsBlock); dexAnnotationParser.setDexSignatureBlock(dexSignatureBlock); try { dexAnnotationParser.parse(tempClassHolder.annotationsOffset); } catch (UnknownInstructionException ex) { } // can't happen classHolder.annotationParser = dexAnnotationParser; } // } } }