Пример #1
0
        private void ReadMapList(BinaryReader reader)
        {
            reader.PreserveCurrentPosition(header.MapOffset, () => {
                var mapsize = reader.ReadUInt32();
                for (var i = 0; i < mapsize; i++)
                {
                    var type = (TypeCodes)reader.ReadUInt16();
                    reader.ReadUInt16(); // unused
                    var size = reader.ReadUInt32();
                    var offset = reader.ReadUInt32();

                    map.Add(type, size, offset);
                }
            });
        }
Пример #2
0
 private void ReadTypesReferences(BinaryReader reader)
 {
     reader.PreserveCurrentPosition(Header.TypeReferencesOffset, () =>
     {
         for (var i = 0; i < Header.TypeReferencesSize; i++)
         {
             var descriptorIndex = reader.ReadInt32();
             var descriptor = Dex.Strings[descriptorIndex];
             TypeDescriptor.Fill(descriptor, Dex.TypeReferences[i], Dex);
         }
     });
 }
Пример #3
0
 private void ReadParameters(BinaryReader reader, Prototype prototype, uint parametersOffset)
 {
     reader.PreserveCurrentPosition(parametersOffset, () =>
     {
         var typecount = reader.ReadUInt32();
         for (var j = 0; j < typecount; j++)
         {
             var parameter = new Parameter();
             var typeIndex = reader.ReadUInt16();
             parameter.Type = Dex.TypeReferences[typeIndex];
             prototype.Parameters.Add(parameter);
         }
     });
 }
Пример #4
0
 private void ReadStaticValues(BinaryReader reader, ClassDefinition classDefinition, uint staticValuesOffset)
 {
     reader.PreserveCurrentPosition(staticValuesOffset, () =>
     {
         var values = ReadValues(reader);
         for (var j = 0; j < values.Length; j++)
             classDefinition.Fields[j].Value = values[j];
     });
 }
Пример #5
0
 private void ReadInterfaces(BinaryReader reader, ClassDefinition classDefinition, uint interfaceOffset)
 {
     reader.PreserveCurrentPosition(interfaceOffset, () =>
     {
         var typecount = reader.ReadUInt32();
         for (var j = 0; j < typecount; j++)
         {
             var typeIndex = reader.ReadUInt16();
             classDefinition.Interfaces.Add((ClassReference)Dex.TypeReferences[typeIndex]);
         }
     });
 }
Пример #6
0
        private void ReadMethodBody(BinaryReader reader, MethodDefinition mdef, uint codeOffset)
        {
            reader.PreserveCurrentPosition(codeOffset, () =>
            {
                var registersSize = reader.ReadUInt16();
                var incomingArgsSize = reader.ReadUInt16();
                var outgoingArgsSize = reader.ReadUInt16();
                var triesSize = reader.ReadUInt16();
                var debugOffset = reader.ReadUInt32();

                mdef.Body = new MethodBody(mdef, registersSize)
                {
                    IncomingArguments = incomingArgsSize,
                    OutgoingArguments = outgoingArgsSize
                };

                var ireader = new InstructionReader(Dex, mdef);
                ireader.ReadFrom(reader);

                if ((triesSize != 0) && (ireader.Codes.Length % 2 != 0))
                    reader.ReadUInt16(); // padding (4-byte alignment)

                if (triesSize != 0)
                    ReadExceptionHandlers(reader, mdef, ireader, triesSize);

                if (debugOffset != 0)
                    ReadDebugInfo(reader, mdef, debugOffset);
            });
        }
Пример #7
0
        private void ReadMethodReferences(BinaryReader reader)
        {
            reader.PreserveCurrentPosition(header.MethodReferencesOffset, () =>
            {
                for (int i = 0; i < header.MethodReferencesSize; i++)
                {
                    int classIndex = reader.ReadUInt16();
                    int prototypeIndex = reader.ReadUInt16();
                    int nameIndex = reader.ReadInt32();

                    var mref = new MethodReference();
                    mref.Owner = (CompositeType) typeReferences[classIndex];
                    // Clone the prototype so we can annotate & update it easily
                    mref.Prototype = prototypes[prototypeIndex].Clone();
                    mref.Name = strings[nameIndex];

                    methodReferences.Add(mref);
                }
            });
        }
