Пример #1
0
        /// <summary>
        /// Reads a single exception handler from the given input stream.
        /// </summary>
        /// <param name="cilMethodBody">The method body that contains the exception handler.</param>
        /// <param name="reader">The input stream to read from.</param>
        /// <param name="fatFormat">A value indicating whether the fat format or the small format should be used.</param>
        /// <returns>The exception handler.</returns>
        public static ExceptionHandler FromReader(CilMethodBody cilMethodBody, IBinaryStreamReader reader, bool fatFormat)
        {
            var  handlerType              = (ExceptionHandlerType)(fatFormat ? reader.ReadUInt32() : reader.ReadUInt16());
            int  tryOffset                = fatFormat ? reader.ReadInt32() : reader.ReadUInt16();
            int  tryLength                = fatFormat ? reader.ReadInt32() : reader.ReadByte();
            int  handlerOffset            = fatFormat ? reader.ReadInt32() : reader.ReadUInt16();
            int  handlerLength            = fatFormat ? reader.ReadInt32() : reader.ReadByte();
            uint classTokenOrFilterOffset = reader.ReadUInt32();

            var handler = new ExceptionHandler(handlerType)
            {
                IsFat        = fatFormat,
                TryStart     = cilMethodBody.Instructions.GetByOffset(tryOffset),
                TryEnd       = cilMethodBody.Instructions.GetByOffset(tryOffset + tryLength),
                HandlerStart = cilMethodBody.Instructions.GetByOffset(handlerOffset),
                HandlerEnd   = cilMethodBody.Instructions.GetByOffset(handlerOffset + handlerLength),
            };

            switch (handler.HandlerType)
            {
            case ExceptionHandlerType.Exception:
                handler.CatchType = (ITypeDefOrRef)((IOperandResolver)cilMethodBody).ResolveMember(
                    new MetadataToken(classTokenOrFilterOffset));
                break;

            case ExceptionHandlerType.Filter:
                handler.FilterStart = cilMethodBody.Instructions.GetByOffset((int)classTokenOrFilterOffset);
                break;
            }

            return(handler);
        }
        public static CustomAttributeSignature FromReader(CustomAttribute parent, IBinaryStreamReader reader)
        {
            long position = reader.Position;

            if (!reader.CanRead(sizeof (ushort)) || reader.ReadUInt16() != 0x0001)
                throw new ArgumentException("Signature doesn't refer to a valid custom attribute signature.");

            var signature = new CustomAttributeSignature()
            {
                StartOffset = position,
            };

            if (parent.Constructor != null)
            {
                var methodSignature = parent.Constructor.Signature as MethodSignature;
                if (methodSignature != null)
                {
                    foreach (var parameter in methodSignature.Parameters)
                    {
                        signature.FixedArguments.Add(CustomAttributeArgument.FromReader(parent.Header,
                            parameter.ParameterType, reader));
                    }
                }
            }

            var namedElementCount = reader.CanRead(sizeof (ushort)) ? reader.ReadUInt16() : 0;
            for (uint i = 0; i < namedElementCount; i++)
            {
                signature.NamedArguments.Add(CustomAttributeNamedArgument.FromReader(parent.Header, reader));
            }

            return signature;
        }
