internal Prototype(Dex dex, BinaryReader reader) { Dex = dex; ShortyIndex = reader.ReadUInt32(); ReturnTypeIndex = reader.ReadUInt32(); Parameters = dex.ReadTypeList(reader.ReadUInt32()); }
internal Field(uint id, Dex dex, BinaryReader reader) { Id = id; Dex = dex; ClassIndex = reader.ReadUInt16(); TypeIndex = reader.ReadUInt16(); NameIndex = reader.ReadUInt32(); Annotations = new Annotation[0]; }
/// <summary> /// Constructor /// </summary> /// <param name='dex'> /// Pointer to the DEX file this class was loaded from /// </param> internal Class(Dex dex, BinaryReader reader) { Dex = dex; ClassIndex = reader.ReadUInt32(); AccessFlags = (AccessFlag)reader.ReadUInt32(); SuperClassIndex = reader.ReadUInt32(); var interfacesOffset = reader.ReadUInt32(); SourceFileIndex = reader.ReadUInt32(); var annotationsOffset = reader.ReadUInt32(); var classDataOffset = reader.ReadUInt32(); var staticValuesOffset = reader.ReadUInt32(); Interfaces = dex.ReadTypeList(interfacesOffset); var fieldAnnotations = new Dictionary <uint, List <Annotation> >(); var methodAnnotations = new Dictionary <uint, List <Annotation> >(); var parameterAnnotations = new Dictionary <uint, List <Annotation> >(); if (annotationsOffset != 0) { reader.BaseStream.Position = annotationsOffset; // annotations_directory_item var classAnnotationsOffset = reader.ReadUInt32(); var annotatedFieldsCount = reader.ReadUInt32(); var annotatedMethodsCount = reader.ReadUInt32(); var annotatedParametersCount = reader.ReadUInt32(); for (int i = 0; i < annotatedFieldsCount; i++) { // field_annotation var fieldIndex = reader.ReadUInt32(); var annotations = Annotation.ReadAnnotations(reader); fieldAnnotations.Add(fieldIndex, annotations); } for (int i = 0; i < annotatedMethodsCount; i++) { // method_annotation var methodIndex = reader.ReadUInt32(); var annotations = Annotation.ReadAnnotations(reader); methodAnnotations.Add(methodIndex, annotations); } for (int i = 0; i < annotatedParametersCount; i++) { // parameter_annotation var methodIndex = reader.ReadUInt32(); var annotations = Annotation.ReadAnnotations(reader); parameterAnnotations.Add(methodIndex, annotations); } if (classAnnotationsOffset > 0) { reader.BaseStream.Position = classAnnotationsOffset; Annotations = Annotation.ReadAnnotationSetItem(reader); } } if (classDataOffset != 0) { reader.BaseStream.Position = classDataOffset; var staticFieldsCount = Leb128.ReadUleb(reader); var instanceFieldsCount = Leb128.ReadUleb(reader); var directMethodsCount = Leb128.ReadUleb(reader); var virtualMethodsCount = Leb128.ReadUleb(reader); StaticFields = ReadFields(staticFieldsCount, reader, fieldAnnotations); InstanceFields = ReadFields(instanceFieldsCount, reader, fieldAnnotations); DirectMethods = ReadMethods(directMethodsCount, reader, methodAnnotations, parameterAnnotations); VirtualMethods = ReadMethods(virtualMethodsCount, reader, methodAnnotations, parameterAnnotations); } else { StaticFields = new Field[0]; InstanceFields = new Field[0]; DirectMethods = new Method[0]; VirtualMethods = new Method[0]; } if (staticValuesOffset != 0) { reader.BaseStream.Position = staticValuesOffset; var size = Leb128.ReadUleb(reader); var values = new EncodedValue[size]; for (int i = 0; i < (int)size; i++) { values[i] = EncodedValue.parse(reader); } StaticFieldsValues = values; } else { StaticFieldsValues = new EncodedValue[0]; } }
internal Method(uint id, Dex dex, BinaryReader reader, uint codeOffset) { Id = id; Dex = dex; ClassIndex = reader.ReadUInt16(); PrototypeIndex = reader.ReadUInt16(); NameIndex = reader.ReadUInt32(); Annotations = new Annotation[0]; ParameterAnnotations = new List <Annotation>(); // This method has no opcodes, must be abstract or native. // Or the method is being loaded directly from the methods list if (codeOffset != 0) { reader.BaseStream.Position = codeOffset; RegistersSize = reader.ReadUInt16(); ArgumentsSize = reader.ReadUInt16(); ReturnValuesSize = reader.ReadUInt16(); var numberOfTryItems = reader.ReadUInt16(); // Not parsing debug info /*var debugInfoOffset =*/ reader.ReadUInt32(); CodeLength = reader.ReadUInt32(); CodeOffset = reader.BaseStream.Position; // Skip the opcode block reader.BaseStream.Position += CodeLength * 2; // Skip the optional padding if ((numberOfTryItems != 0) && (CodeLength % 2 != 0)) { reader.BaseStream.Position += 2; } // Load the try blocks if (numberOfTryItems != 0) { TryCatchBlocks = new TryCatchBlock[numberOfTryItems]; var handlerOffsets = new long[numberOfTryItems]; // read Try for (int i = 0; i < numberOfTryItems; i++) { var tryCatch = new TryCatchBlock(CodeOffset); tryCatch.StartAddress = reader.ReadUInt32(); tryCatch.InstructionCount = reader.ReadUInt16(); TryCatchBlocks [i] = tryCatch; handlerOffsets[i] = reader.ReadUInt16(); } var encodedCatchHandlerListOffset = reader.BaseStream.Position; // Size of the list, could be used to confirm the DEX is properly // built. For this purpose will assume DEX files are always good Leb128.ReadUleb(reader); // read Catch blocks for (int i = 0; i < numberOfTryItems; i++) { //encoded_catch_handler if (handlerOffsets [i] > 0) { reader.BaseStream.Position = encodedCatchHandlerListOffset + handlerOffsets [i]; var handlersCount = Leb128.ReadLeb(reader); var handlers = new CatchHandler[handlersCount <= 0 ? Math.Abs(handlersCount) + 1 : handlersCount]; for (int j = 0; j < Math.Abs(handlersCount); j++) { var catchHandler = new CatchHandler(CodeOffset); catchHandler.TypeIndex = Leb128.ReadUleb(reader); catchHandler.Address = Leb128.ReadUleb(reader); handlers [j] = catchHandler; } // parse the catch all block if (handlersCount <= 0) { var catchHandler = new CatchHandler(CodeOffset); catchHandler.TypeIndex = 0; catchHandler.Address = Leb128.ReadUleb(reader); handlers [handlers.Length - 1] = catchHandler; } TryCatchBlocks [i].Handlers = handlers; } } } } }
public string GetName(Dex dex) { return(dex.GetString(NameIdx)); }