Пример #8
0
        private void ReadDebugInfo(BinaryReader reader, MethodDefinition mdef, uint debugOffset)
        {
            reader.PreserveCurrentPosition(debugOffset, () =>
            {
                var debugInfo = new DebugInfo(mdef.Body);
                mdef.Body.DebugInfo = debugInfo;

                var lineStart = reader.ReadULEB128();
                debugInfo.LineStart = lineStart;

                var parametersSize = reader.ReadULEB128();
                for (var i = 0; i < parametersSize; i++)
                {
                    var index = reader.ReadULEB128P1();
                    string name = null;
                    if (index != DexConsts.NoIndex && index >= 0)
                        name = Dex.Strings[(int)index];
                    debugInfo.Parameters.Add(name);
                }

                while (true)
                {
                    var ins = new DebugInstruction {OpCode = (DebugOpCodes) reader.ReadByte()};
                    debugInfo.DebugInstructions.Add(ins);

                    uint registerIndex;
                    long nameIndex;
                    string name;

                    switch (ins.OpCode)
                    {
                        case DebugOpCodes.AdvancePc:
                            // uleb128 addr_diff
                            var addrDiff = reader.ReadULEB128();
                            ins.Operands.Add(addrDiff);
                            break;
                        case DebugOpCodes.AdvanceLine:
                            // sleb128 line_diff
                            var lineDiff = reader.ReadSLEB128();
                            ins.Operands.Add(lineDiff);
                            break;
                        case DebugOpCodes.EndLocal:
                        case DebugOpCodes.RestartLocal:
                            // uleb128 register_num
                            registerIndex = reader.ReadULEB128();
                            ins.Operands.Add(mdef.Body.Registers[(int)registerIndex]);
                            break;
                        case DebugOpCodes.SetFile:
                            // uleb128p1 name_idx
                            nameIndex = reader.ReadULEB128P1();
                            name = null;
                            if (nameIndex != DexConsts.NoIndex && nameIndex >= 0)
                                name = Dex.Strings[(int)nameIndex];
                            ins.Operands.Add(name);
                            break;
                        case DebugOpCodes.StartLocalExtended:
                        case DebugOpCodes.StartLocal:
                            // StartLocalExtended : uleb128 register_num, uleb128p1 name_idx, uleb128p1 type_idx, uleb128p1 sig_idx
                            // StartLocal : uleb128 register_num, uleb128p1 name_idx, uleb128p1 type_idx
                            var isExtended = ins.OpCode == DebugOpCodes.StartLocalExtended;

                            registerIndex = reader.ReadULEB128();
                            ins.Operands.Add(mdef.Body.Registers[(int)registerIndex]);

                            nameIndex = reader.ReadULEB128P1();
                            name = null;
                            if (nameIndex != DexConsts.NoIndex && nameIndex >= 0)
                                name = Dex.Strings[(int)nameIndex];
                            ins.Operands.Add(name);

                            var typeIndex = reader.ReadULEB128P1();
                            TypeReference type = null;
                            if (typeIndex != DexConsts.NoIndex && typeIndex >= 0)
                                type = Dex.TypeReferences[(int)typeIndex];
                            ins.Operands.Add(type);

                            if (isExtended)
                            {
                                var signatureIndex = reader.ReadULEB128P1();
                                string signature = null;
                                if (signatureIndex != DexConsts.NoIndex && signatureIndex >= 0)
                                    signature = Dex.Strings[(int)signatureIndex];
                                ins.Operands.Add(signature);
                            }

                            break;
                        case DebugOpCodes.EndSequence:
                            return;
                        //case DebugOpCodes.Special:
                        // between 0x0a and 0xff (inclusive)
                        //case DebugOpCodes.SetPrologueEnd:
                        //case DebugOpCodes.SetEpilogueBegin:
                        //default:
                        //    break;
                    }
                }
            });
        }