Пример #3
0
 /// <summary>
 /// Reads a single parameter definition row from an input stream.
 /// </summary>
 /// <param name="reader">The input stream.</param>
 /// <param name="layout">The layout of the parameter definition table.</param>
 /// <returns>The row.</returns>
 public static ParameterDefinitionRow FromReader(IBinaryStreamReader reader, TableLayout layout)
 {
     return(new ParameterDefinitionRow(
                (ParameterAttributes)reader.ReadUInt16(),
                reader.ReadUInt16(),
                reader.ReadIndex((IndexSize)layout.Columns[2].Size)));
 }
        /// <summary>
        /// Reads a single custom attribute signature from the input stream.
        /// </summary>
        /// <param name="parentModule">The module that contains the attribute signature.</param>
        /// <param name="ctor">The constructor that was called.</param>
        /// <param name="reader">The input stream.</param>
        /// <returns>The signature.</returns>
        /// <exception cref="FormatException">Occurs when the input stream does not point to a valid signature.</exception>
        public static CustomAttributeSignature FromReader(ModuleDefinition parentModule, ICustomAttributeType ctor, IBinaryStreamReader reader)
        {
            ushort prologue = reader.ReadUInt16();

            if (prologue != CustomAttributeSignaturePrologue)
            {
                throw new FormatException("Input stream does not point to a valid custom attribute signature.");
            }

            var result = new CustomAttributeSignature();

            // Read fixed arguments.
            var parameterTypes = ctor.Signature.ParameterTypes;

            for (int i = 0; i < parameterTypes.Count; i++)
            {
                var argument = CustomAttributeArgument.FromReader(parentModule, parameterTypes[i], reader);
                result.FixedArguments.Add(argument);
            }

            // Read named arguments.
            ushort namedArgumentCount = reader.ReadUInt16();

            for (int i = 0; i < namedArgumentCount; i++)
            {
                var argument = CustomAttributeNamedArgument.FromReader(parentModule, reader);
                result.NamedArguments.Add(argument);
            }

            return(result);
        }
        /// <summary>
        /// Reads a single resource directory from an input stream.
        /// </summary>
        /// <param name="peFile">The PE file containing the resource.</param>
        /// <param name="entry">The entry to read. If this value is <c>null</c>, the root directory is assumed.</param>
        /// <param name="directoryReader">The input stream.</param>
        /// <param name="depth">
        /// The current depth of the resource directory tree structure.
        /// If this value exceeds <see cref="MaxDepth"/>, this class will not initialize any entries.
        /// </param>
        public SerializedResourceDirectory(IPEFile peFile, ResourceDirectoryEntry?entry,
                                           IBinaryStreamReader directoryReader, int depth = 0)
        {
            _peFile = peFile ?? throw new ArgumentNullException(nameof(peFile));

            _depth = depth;

            if (entry.HasValue)
            {
                var value = entry.Value;
                if (value.IsByName)
                {
                    Name = value.Name;
                }
                else
                {
                    Id = value.IdOrNameOffset;
                }
            }

            if (directoryReader != null)
            {
                Characteristics = directoryReader.ReadUInt32();
                TimeDateStamp   = directoryReader.ReadUInt32();
                MajorVersion    = directoryReader.ReadUInt16();
                MinorVersion    = directoryReader.ReadUInt16();

                _namedEntries = directoryReader.ReadUInt16();
                _idEntries    = directoryReader.ReadUInt16();
                _entriesRva   = directoryReader.Rva;

                directoryReader.Offset =
                    (directoryReader.Offset + (ulong)((_namedEntries + _idEntries) * ResourceDirectoryEntry.EntrySize));
            }
        }
Пример #6
0
        public new static CilRawFatMethodBody FromReader(IBinaryStreamReader reader)
        {
            var body = new CilRawFatMethodBody
            {
                _header  = reader.ReadUInt16(),
                MaxStack = reader.ReadUInt16()
            };

            int codeSize = reader.ReadInt32();

            body.LocalVarSigToken = reader.ReadUInt32();

            body.Code = reader.ReadBytes(codeSize);

            if (body.HasSections)
            {
                reader.Align(4);

                CilExtraSection section;
                do
                {
                    section = CilExtraSection.FromReader(reader);
                    body.ExtraSections.Add(section);
                } while (section.HasMoreSections);
            }

            return(body);
        }
Пример #7
0
        public static ExceptionHandler FromReader(MethodBody methodBody, IBinaryStreamReader reader, bool fatFormat)
        {
            var offset                   = reader.Position;
            var handerType               = fatFormat ? reader.ReadUInt32() : reader.ReadUInt16();
            var tryOffset                = fatFormat ? reader.ReadInt32() : reader.ReadUInt16();
            var tryLength                = fatFormat ? reader.ReadInt32() : reader.ReadByte();
            var handlerOffset            = fatFormat ? reader.ReadInt32() : reader.ReadUInt16();
            var handlerLength            = fatFormat ? reader.ReadInt32() : reader.ReadByte();
            var classTokenOrFilterOffset = reader.ReadUInt32();

            var handler = new ExceptionHandler((ExceptionHandlerType)handerType)
            {
                StartOffset  = offset,
                IsFat        = fatFormat,
                MethodBody   = methodBody,
                TryStart     = methodBody.GetInstructionByOffset(tryOffset),
                TryEnd       = methodBody.GetInstructionByOffset(tryOffset + tryLength),
                HandlerStart = methodBody.GetInstructionByOffset(handlerOffset),
                HandlerEnd   = methodBody.GetInstructionByOffset(handlerOffset + handlerLength),
            };

            switch (handler.HandlerType)
            {
            case ExceptionHandlerType.Exception:
                handler.CatchType = (ITypeDefOrRef)((IOperandResolver)methodBody).ResolveMember(new MetadataToken(classTokenOrFilterOffset));
                break;

            case ExceptionHandlerType.Filter:
                handler.FilterStart = methodBody.GetInstructionByOffset((int)classTokenOrFilterOffset);
                break;
            }

            return(handler);
        }
        /// <summary>
        /// Reads a .NET directory from an input stream.
        /// </summary>
        /// <param name="peFile">The PE file containing the .NET directory.</param>
        /// <param name="reader">The input stream.</param>
        /// <param name="metadataStreamReader"></param>
        /// <exception cref="ArgumentNullException">Occurs when any of the arguments are <c>null</c>.</exception>
        public SerializedDotNetDirectory(IPEFile peFile, IBinaryStreamReader reader,
                                         IMetadataStreamReader metadataStreamReader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }
            _peFile = peFile ?? throw new ArgumentNullException(nameof(peFile));
            _metadataStreamReader = metadataStreamReader;

            Offset = reader.Offset;

            uint cb = reader.ReadUInt32();

            MajorRuntimeVersion = reader.ReadUInt16();
            MinorRuntimeVersion = reader.ReadUInt16();
            _metadataDirectory  = DataDirectory.FromReader(reader);
            Flags                  = (DotNetDirectoryFlags)reader.ReadUInt32();
            Entrypoint             = reader.ReadUInt32();
            _resourcesDirectory    = DataDirectory.FromReader(reader);
            _strongNameDirectory   = DataDirectory.FromReader(reader);
            _codeManagerDirectory  = DataDirectory.FromReader(reader);
            _vtableFixupsDirectory = DataDirectory.FromReader(reader);
            _exportsDirectory      = DataDirectory.FromReader(reader);
            _nativeHeaderDirectory = DataDirectory.FromReader(reader);
        }
