Beispiel #1
0
        internal Prototype(Dex dex, BinaryReader reader)
        {
            Dex = dex;

            ShortyIndex     = reader.ReadUInt32();
            ReturnTypeIndex = reader.ReadUInt32();
            Parameters      = dex.ReadTypeList(reader.ReadUInt32());
        }
Beispiel #2
0
        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];
        }
Beispiel #3
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];
            }
        }
Beispiel #4
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;
                        }
                    }
                }
            }
        }
Beispiel #5
0
 public string GetName(Dex dex)
 {
     return(dex.GetString(NameIdx));
 }