Пример #9
0
        private void ReadAnnotationDirectory(BinaryReader reader, ClassDefinition classDefinition, uint annotationOffset)
        {
            reader.PreserveCurrentPosition(annotationOffset, () =>
            {
                uint classAnnotationOffset = reader.ReadUInt32();
                uint annotatedFieldsSize = reader.ReadUInt32();
                uint annotatedMethodsSize = reader.ReadUInt32();
                uint annotatedParametersSize = reader.ReadUInt32();

                if (classAnnotationOffset > 0)
                    classDefinition.Annotations =
                        ReadAnnotationSet(reader,
                            classAnnotationOffset);

                for (int j = 0; j < annotatedFieldsSize; j++)
                    ((FieldDefinition) fieldReferences[reader.ReadInt32()]).Annotations =
                        ReadAnnotationSet(reader, reader.ReadUInt32());

                for (int j = 0; j < annotatedMethodsSize; j++)
                    ((MethodDefinition) methodReferences[reader.ReadInt32()]).Annotations =
                        ReadAnnotationSet(reader, reader.ReadUInt32());

                for (int j = 0; j < annotatedParametersSize; j++)
                {
                    int methodIndex = reader.ReadInt32();
                    uint offset = reader.ReadUInt32();
                    var annotations = ReadAnnotationSetRefList(reader, offset);
                    var mdef = (methodReferences[methodIndex] as MethodDefinition);

                    for (int i = 0; i < annotations.Count; i++)
                    {
                        if (annotations[i].Count > 0)
                        {
                            mdef.Prototype.Parameters[i].Annotations = annotations[i];
                        }
                    }
                }
            });
        }
Пример #10
0
        private void ReadFieldReferences(BinaryReader reader)
        {
            reader.PreserveCurrentPosition(header.FieldReferencesOffset, () =>
            {
                for (int i = 0; i < header.FieldReferencesSize; i++)
                {
                    int classIndex = reader.ReadUInt16();
                    int typeIndex  = reader.ReadUInt16();
                    int nameIndex  = reader.ReadInt32();

                    var fref = new FieldReference();

                    fref.Owner = (ClassReference) typeReferences[classIndex];
                    fref.Type  = typeReferences[typeIndex];
                    fref.Name  = strings[nameIndex];

                    fieldReferences.Add(fref);
                }
            });
        }
Пример #11
0
        private void PrefetchTypeReferences(BinaryReader reader)
        {
            reader.PreserveCurrentPosition(header.TypeReferencesOffset, () =>
            {
                reader.BaseStream.Seek(header.TypeReferencesOffset, SeekOrigin.Begin);

                for (int i = 0; i < header.TypeReferencesSize; i++)
                {
                    int descriptorIndex = reader.ReadInt32();
                    string descriptor = strings[descriptorIndex];
                    typeReferences.Add(TypeDescriptor.Allocate(descriptor));
                }
            });
        }
Пример #12
0
        private void PrefetchClassDefinitions(BinaryReader reader, bool prefetchMembers)
        {
            reader.PreserveCurrentPosition(header.ClassDefinitionsOffset, () =>
            {
                for (int i = 0; i < header.ClassDefinitionsSize; i++)
                {
                    int classIndex = reader.ReadInt32();

                    ClassDefinition cdef;
                    if (typeReferences[classIndex] is ClassDefinition)
                    {
                        cdef = (ClassDefinition) typeReferences[classIndex];
                    }
                    else
                    {
                        cdef = new ClassDefinition((ClassReference) typeReferences[classIndex]);
                        typeReferences[classIndex] = cdef;
                        classes.Add(cdef);
                    }

                    reader.ReadInt32();
                    // skip access_flags
                    reader.ReadInt32();
                    // skip superclass_idx
                    reader.ReadInt32();
                    // skip interfaces_off
                    reader.ReadInt32();
                    // skip source_file_idx
                    reader.ReadInt32();
                    // skip annotations_off

                    uint classDataOffset = reader.ReadUInt32();
                    if ((classDataOffset > 0) && prefetchMembers)
                    {
                        PrefetchClassDefinition(reader, cdef, classDataOffset);
                    }

                    reader.ReadInt32();
                    // skip static_values_off
                }
            });
        }
Пример #13
0
 private void ReadTypesReferences(BinaryReader reader)
 {
     reader.PreserveCurrentPosition(header.TypeReferencesOffset, () => {
                                                                     for (int i = 0;
                                                                          i < header.TypeReferencesSize;
                                                                          i++)
                                                                     {
                                                                         int descriptorIndex =
                                                                             reader.ReadInt32();
                                                                         string descriptor =
                                                                             strings[descriptorIndex];
                                                                         TypeDescriptor.Fill(descriptor,
                                                                                             typeReferences
                                                                                                 [i]);
                                                                     }
                                                                 });
 }