Пример #9
0
        public static CustomAttributeSignature FromReader(CustomAttribute parent, IBinaryStreamReader reader)
        {
            if (!reader.CanRead(sizeof(ushort)) || reader.ReadUInt16() != 0x0001)
            {
                throw new ArgumentException("Signature doesn't refer to a valid custom attribute signature.");
            }

            var signature = new CustomAttributeSignature();

            if (parent.Constructor != null)
            {
                var methodSignature = parent.Constructor.Signature as MethodSignature;
                if (methodSignature != null)
                {
                    foreach (var parameter in methodSignature.Parameters)
                    {
                        signature.FixedArguments.Add(CustomAttributeArgument.FromReader(parent.Image, parameter.ParameterType, reader));
                    }
                }
            }

            var namedElementCount = reader.CanRead(sizeof(ushort)) ? reader.ReadUInt16() : 0;

            for (uint i = 0; i < namedElementCount; i++)
            {
                signature.NamedArguments.Add(CustomAttributeNamedArgument.FromReader(parent.Image, reader));
            }

            return(signature);
        }
Пример #10
0
 /// <summary>
 /// Reads a single generic parameter row from an input stream.
 /// </summary>
 /// <param name="reader">The input stream.</param>
 /// <param name="layout">The layout of the generic parameter table.</param>
 /// <returns>The row.</returns>
 public static GenericParameterRow FromReader(IBinaryStreamReader reader, TableLayout layout)
 {
     return(new GenericParameterRow(
                reader.ReadUInt16(),
                (GenericParameterAttributes)reader.ReadUInt16(),
                reader.ReadIndex((IndexSize)layout.Columns[2].Size),
                reader.ReadIndex((IndexSize)layout.Columns[3].Size)));
 }
Пример #11
0
        /// <summary>
        /// Reads a raw method body from the given binary input stream using the fat method body format.
        /// </summary>
        /// <param name="errorListener">The object responsible for recording parser errors.</param>
        /// <param name="reader">The binary input stream to read from.</param>
        /// <returns>The raw method body.</returns>
        /// <exception cref="FormatException">Occurs when the method header indicates an method body that is not in the
        /// fat format.</exception>
        public new static CilRawFatMethodBody FromReader(IErrorListener errorListener, IBinaryStreamReader reader)
        {
            ulong fileOffset = reader.Offset;
            uint  rva        = reader.Rva;

            // Read flags.
            ushort header     = reader.ReadUInt16();
            var    flags      = (CilMethodBodyAttributes)(header & 0xFFF);
            int    headerSize = (header >> 12) * sizeof(uint);

            // Verify this is a fat method body.
            if ((flags & CilMethodBodyAttributes.Fat) != CilMethodBodyAttributes.Fat)
            {
                errorListener.BadImage("Invalid fat CIL method body header.");
                return(null);
            }

            // Read remaining header.
            ushort maxStack         = reader.ReadUInt16();
            uint   codeSize         = reader.ReadUInt32();
            uint   localVarSigToken = reader.ReadUInt32();

            // Move to code.
            reader.Offset = fileOffset + (ulong)headerSize;

            // Verify code size.
            if (reader.Offset + codeSize > reader.StartOffset + reader.Length)
            {
                errorListener.BadImage("Invalid fat CIL method body code size.");
                return(null);
            }

            // Read code.
            var code = new byte[codeSize];

            reader.ReadBytes(code, 0, code.Length);

            // Create body.
            var body = new CilRawFatMethodBody(flags, maxStack, localVarSigToken, code);

            body.UpdateOffsets(fileOffset, rva);

            // Read any extra sections.
            if (body.HasSections)
            {
                reader.Align(4);

                CilExtraSection section;
                do
                {
                    section = CilExtraSection.FromReader(reader);
                    body.ExtraSections.Add(section);
                } while (section.HasMoreSections);
            }

            return(body);
        }
Пример #12
0
        private static System.Version ReadVersion(IBinaryStreamReader reader)
        {
            ushort minor    = reader.ReadUInt16();
            ushort major    = reader.ReadUInt16();
            ushort revision = reader.ReadUInt16();
            ushort build    = reader.ReadUInt16();

            return(new System.Version(major, minor, build, revision));
        }
        /// <summary>
        /// Reads a single exception handler from the provided input stream.
        /// </summary>
        /// <param name="body">The method body containing the exception handler.</param>
        /// <param name="reader">The input stream.</param>
        /// <param name="isFat"><c>true</c> if the fat format should be used, <c>false</c> otherwise.</param>
        /// <returns>The exception handler.</returns>
        public static CilExceptionHandler FromReader(CilMethodBody body, IBinaryStreamReader reader, bool isFat)
        {
            CilExceptionHandlerType handlerType;
            int tryStartOffset;
            int tryEndOffset;
            int handlerStartOffset;
            int handlerEndOffset;

            // Read raw structure.
            if (isFat)
            {
                handlerType        = (CilExceptionHandlerType)reader.ReadUInt32();
                tryStartOffset     = reader.ReadInt32();
                tryEndOffset       = tryStartOffset + reader.ReadInt32();
                handlerStartOffset = reader.ReadInt32();
                handlerEndOffset   = handlerStartOffset + reader.ReadInt32();
            }
            else
            {
                handlerType        = (CilExceptionHandlerType)reader.ReadUInt16();
                tryStartOffset     = reader.ReadUInt16();
                tryEndOffset       = tryStartOffset + reader.ReadByte();
                handlerStartOffset = reader.ReadUInt16();
                handlerEndOffset   = handlerStartOffset + reader.ReadByte();
            }

            int exceptionTokenOrFilterStart = reader.ReadInt32();

            // Create handler.
            var handler = new CilExceptionHandler
            {
                HandlerType = handlerType,
                TryStart    = body.Instructions.GetByOffset(tryStartOffset)?.CreateLabel() ??
                              new CilOffsetLabel(tryStartOffset),
                TryEnd       = body.Instructions.GetByOffset(tryEndOffset)?.CreateLabel() ?? new CilOffsetLabel(tryEndOffset),
                HandlerStart = body.Instructions.GetByOffset(handlerStartOffset)?.CreateLabel() ??
                               new CilOffsetLabel(handlerStartOffset),
                HandlerEnd = body.Instructions.GetByOffset(handlerEndOffset)?.CreateLabel() ??
                             new CilOffsetLabel(handlerEndOffset),
            };

            // Interpret last field.
            switch (handler.HandlerType)
            {
            case CilExceptionHandlerType.Exception when body.Owner.Module.TryLookupMember(exceptionTokenOrFilterStart, out var member):
                handler.ExceptionType = member as ITypeDefOrRef;

                break;

            case CilExceptionHandlerType.Filter:
                handler.FilterStart = body.Instructions.GetByOffset(exceptionTokenOrFilterStart)?.CreateLabel()
                                      ?? new CilOffsetLabel(exceptionTokenOrFilterStart);
                break;;
            }

            return(handler);
        }
Пример #14
0
 /// <summary>
 /// Reads a single resource table header.
 /// </summary>
 /// <param name="reader">The reader.</param>
 /// <returns>The table header.</returns>
 public static VersionTableEntryHeader FromReader(IBinaryStreamReader reader)
 {
     return(new VersionTableEntryHeader
     {
         Length = reader.ReadUInt16(),
         ValueLength = reader.ReadUInt16(),
         Type = (VersionTableValueType)reader.ReadUInt16(),
         Key = reader.ReadUnicodeString(),
     });
 }
 /// <summary>
 /// Reads a single method definition row from an input stream.
 /// </summary>
 /// <param name="reader">The input stream.</param>
 /// <param name="layout">The layout of the method definition table.</param>
 /// <param name="referenceResolver">The resolver to use for resolving the virtual address of the method body.</param>
 /// <returns>The row.</returns>
 public static MethodDefinitionRow FromReader(IBinaryStreamReader reader, TableLayout layout, ISegmentReferenceResolver referenceResolver)
 {
     return(new MethodDefinitionRow(
                referenceResolver.GetReferenceToRva(reader.ReadUInt32()),
                (MethodImplAttributes)reader.ReadUInt16(),
                (MethodAttributes)reader.ReadUInt16(),
                reader.ReadIndex((IndexSize)layout.Columns[3].Size),
                reader.ReadIndex((IndexSize)layout.Columns[4].Size),
                reader.ReadIndex((IndexSize)layout.Columns[5].Size)));
 }