Пример #14
0
        private void ReadClassDefinition(BinaryReader reader, ClassDefinition classDefinition, uint classDataOffset)
        {
            reader.PreserveCurrentPosition(classDataOffset, () =>
            {
                var staticFieldSize = reader.ReadULEB128();
                var instanceFieldSize = reader.ReadULEB128();
                var directMethodSize = reader.ReadULEB128();
                var virtualMethodSize = reader.ReadULEB128();

                ReadFieldDefinitions(reader, classDefinition, staticFieldSize);
                ReadFieldDefinitions(reader, classDefinition, instanceFieldSize);
                ReadMethodDefinitions(reader, classDefinition, directMethodSize, false);
                ReadMethodDefinitions(reader, classDefinition, virtualMethodSize, true);
            });
        }
Пример #15
0
        private void ReadPrototypes(BinaryReader reader)
        {
            reader.PreserveCurrentPosition(header.PrototypesOffset, () =>
            {
                for (int i = 0; i < header.PrototypesSize; i++)
                {
                    long thisOffset = reader.BaseStream.Position;
                    int shortyIndex = reader.ReadInt32();
                    int returnTypeIndex = reader.ReadInt32();
                    uint parametersOffset = reader.ReadUInt32();

                    var prototype = new Prototype();
                    prototype.ReturnType = typeReferences[returnTypeIndex];

                    if (parametersOffset > 0)
                    {
                        ReadParameters(reader, prototype, parametersOffset);
                    }

                    prototype.Freeze();

                    // cache the signature and hashcode.
                    // ReSharper disable once ReturnValueOfPureMethodIsNotUsed
                    prototype.GetHashCode();
                    prototype.ToSignature();

                    prototypes.Add(prototype);
                }
            });
        }
Пример #16
0
        private void ReadClassDefinitions(BinaryReader reader)
        {
            reader.PreserveCurrentPosition(Header.ClassDefinitionsOffset, () =>
            {
                for (var i = 0; i < Header.ClassDefinitionsSize; i++)
                {
                    var classIndex = reader.ReadUInt32();

                    var cdef = (ClassDefinition)Dex.TypeReferences[(int)classIndex];
                    cdef.AccessFlags = (AccessFlags)reader.ReadUInt32();

                    var superClassIndex = reader.ReadUInt32();
                    if (superClassIndex != DexConsts.NoIndex)
                        cdef.SuperClass = (ClassReference)Dex.TypeReferences[(int)superClassIndex];

                    var interfaceOffset = reader.ReadUInt32();
                    var sourceFileIndex = reader.ReadUInt32();
                    var annotationOffset = reader.ReadUInt32();
                    var classDataOffset = reader.ReadUInt32();
                    var staticValuesOffset = reader.ReadUInt32();

                    if (interfaceOffset > 0)
                        ReadInterfaces(reader, cdef, interfaceOffset);

                    if (sourceFileIndex != DexConsts.NoIndex)
                        cdef.SourceFile = Dex.Strings[(int)sourceFileIndex];

                    if (classDataOffset > 0)
                        ReadClassDefinition(reader, cdef, classDataOffset);

                    if (annotationOffset > 0)
                        ReadAnnotationDirectory(reader, cdef, annotationOffset);

                    if (staticValuesOffset > 0)
                        ReadStaticValues(reader, cdef, staticValuesOffset);
                }
            });
        }
Пример #17
0
        private void ReadTypesReferences(BinaryReader reader)
        {
            reader.PreserveCurrentPosition(header.TypeReferencesOffset, () =>
            {
                for (int i = 0; i < header.TypeReferencesSize; i++)
                {
                    int descriptorIndex = reader.ReadInt32();
                    string descriptor = strings[descriptorIndex];
                    TypeDescriptor.Fill(descriptor, typeReferences[i]);

                    // freeze the references and cache the encoded value.
                    typeReferences[i].Freeze();
                    TypeDescriptor.Encode(typeReferences[i]);
                }
            });
        }
Пример #18
0
        private void ReadFieldReferences(BinaryReader reader)
        {
            reader.PreserveCurrentPosition(Header.FieldReferencesOffset, () =>
            {
                for (var i = 0; i < Header.FieldReferencesSize; i++)
                {
                    var classIndex = reader.ReadUInt16();
                    var typeIndex = reader.ReadUInt16();
                    var nameIndex = reader.ReadInt32();

                    var fref = new FieldReference
                    {
                        Owner = (ClassReference) Dex.TypeReferences[classIndex],
                        Type = Dex.TypeReferences[typeIndex],
                        Name = Dex.Strings[nameIndex]
                    };

                    Dex.FieldReferences.Add(fref);
                }
            });
        }