Пример #16
0
 /// <summary>
 /// Reads a single method definition row from an input stream.
 /// </summary>
 /// <param name="context">The reader context.</param>
 /// <param name="reader">The input stream.</param>
 /// <param name="layout">The layout of the method definition table.</param>
 /// <returns>The row.</returns>
 public static MethodDefinitionRow FromReader(PEReaderContext context, IBinaryStreamReader reader, TableLayout layout)
 {
     return(new MethodDefinitionRow(
                context.File.GetReferenceToRva(reader.ReadUInt32()),
                (MethodImplAttributes)reader.ReadUInt16(),
                (MethodAttributes)reader.ReadUInt16(),
                reader.ReadIndex((IndexSize)layout.Columns[3].Size),
                reader.ReadIndex((IndexSize)layout.Columns[4].Size),
                reader.ReadIndex((IndexSize)layout.Columns[5].Size)));
 }
Пример #17
0
 /// <summary>
 /// Reads a single assembly definition row from an input stream.
 /// </summary>
 /// <param name="reader">The input stream.</param>
 /// <param name="layout">The layout of the assembly definition table.</param>
 /// <returns>The row.</returns>
 public static AssemblyReferenceRow FromReader(IBinaryStreamReader reader, TableLayout layout)
 {
     return(new AssemblyReferenceRow(
                reader.ReadUInt16(),
                reader.ReadUInt16(),
                reader.ReadUInt16(),
                reader.ReadUInt16(),
                (AssemblyAttributes)reader.ReadUInt32(),
                reader.ReadIndex((IndexSize)layout.Columns[5].Size),
                reader.ReadIndex((IndexSize)layout.Columns[6].Size),
                reader.ReadIndex((IndexSize)layout.Columns[7].Size),
                reader.ReadIndex((IndexSize)layout.Columns[8].Size)));
 }
Пример #18
0
 /// <summary>
 /// Reads a single assembly definition row from an input stream.
 /// </summary>
 /// <param name="reader">The input stream.</param>
 /// <param name="layout">The layout of the assembly definition table.</param>
 /// <returns>The row.</returns>
 public static AssemblyDefinitionRow FromReader(IBinaryStreamReader reader, TableLayout layout)
 {
     return(new AssemblyDefinitionRow(
                (AssemblyHashAlgorithm)reader.ReadUInt32(),
                reader.ReadUInt16(),
                reader.ReadUInt16(),
                reader.ReadUInt16(),
                reader.ReadUInt16(),
                (AssemblyAttributes)reader.ReadUInt32(),
                reader.ReadIndex((IndexSize)layout.Columns[6].Size),
                reader.ReadIndex((IndexSize)layout.Columns[7].Size),
                reader.ReadIndex((IndexSize)layout.Columns[8].Size)));
 }
Пример #19
0
 public static FileHeader FromReader(IBinaryStreamReader reader)
 {
     return(new FileHeader
     {
         FileOffset = reader.FileOffset,
         Machine = (MachineType)reader.ReadUInt16(),
         NumberOfSections = reader.ReadUInt16(),
         TimeDateStamp = reader.ReadUInt32(),
         PointerToSymbolTable = reader.ReadUInt32(),
         NumberOfSymbols = reader.ReadUInt32(),
         SizeOfOptionalHeader = reader.ReadUInt16(),
         Characteristics = (Characteristics)reader.ReadUInt16()
     });
 }
Пример #20
0
        /// <summary>
        /// Reads a metadata directory from an input stream.
        /// </summary>
        /// <param name="context">The reader context.</param>
        /// <param name="directoryReader">The input stream containing the metadata directory.</param>
        /// <exception cref="ArgumentNullException">Occurs when any of the arguments are <c>null</c>.</exception>
        /// <exception cref="NotSupportedException">Occurs when an unsupported metadata directory format was encountered.</exception>
        /// <exception cref="BadImageFormatException">Occurs when the metadata directory header is invalid.</exception>
        public SerializedMetadata(PEReaderContext context, IBinaryStreamReader directoryReader)
        {
            if (directoryReader == null)
            {
                throw new ArgumentNullException(nameof(directoryReader));
            }
            _context = context ?? throw new ArgumentNullException(nameof(context));

            _streamContentsReader = directoryReader.Fork();

            var signature = (MetadataSignature)directoryReader.ReadUInt32();

            switch (signature)
            {
            case MetadataSignature.Bsjb:
                // BSJB header is the default header.
                break;

            case MetadataSignature.Moc:
                _context.NotSupported("Old +MOC metadata header format is not supported.");
                return;

            default:
                _context.BadImage($"Invalid metadata header ({(uint) signature:X8}).");
                return;
            }

            MajorVersion = directoryReader.ReadUInt16();
            MinorVersion = directoryReader.ReadUInt16();
            Reserved     = directoryReader.ReadUInt32();

            int versionLength = directoryReader.ReadInt32();

            if (!directoryReader.CanRead(versionLength))
            {
                _context.BadImage($"Invalid version length in metadata header ({versionLength.ToString()} characters).");
                return;
            }

            var versionBytes = new byte[versionLength];

            directoryReader.ReadBytes(versionBytes, 0, versionBytes.Length);
            VersionString = Encoding.ASCII.GetString(versionBytes);

            Flags                = directoryReader.ReadUInt16();
            _numberOfStreams     = directoryReader.ReadInt16();
            _streamEntriesReader = directoryReader.Fork();
        }
Пример #21
0
        /// <summary>
        /// Reads a single extra section from the provided input stream.
        /// </summary>
        /// <param name="reader">The input stream to read from.</param>
        /// <returns>The extra section that was read.</returns>
        public static CilExtraSection FromReader(IBinaryStreamReader reader)
        {
            var section = new CilExtraSection
            {
                Attributes = (CilExtraSectionAttributes)reader.ReadByte()
            };

            int dataSize;

            if (section.IsFat)
            {
                dataSize = reader.ReadByte() |
                           (reader.ReadByte() << 0x08) |
                           (reader.ReadByte() << 0x10);
            }
            else
            {
                dataSize = reader.ReadByte();
                reader.ReadUInt16();
            }

            section.Data = new byte[dataSize];
            reader.ReadBytes(section.Data, 0, dataSize);

            return(section);
        }
Пример #22
0
 /// <summary>
 /// Reads a single class layout row from an input stream.
 /// </summary>
 /// <param name="reader">The input stream.</param>
 /// <param name="layout">The layout of the class layout table.</param>
 /// <returns>The row.</returns>
 public static ClassLayoutRow FromReader(IBinaryStreamReader reader, TableLayout layout)
 {
     return(new ClassLayoutRow(
                reader.ReadUInt16(),
                reader.ReadUInt32(),
                reader.ReadIndex((IndexSize)layout.Columns[2].Size)));
 }
Пример #23
0
        /// <summary>
        /// Reads a DOS header structure at the current position of the provided input stream.
        /// </summary>
        /// <param name="reader">The input stream to read from.</param>
        /// <returns>The read DOS header.</returns>
        /// <exception cref="BadImageFormatException">Occurs when the input stream does not point to a valid DOS header.</exception>
        public static DosHeader FromReader(IBinaryStreamReader reader)
        {
            ulong offset = reader.Offset;
            uint  rva    = reader.Rva;

            var stub = new byte[DefaultNewHeaderOffset];

            ushort magic = reader.ReadUInt16();

            if (magic != ValidPEMagic)
            {
                throw new BadImageFormatException();
            }

            reader.Offset += NextHeaderFieldOffset - 2;
            uint nextHeaderOffset = reader.ReadUInt32();

            if (nextHeaderOffset != DefaultNewHeaderOffset)
            {
                Array.Resize(ref stub, (int)nextHeaderOffset);
            }

            reader.Offset -= NextHeaderFieldOffset + 4;
            reader.ReadBytes(stub, 0, stub.Length);

            return(new DosHeader(stub)
            {
                Offset = offset,
                Rva = rva,
                NextHeaderOffset = nextHeaderOffset
            });
        }
Пример #24
0
 /// <summary>
 /// Reads a single security declaration row from an input stream.
 /// </summary>
 /// <param name="reader">The input stream.</param>
 /// <param name="layout">The layout of the security declaration table.</param>
 /// <returns>The row.</returns>
 public static SecurityDeclarationRow FromReader(IBinaryStreamReader reader, TableLayout layout)
 {
     return(new SecurityDeclarationRow(
                (SecurityAction)reader.ReadUInt16(),
                reader.ReadIndex((IndexSize)layout.Columns[1].Size),
                reader.ReadIndex((IndexSize)layout.Columns[2].Size)));
 }
Пример #25
0
 /// <summary>
 /// Reads a single method semantics row from an input stream.
 /// </summary>
 /// <param name="reader">The input stream.</param>
 /// <param name="layout">The layout of the method semantics table.</param>
 /// <returns>The row.</returns>
 public static MethodSemanticsRow FromReader(IBinaryStreamReader reader, TableLayout layout)
 {
     return(new MethodSemanticsRow(
                (MethodSemanticsAttributes)reader.ReadUInt16(),
                reader.ReadIndex((IndexSize)layout.Columns[1].Size),
                reader.ReadIndex((IndexSize)layout.Columns[2].Size)));
 }