Пример #19
0
        private void PrefetchClassDefinitions(BinaryReader reader, bool prefetchMembers)
        {
            reader.PreserveCurrentPosition(Header.ClassDefinitionsOffset, () =>
            {
                for (var i = 0; i < Header.ClassDefinitionsSize; i++)
                {
                    var classIndex = reader.ReadInt32();

                    var reference = Dex.TypeReferences[classIndex] as ClassDefinition;
                    if (reference == null)
                    {
                        var cdef = new ClassDefinition((ClassReference)Dex.TypeReferences[classIndex]);
                        Dex.TypeReferences[classIndex] = cdef;
                        Dex.Classes.Add(cdef);
                    }

                    reader.ReadInt32(); // skip access_flags
                    reader.ReadInt32(); // skip superclass_idx
                    reader.ReadInt32(); // skip interfaces_off
                    reader.ReadInt32(); // skip source_file_idx
                    reader.ReadInt32(); // skip annotations_off

                    var classDataOffset = reader.ReadUInt32();
                    if ((classDataOffset > 0) && prefetchMembers)
                    {
                        PrefetchClassDefinition(reader, classDataOffset);
                    }

                    reader.ReadInt32(); // skip static_values_off
                }
            });
        }
Пример #20
0
 private void ReadMapList(BinaryReader reader)
 {
     reader.PreserveCurrentPosition(Header.MapOffset, () =>
     {
         uint mapsize = reader.ReadUInt32();
         for (int i = 0; i < mapsize; i++)
         {
             var item = new MapItem {Type = (TypeCodes) reader.ReadUInt16()};
             reader.ReadUInt16(); // unused
             item.Size = reader.ReadUInt32();
             item.Offset = reader.ReadUInt32();
             Map.Add(item.Type, item);
         }
     });
 }
Пример #21
0
        private void PrefetchTypeReferences(BinaryReader reader)
        {
            reader.PreserveCurrentPosition(Header.TypeReferencesOffset, () =>
            {
                reader.BaseStream.Seek(Header.TypeReferencesOffset, SeekOrigin.Begin);

                for (var i = 0; i < Header.TypeReferencesSize; i++)
                {
                    var descriptorIndex = reader.ReadInt32();
                    var descriptor = Dex.Strings[descriptorIndex];
                    Dex.TypeReferences.Add(TypeDescriptor.Allocate(descriptor));
                }

            });
        }
Пример #22
0
        private void ReadMethodReferences(BinaryReader reader)
        {
            reader.PreserveCurrentPosition(Header.MethodReferencesOffset, () =>
            {
                for (var i = 0; i < Header.MethodReferencesSize; i++)
                {
                    int classIndex = reader.ReadUInt16();
                    int prototypeIndex = reader.ReadUInt16();
                    int nameIndex = reader.ReadInt32();

                    var mref = new MethodReference
                    {
                        Owner = (CompositeType) Dex.TypeReferences[classIndex],
                        // Clone the prototype so we can annotate & update it easily
                        Prototype = Dex.Prototypes[prototypeIndex].Clone(),
                        Name = Dex.Strings[nameIndex]
                    };

                    Dex.MethodReferences.Add(mref);
                }
            });
        }
Пример #23
0
 private Annotation ReadAnnotation(BinaryReader reader, uint annotationOffset)
 {
     Annotation annotation = null;
     reader.PreserveCurrentPosition(annotationOffset, () =>
     {
         var visibility = reader.ReadByte();
         annotation = ReadEncodedAnnotation(reader);
         annotation.Visibility = (AnnotationVisibility)visibility;
     });
     return annotation;
 }
Пример #24
0
        private void ReadPrototypes(BinaryReader reader)
        {
            reader.PreserveCurrentPosition(Header.PrototypesOffset, () =>
            {
                for (var i = 0; i < Header.PrototypesSize; i++)
                {
                    //var thisOffset = reader.BaseStream.Position;
                    /*var shortyIndex =*/ reader.ReadInt32();
                    var returnTypeIndex = reader.ReadInt32();
                    var parametersOffset = reader.ReadUInt32();

                    var prototype = new Prototype {ReturnType = Dex.TypeReferences[returnTypeIndex]};

                    if (parametersOffset > 0)
                    {
                        ReadParameters(reader, prototype, parametersOffset);
                    }

                    Dex.Prototypes.Add(prototype);
                }
            });
        }