Пример #26
0
        public static CilExtraSection FromReader(IBinaryStreamReader reader)
        {
            var section = new CilExtraSection
            {
                Attributes = (CilExtraSectionAttributes)reader.ReadByte()
            };

            if (!section.IsExceptionHandler)
            {
                throw new NotSupportedException("Invalid or unsupported extra section.");
            }

            int dataSize;

            if (section.IsFat)
            {
                dataSize = reader.ReadByte() |
                           (reader.ReadByte() << 0x08) |
                           (reader.ReadByte() << 0x10);
            }
            else
            {
                dataSize = reader.ReadByte();
                reader.ReadUInt16();
            }
            section.Data = reader.ReadBytes(dataSize);

            return(section);
        }
        private void ReadRelocationEntry(IBinaryStreamReader reader, uint pageRva)
        {
            ushort rawValue = reader.ReadUInt16();
            var    type     = (RelocationType)(rawValue >> 12);
            int    offset   = rawValue & 0xFFF;

            Items.Add(new BaseRelocation(type, _peFile.GetReferenceToRva((uint)(pageRva + offset))));
        }
 /// <summary>
 /// Reads a single implementation map row from an input stream.
 /// </summary>
 /// <param name="reader">The input stream.</param>
 /// <param name="layout">The layout of the implementation map table.</param>
 /// <returns>The row.</returns>
 public static ImplementationMapRow FromReader(IBinaryStreamReader reader, TableLayout layout)
 {
     return(new ImplementationMapRow(
                (ImplementationMapAttributes)reader.ReadUInt16(),
                reader.ReadIndex((IndexSize)layout.Columns[1].Size),
                reader.ReadIndex((IndexSize)layout.Columns[2].Size),
                reader.ReadIndex((IndexSize)layout.Columns[3].Size)));
 }
Пример #29
0
        /// <summary>
        /// Reads a metadata directory from an input stream.
        /// </summary>
        /// <param name="reader">The input stream.</param>
        /// <param name="metadataStreamReader"></param>
        /// <exception cref="ArgumentNullException">Occurs when any of the arguments are <c>null</c>.</exception>
        /// <exception cref="NotSupportedException">Occurs when an unsupported metadata directory format was encountered.</exception>
        /// <exception cref="BadImageFormatException">Occurs when the metadata directory header is invalid.</exception>
        public SerializedMetadata(IBinaryStreamReader reader, IMetadataStreamReader metadataStreamReader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }
            _metadataStreamReader = metadataStreamReader;

            _streamContentsReader = reader.Fork();

            var signature = (MetadataSignature)reader.ReadUInt32();

            switch (signature)
            {
            case MetadataSignature.Bsjb:
                // BSJB header is the default header.
                break;

            case MetadataSignature.Moc:
                throw new NotSupportedException("Old +MOC metadata header format is not supported.");

            default:
                throw new BadImageFormatException($"Invalid metadata header ({(uint) signature:X8}).");
            }

            MajorVersion = reader.ReadUInt16();
            MinorVersion = reader.ReadUInt16();
            Reserved     = reader.ReadUInt32();

            int versionLength = reader.ReadInt32();

            if (!reader.CanRead(versionLength))
            {
                throw new BadImageFormatException($"Invalid version length in metadata header ({versionLength} characters).");
            }

            var versionBytes = new byte[versionLength];

            reader.ReadBytes(versionBytes, 0, versionBytes.Length);
            VersionString = Encoding.ASCII.GetString(versionBytes);

            Flags                = reader.ReadUInt16();
            _numberOfStreams     = reader.ReadInt16();
            _streamEntriesReader = reader.Fork();
        }
Пример #30
0
        /// <summary>
        /// Reads an icon group resource entry from an input stream.
        /// </summary>
        /// <param name="reader">The input stream.</param>
        /// <returns>The parsed group icon resource entry.</returns>
        public static IconGroupDirectoryEntry FromReader(IBinaryStreamReader reader)
        {
            var entry = new IconGroupDirectoryEntry
            {
                Offset        = reader.Offset,
                Rva           = reader.Rva,
                Width         = reader.ReadByte(),
                Height        = reader.ReadByte(),
                ColorCount    = reader.ReadByte(),
                Reserved      = reader.ReadByte(),
                ColorPlanes   = reader.ReadUInt16(),
                PixelBitCount = reader.ReadUInt16(),
                BytesInRes    = reader.ReadUInt32(),
                Id            = reader.ReadUInt16()
            };

            return(entry);
        }
Пример #31
0
 /// <summary>
 /// Reads a single module definition row from an input stream.
 /// </summary>
 /// <param name="reader">The input stream.</param>
 /// <param name="layout">The layout of the module definition table.</param>
 /// <returns>The row.</returns>
 public static ModuleDefinitionRow FromReader(IBinaryStreamReader reader, TableLayout layout)
 {
     return(new ModuleDefinitionRow(
                reader.ReadUInt16(),
                reader.ReadIndex((IndexSize)layout.Columns[1].Size),
                reader.ReadIndex((IndexSize)layout.Columns[2].Size),
                reader.ReadIndex((IndexSize)layout.Columns[3].Size),
                reader.ReadIndex((IndexSize)layout.Columns[4].Size)));
 }
Пример #32
0
        private static object ReadRawOperand(IBinaryStreamReader reader, MsilOperandType msilOperandType)
        {
            switch (msilOperandType)
            {
                case MsilOperandType.InlineNone:
                    return null;

                case MsilOperandType.InlineArgument:
                case MsilOperandType.InlineVar:
                    return reader.ReadUInt16();

                case MsilOperandType.InlineI:
                case MsilOperandType.InlineBrTarget:
                    return reader.ReadInt32();

                case MsilOperandType.ShortInlineArgument:
                case MsilOperandType.ShortInlineVar:
                    return reader.ReadByte();

                case MsilOperandType.ShortInlineBrTarget:
                case MsilOperandType.ShortInlineI:
                    return reader.ReadSByte();

                case MsilOperandType.ShortInlineR:
                    return reader.ReadSingle();
                case MsilOperandType.InlineR:
                    return reader.ReadDouble();
                case MsilOperandType.InlineI8:
                    return reader.ReadInt64();

                case MsilOperandType.InlineField :
                case MsilOperandType.InlineMethod :
                case MsilOperandType.InlineSig:
                case MsilOperandType.InlineTok:
                case MsilOperandType.InlineType:
                case MsilOperandType.InlineString:
                    return new MetadataToken(reader.ReadUInt32());

                case MsilOperandType.InlineSwitch:
                    var offsets = new int[reader.ReadUInt32()];
                    for (int i = 0; i < offsets.Length; i++)
                        offsets[i] = reader.ReadInt32();
                    return offsets;
            }
            throw new NotSupportedException();
        }
Пример #33
0
        private static object ReadValue(MetadataHeader header, TypeSignature typeSignature, IBinaryStreamReader reader)
        {
            switch (typeSignature.ElementType)
            {
                case ElementType.Boolean:
                    return reader.ReadByte() == 1;
                case ElementType.Char:
                    return (char)reader.ReadUInt16();
                case ElementType.R4:
                    return reader.ReadSingle();
                case ElementType.R8:
                    return reader.ReadDouble();
                case ElementType.I1:
                    return reader.ReadSByte();
                case ElementType.I2:
                    return reader.ReadInt16();
                case ElementType.I4:
                    return reader.ReadInt32();
                case ElementType.I8:
                    return reader.ReadInt64();
                case ElementType.U1:
                    return reader.ReadByte();
                case ElementType.U2:
                    return reader.ReadUInt16();
                case ElementType.U4:
                    return reader.ReadUInt32();
                case ElementType.U8:
                    return reader.ReadUInt64();
                case ElementType.String:
                    return reader.ReadSerString();
                case ElementType.Object:
                    return ReadValue(header, TypeSignature.ReadFieldOrPropType(header, reader), reader);
                case ElementType.Class:
                case ElementType.Enum:
                case ElementType.ValueType:
                    var enumTypeDef = header.MetadataResolver.ResolveType(typeSignature);
                    if (enumTypeDef == null)
                        throw new MemberResolutionException(typeSignature);

                    if (enumTypeDef.IsEnum)
                        return ReadValue(header, enumTypeDef.GetEnumUnderlyingType(), reader);
                    break;
            }
            if (typeSignature.IsTypeOf("System", "Type"))
                return TypeSignature.FromAssemblyQualifiedName(header, reader.ReadSerString());
            throw new NotSupportedException("Unsupported element type " + typeSignature.ElementType);
        }
Пример #34
0
        public static ExceptionHandler FromReader(MethodBody methodBody, IBinaryStreamReader reader, bool fatFormat)
        {
            var offset = reader.Position;
            var handerType = fatFormat ? reader.ReadUInt32() : reader.ReadUInt16();
            var tryOffset = fatFormat ? reader.ReadInt32() : reader.ReadUInt16();
            var tryLength = fatFormat ? reader.ReadInt32() : reader.ReadByte();
            var handlerOffset = fatFormat ? reader.ReadInt32() : reader.ReadUInt16();
            var handlerLength = fatFormat ? reader.ReadInt32() : reader.ReadByte();
            var classTokenOrFilterOffset = reader.ReadUInt32();

            var handler = new ExceptionHandler((ExceptionHandlerType)handerType)
            {
                StartOffset = offset,
                IsFat = fatFormat,
                TryStart = methodBody.GetInstructionByOffset(tryOffset),
                TryEnd = methodBody.GetInstructionByOffset(tryOffset + tryLength),
                HandlerStart = methodBody.GetInstructionByOffset(handlerOffset),
                HandlerEnd = methodBody.GetInstructionByOffset(handlerOffset + handlerLength),
            };

            switch (handler.HandlerType)
            {
                case ExceptionHandlerType.Exception:
                    handler.CatchType = (ITypeDefOrRef)((IOperandResolver)methodBody).ResolveMember(new MetadataToken(classTokenOrFilterOffset));
                    break;
                case ExceptionHandlerType.Filter:
                    handler.FilterStart = methodBody.GetInstructionByOffset((int)classTokenOrFilterOffset);
                    break;
            }

            return handler;
        }