Пример #25
0
        private void ReadAnnotationDirectory(BinaryReader reader, IAnnotationProvider provider, uint annotationOffset)
        {
            reader.PreserveCurrentPosition(annotationOffset, () =>
            {
                uint classAnnotationOffset = reader.ReadUInt32();
                uint annotatedFieldsSize = reader.ReadUInt32();
                uint annotatedMethodsSize = reader.ReadUInt32();
                uint annotatedParametersSize = reader.ReadUInt32();

                if (classAnnotationOffset > 0)
                    provider.Annotations = ReadAnnotationSet(reader, classAnnotationOffset);

                for (var j = 0; j < annotatedFieldsSize; j++)
                {
                    var fieldDefinition = Dex.FieldReferences[reader.ReadInt32()] as FieldDefinition;
                    if (fieldDefinition != null)
                        fieldDefinition.Annotations = ReadAnnotationSet(reader, reader.ReadUInt32());
                }

                for (var j = 0; j < annotatedMethodsSize; j++)
                {
                    var methodDefinition = Dex.MethodReferences[reader.ReadInt32()] as MethodDefinition;
                    if (methodDefinition != null)
                        methodDefinition.Annotations = ReadAnnotationSet(reader, reader.ReadUInt32());
                }

                for (var j = 0; j < annotatedParametersSize; j++)
                {
                    var methodIndex = reader.ReadInt32();
                    var offset = reader.ReadUInt32();
                    var annotations = ReadAnnotationSetRefList(reader, offset);
                    var mdef = (Dex.MethodReferences[methodIndex] as MethodDefinition);

                    if (mdef == null)
                        break;

                    for (var i = 0; i < annotations.Count; i++)
                    {
                        if (annotations[i].Count <= 0)
                            continue;

                        mdef.Prototype.Parameters[i].Annotations = annotations[i];
                    }
                }
            });
        }
Пример #26
0
 private void ReadStrings(BinaryReader reader)
 {
     reader.PreserveCurrentPosition(Header.StringsOffset, () =>
     {
         var stringsDataOffset = reader.ReadUInt32();
         reader.BaseStream.Seek(stringsDataOffset, SeekOrigin.Begin);
         for (var i = 0; i < Header.StringsSize; i++)
         {
             Dex.Strings.Add(reader.ReadMUTF8String());
         }
     });
 }
Пример #27
0
 private List<List<Annotation>> ReadAnnotationSetRefList(BinaryReader reader, uint annotationOffset)
 {
     var result = new List<List<Annotation>>();
     reader.PreserveCurrentPosition(annotationOffset, () =>
     {
         var size = reader.ReadUInt32();
         for (uint i = 0; i < size; i++)
         {
             var offset = reader.ReadUInt32();
             result.Add(ReadAnnotationSet(reader, offset));
         }
     });
     return result;
 }
Пример #28
0
        private void PrefetchClassDefinition(BinaryReader reader, uint classDataOffset)
        {
            reader.PreserveCurrentPosition(classDataOffset, () =>
            {
                var staticFieldSize = reader.ReadULEB128();
                var instanceFieldSize = reader.ReadULEB128();
                var directMethodSize = reader.ReadULEB128();
                var virtualMethodSize = reader.ReadULEB128();

                PrefetchFieldDefinitions(reader, staticFieldSize);
                PrefetchFieldDefinitions(reader, instanceFieldSize);
                PrefetchMethodDefinitions(reader, directMethodSize);
                PrefetchMethodDefinitions(reader, virtualMethodSize);
            });
        }
Пример #29
0
        private void ReadPrototypes(BinaryReader reader)
        {
            reader.PreserveCurrentPosition(header.PrototypesOffset, () => {
                                                                        for (int i = 0;
                                                                             i < header.PrototypesSize;
                                                                             i++)
                                                                        {
                                                                            long thisOffset =
                                                                                reader.BaseStream.Position;
                                                                            int shortyIndex = reader.ReadInt32();
                                                                            int returnTypeIndex = reader.ReadInt32();
                                                                            uint parametersOffset =
                                                                                reader.ReadUInt32();

                                                                            var prototype = new Prototype();
                                                                            prototype.ReturnType =
                                                                                typeReferences[returnTypeIndex];

                                                                            if (parametersOffset > 0)
                                                                            {
                                                                                ReadParameters(reader, prototype,
                                                                                               parametersOffset);
                                                                            }

                                                                            prototypes.Add(prototype);
                                                                        }
                                                                    });
        }