public static CustomAttributeArgument FromReader(MetadataHeader header, TypeSignature typeSignature, IBinaryStreamReader reader)
        {
            var signature = new CustomAttributeArgument()
            {
                StartOffset = reader.Position,
                ArgumentType = typeSignature
            };

            if (typeSignature.ElementType != ElementType.SzArray)
            {
                signature.Elements.Add(ElementSignature.FromReader(header, typeSignature, reader));
            }
            else
            {
                var arrayType = ((SzArrayTypeSignature)typeSignature).BaseType;

                var elementCount = reader.CanRead(sizeof (uint)) ? reader.ReadUInt32() : uint.MaxValue;
                if (elementCount != uint.MaxValue)
                {
                    for (uint i = 0; i < elementCount; i++)
                    {
                        signature.Elements.Add(ElementSignature.FromReader(header, arrayType, reader));
                    }
                }
            }

            return signature;
        }
Esempio n. 2
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();
        }
        /// <summary>
        /// Reads a single fixed version info structure from an input stream.
        /// </summary>
        /// <param name="reader">The input stream.</param>
        /// <returns>The read structure.</returns>
        public static FixedVersionInfo FromReader(IBinaryStreamReader reader)
        {
            var result = new FixedVersionInfo();

            result.UpdateOffsets(reader.FileOffset, reader.Rva);

            uint signature = reader.ReadUInt32();

            if (signature != Signature)
            {
                throw new FormatException($"Input stream does not point to a valid FixedVersionInfo structure.");
            }

            uint structVersion = reader.ReadUInt32();

            result.FileVersion    = ReadVersion(reader);
            result.ProductVersion = ReadVersion(reader);
            result.FileFlagsMask  = (FileFlags)reader.ReadUInt32();
            result.FileFlags      = (FileFlags)reader.ReadUInt32();
            result.FileOS         = (FileOS)reader.ReadUInt32();
            result.FileType       = (FileType)reader.ReadUInt32();
            result.FileSubType    = (FileSubType)reader.ReadUInt32();
            result.FileDate       = reader.ReadUInt64();

            return(result);
        }
Esempio n. 4
0
        /// <summary>
        /// Reads a module import entry from an input stream.
        /// </summary>
        /// <param name="peFile">The PE file containing the module import.</param>
        /// <param name="reader">The input stream.</param>
        public SerializedImportedModule(IPEFile peFile, IBinaryStreamReader reader)
        {
            _peFile        = peFile;
            _lookupRva     = reader.ReadUInt32();
            TimeDateStamp  = reader.ReadUInt32();
            ForwarderChain = reader.ReadUInt32();
            uint nameRva = reader.ReadUInt32();

            if (nameRva != 0)
            {
                if (_peFile.TryCreateReaderAtRva(nameRva, out var nameReader))
                {
                    Name = nameReader.ReadAsciiString();
                }
            }

            _addressRva = reader.ReadUInt32();
        }
        /// <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);
        }
Esempio n. 6
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)));
 }
 /// <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)));
 }
Esempio n. 8
0
        private X86Operand ReadOperand(X86OperandType method, X86OperandSize size, byte opcode, byte registerToken)
        {
            switch (method)
            {
            case X86OperandType.OpCodeRegister:
                return(new X86Operand(GetRegisterFromToken((byte)(opcode & 7), GetRegisterSize(size))));

            case X86OperandType.Register:
                return(new X86Operand(GetRegisterFromToken((byte)((registerToken >> 3) & 7),
                                                           GetRegisterSize(size))));

            case X86OperandType.RegisterOrMemoryAddress:
                return(GetRegOrMemOperand32(registerToken, size));

            case X86OperandType.ImmediateData:
                return(new X86Operand(ReadImmediateData(size)));

            case X86OperandType.MemoryAddress:
                return(new X86Operand(GetOperandType(size), _reader.ReadUInt32()));

            case X86OperandType.RegisterAl:
                return(new X86Operand(X86Register.Al));

            case X86OperandType.RegisterCl:
                return(new X86Operand(X86Register.Cl));

            case X86OperandType.RegisterDx:
                return(new X86Operand(X86Register.Dx));

            case X86OperandType.RegisterEax:
                return(new X86Operand(X86Register.Eax));

            case X86OperandType.ImmediateOne:
                return(new X86Operand(1));

            case X86OperandType.RelativeOffset:
                return(new X86Operand((ulong)(Convert.ToInt64(ReadSignedImmediateData(size)) + BaseAddress + _reader.Position)));

            case X86OperandType.None:
                return(null);
            }
            throw new NotSupportedException("Unrecognized or unsupported addressing method.");
        }
Esempio n. 9
0
 /// <summary>
 /// Reads a single type definition row from an input stream.
 /// </summary>
 /// <param name="reader">The input stream.</param>
 /// <param name="layout">The layout of the type definition table.</param>
 /// <returns>The row.</returns>
 public static TypeDefinitionRow FromReader(IBinaryStreamReader reader, TableLayout layout)
 {
     return(new TypeDefinitionRow(
                (TypeAttributes)reader.ReadUInt32(),
                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),
                reader.ReadIndex((IndexSize)layout.Columns[5].Size)));
 }
Esempio n. 10
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)));
 }
Esempio n. 11
0
        /// <summary>
        /// Creates a new CodeViewDataSegment depending on CodeView Signature
        /// </summary>
        /// <param name="context">Context for the reader</param>
        /// <param name="reader">The input stream to read from.</param>
        /// <returns></returns>
        public static CodeViewDataSegment FromReader(PEReaderContext context, IBinaryStreamReader reader)
        {
            var signature = (CodeViewSignature)reader.ReadUInt32();

            return(signature switch
            {
                CodeViewSignature.Rsds => RsdsDataSegment.FromReader(context, reader),
                CodeViewSignature.Nb05 => context.NotSupportedAndReturn <CodeViewDataSegment>(),
                CodeViewSignature.Nb09 => context.NotSupportedAndReturn <CodeViewDataSegment>(),
                CodeViewSignature.Nb10 => context.NotSupportedAndReturn <CodeViewDataSegment>(),
                CodeViewSignature.Nb11 => context.NotSupportedAndReturn <CodeViewDataSegment>(),
                _ => context.BadImageAndReturn <CodeViewDataSegment>("Invalid code view debug data signature.")
            });
        private uint[] ReadRowCounts(IBinaryStreamReader reader)
        {
            const TableIndex maxTableIndex = TableIndex.GenericParamConstraint;

            var result = new uint[(int)maxTableIndex + 1];

            for (TableIndex i = 0; i <= maxTableIndex; i++)
            {
                result[(int)i] = HasTable(_validMask, i) ? reader.ReadUInt32() : 0;
            }

            return(result);
        }
        /// <summary>
        /// Reads a new resource directory entry from the reader.
        /// </summary>
        /// <param name="peFile">The containing PE file.</param>
        /// <param name="reader">The input stream to read from.</param>
        public ResourceDirectoryEntry(PEFile peFile, IBinaryStreamReader reader)
        {
            _idOrNameOffset     = reader.ReadUInt32();
            _dataOrSubDirOffset = reader.ReadUInt32();
            Name = null;

            if (IsByName)
            {
                uint baseRva = peFile.OptionalHeader
                               .DataDirectories[OptionalHeader.ResourceDirectoryIndex]
                               .VirtualAddress;

                if (peFile.TryCreateReaderAtRva(baseRva + IdOrNameOffset, out var nameReader))
                {
                    int length = nameReader.ReadUInt16() * 2;
                    var data   = new byte[length];
                    length = nameReader.ReadBytes(data, 0, length);

                    Name = Encoding.Unicode.GetString(data, 0, length);
                }
            }
        }
Esempio n. 14
0
        /// <summary>
        /// Reads an index with the specified index size of the stream.
        /// </summary>
        /// <param name="reader">The reader to use for reading the data.</param>
        /// <param name="size">The size of the index.</param>
        /// <returns>The index.</returns>
        public static uint ReadIndex(this IBinaryStreamReader reader, IndexSize size)
        {
            switch (size)
            {
            case IndexSize.Short:
                return(reader.ReadUInt16());

            case IndexSize.Long:
                return(reader.ReadUInt32());

            default:
                throw new ArgumentOutOfRangeException("size");
            }
        }
Esempio n. 15
0
        /// <summary>
        /// Reads a private key from an input stream.
        /// </summary>
        /// <param name="reader">The input stream.</param>
        /// <returns>The private key.</returns>
        /// <exception cref="FormatException">Occurs when the input stream is not in the correct format.</exception>
        /// <exception cref="NotSupportedException">Occurs when an invalid or unsupported algorithm is specified.</exception>
        public static StrongNamePublicKey FromReader(IBinaryStreamReader reader)
        {
            // Read BLOBHEADER
            ReadBlobHeader(reader, StrongNameKeyStructureType.PublicKeyBlob, 2, SignatureAlgorithm.RsaSign);

            // Read RSAPUBKEY
            if ((RsaPublicKeyMagic)reader.ReadUInt32() != RsaPublicKeyMagic.Rsa1)
            {
                throw new FormatException("Input stream does not contain a valid RSA public key header magic.");
            }

            uint bitLength = reader.ReadUInt32();

            var result = new StrongNamePublicKey
            {
                PublicExponent = reader.ReadUInt32(),
                Modulus        = new byte[bitLength / 8]
            };

            reader.ReadBytes(result.Modulus, 0, result.Modulus.Length);

            return(result);
        }
        /// <summary>
        /// Reads a single export directory from an input stream.
        /// </summary>
        /// <param name="peFile">The PE file containing the export directory.</param>
        /// <param name="reader">The input stream.</param>
        public SerializedExportDirectory(IPEFile peFile, IBinaryStreamReader reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }
            _peFile = peFile ?? throw new ArgumentNullException(nameof(peFile));

            ExportFlags        = reader.ReadUInt32();
            TimeDateStamp      = reader.ReadUInt32();
            MajorVersion       = reader.ReadUInt16();
            MinorVersion       = reader.ReadUInt16();
            _nameRva           = reader.ReadUInt32();
            BaseOrdinal        = reader.ReadUInt32();
            _numberOfFunctions = reader.ReadUInt32();
            _numberOfNames     = reader.ReadUInt32();
            _addressTableRva   = reader.ReadUInt32();
            _namePointerRva    = reader.ReadUInt32();
            _ordinalTableRva   = reader.ReadUInt32();
        }
Esempio n. 17
0
        /// <summary>
        /// Reads a .NET directory from an input stream.
        /// </summary>
        /// <param name="context">The reader context.</param>
        /// <param name="reader">The input stream.</param>
        /// <exception cref="ArgumentNullException">Occurs when any of the arguments are <c>null</c>.</exception>
        public SerializedDotNetDirectory(PEReaderContext context, IBinaryStreamReader reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }
            _context = context ?? throw new ArgumentNullException(nameof(context));

            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);
        }
Esempio n. 18
0
        /// <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(PEFile peFile, IBinaryStreamReader reader,
                                         IMetadataStreamReader metadataStreamReader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }
            _peFile = peFile ?? throw new ArgumentNullException(nameof(peFile));
            _metadataStreamReader = metadataStreamReader;

            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);
        }
Esempio n. 19
0
        /// <summary>
        /// Initializes a new instance of <see cref="RsdsDataSegment"/>
        /// </summary>
        /// <param name="context">Context for the reader</param>
        /// <param name="reader">The input stream to read from.</param>
        /// <returns></returns>
        public new static RsdsDataSegment FromReader(PEReaderContext context, IBinaryStreamReader reader)
        {
            if (reader.Length < RsdsExpectedDataSize)
            {
                context.BadImage("RSDS Data was shorter than the minimal expected length");
                return(null);
            }
            var result = new RsdsDataSegment();

            byte[] buffer = new byte[16];
            reader.ReadBytes(buffer, 0, 16);
            result.Guid = new Guid(buffer);
            result.Age  = reader.ReadUInt32();
            result.Path = Encoding.UTF8.GetString(reader.ReadBytesUntil(0x00));

            return(result);
        }
Esempio n. 20
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);
        }
        private IDictionary <uint, string> ReadOrdinalNameTable(
            IBinaryStreamReader namePointerReader, IBinaryStreamReader ordinalReader)
        {
            var result = new Dictionary <uint, string>();

            for (int i = 0; i < _numberOfNames; i++)
            {
                uint ordinal = ordinalReader.ReadUInt16();
                uint nameRva = namePointerReader.ReadUInt32();

                if (_peFile.TryCreateReaderAtRva(nameRva, out var nameReader))
                {
                    result[ordinal] = nameReader.ReadAsciiString();
                }
            }

            return(result);
        }
Esempio n. 22
0
        /// <summary>
        /// Reads a PE file from the provided input stream.
        /// </summary>
        /// <param name="reader">The input stream to read from.</param>
        /// <returns>The PE file that was read.</returns>
        /// <exception cref="BadImageFormatException">Occurs when the file does not follow the PE file format.</exception>
        public static PEFile FromReader(IBinaryStreamReader reader)
        {
            // DOS header.
            var dosHeader = DosHeader.FromReader(reader);

            reader.FileOffset = dosHeader.NextHeaderOffset;

            uint signature = reader.ReadUInt32();

            if (signature != ValidPESignature)
            {
                throw new BadImageFormatException();
            }

            // Read NT headers.
            var peFile = new PEFile(
                dosHeader,
                FileHeader.FromReader(reader),
                OptionalHeader.FromReader(reader));

            // Section headers.
            reader.FileOffset = peFile.OptionalHeader.FileOffset + peFile.FileHeader.SizeOfOptionalHeader;
            for (int i = 0; i < peFile.FileHeader.NumberOfSections; i++)
            {
                var header = SectionHeader.FromReader(reader);

                var contentsReader = reader.Fork(header.PointerToRawData, header.SizeOfRawData);
                var contents       = DataSegment.FromReader(contentsReader);
                contents.UpdateOffsets(header.PointerToRawData, header.VirtualAddress);

                peFile.Sections.Add(new PESection(header, new VirtualSegment(contents, header.VirtualSize)));
            }

            // Data between section headers and sections.
            int extraSectionDataLength = (int)(peFile.OptionalHeader.SizeOfHeaders - reader.FileOffset);

            if (extraSectionDataLength != 0)
            {
                peFile.ExtraSectionData = DataSegment.FromReader(reader, extraSectionDataLength);
            }

            return(peFile);
        }
Esempio n. 23
0
 /// <summary>
 /// Reads and verifies the blob header at the provided input stream.
 /// </summary>
 /// <param name="reader">The input stream.</param>
 /// <param name="expectedType">The expected structure type to read.</param>
 /// <param name="expectedVersion">The expected structure version to read.</param>
 /// <param name="expectedAlgorithm">The expected algorithm.</param>
 /// <exception cref="FormatException">Occurs when the input stream is not in the correct format.</exception>
 /// <exception cref="NotSupportedException">Occurs when an invalid or unsupported algorithm is specified.</exception>
 protected static void ReadBlobHeader(IBinaryStreamReader reader,
                                      StrongNameKeyStructureType expectedType,
                                      byte expectedVersion,
                                      SignatureAlgorithm expectedAlgorithm)
 {
     // Read RSAPUBKEY
     if ((StrongNameKeyStructureType)reader.ReadByte() != expectedType)
     {
         throw new FormatException("Input stream does not contain the expected structure type.");
     }
     if (reader.ReadByte() != expectedVersion)
     {
         throw new NotSupportedException("Invalid or unsupported public/private key pair structure version number.");
     }
     reader.ReadUInt16();
     if ((SignatureAlgorithm)reader.ReadUInt32() != expectedAlgorithm)
     {
         throw new NotSupportedException("Invalid or unsupported public key algorithm.");
     }
 }
        private static CustomAttributeArgument ReadSzArrayArgument(ModuleDefinition parentModule,
                                                                   TypeSignature argumentType, IBinaryStreamReader reader)
        {
            var result = new CustomAttributeArgument(argumentType);

            var  arrayElementType = ((SzArrayTypeSignature)argumentType).BaseType;
            uint elementCount     = reader.CanRead(sizeof(uint)) ? reader.ReadUInt32() : uint.MaxValue;

            result.IsNullArray = elementCount == uint.MaxValue;

            if (!result.IsNullArray)
            {
                for (uint i = 0; i < elementCount; i++)
                {
                    var element = CustomAttributeArgumentElement.FromReader(parentModule, arrayElementType, reader);
                    result.Elements.Add(element);
                }
            }

            return(result);
        }
Esempio n. 25
0
        /// <summary>
        /// Reads a single Var table at the provided input stream.
        /// </summary>
        /// <param name="reader">The input stream.</param>
        /// <returns>The var table.</returns>
        /// <exception cref="FormatException">
        /// Occurs when the input stream does not point to a valid Var table structure.
        /// </exception>
        public static VarTable FromReader(IBinaryStreamReader reader)
        {
            var header = VersionTableEntryHeader.FromReader(reader);

            if (header.Key != TranslationKey)
            {
                throw new FormatException($"Expected a Var structure but got a {header.Key} structure.");
            }

            reader.Align(4);

            var result = new VarTable();

            uint start = reader.FileOffset;

            while (reader.FileOffset - start < header.ValueLength)
            {
                result.Values.Add(reader.ReadUInt32());
            }

            return(result);
        }
Esempio n. 26
0
        private static object ReadElement(IBinaryStreamReader reader, ElementType elementType)
        {
            switch (elementType)
            {
            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.R4:
                return(reader.ReadSingle());

            case ElementType.R8:
                return(reader.ReadDouble());
            }

            ThrowUnsupportedElementType(elementType);
            return(null);
        }
Esempio n. 27
0
        /// <summary>
        /// Reads a single section header at the current position of the provided input stream.
        /// </summary>
        /// <param name="reader">The input stream to read from.</param>
        /// <returns>The section header that was read.</returns>
        public static SectionHeader FromReader(IBinaryStreamReader reader)
        {
            uint offset = reader.FileOffset;

            var nameBytes = new byte[8];

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

            return(new SectionHeader(Encoding.UTF8.GetString(nameBytes).Replace("\0", ""), 0)
            {
                _fileOffset = offset,
                VirtualSize = reader.ReadUInt32(),
                VirtualAddress = reader.ReadUInt32(),
                SizeOfRawData = reader.ReadUInt32(),
                PointerToRawData = reader.ReadUInt32(),
                PointerToRelocations = reader.ReadUInt32(),
                PointerToLineNumbers = reader.ReadUInt32(),
                NumberOfRelocations = reader.ReadUInt16(),
                NumberOfLineNumbers = reader.ReadUInt16(),
                Characteristics = (SectionFlags)reader.ReadUInt32()
            });
        }
Esempio n. 28
0
        /// <summary>
        /// Reads a PE file from an input stream.
        /// </summary>
        /// <param name="reader">The input stream.</param>
        /// <param name="mode">Indicates how the input PE file is mapped.</param>
        /// <exception cref="BadImageFormatException">Occurs when the input stream is malformed.</exception>
        public SerializedPEFile(IBinaryStreamReader reader, PEMappingMode mode)
        {
            _reader     = reader ?? throw new ArgumentNullException(nameof(reader));
            MappingMode = mode;

            // DOS header.
            DosHeader     = DosHeader.FromReader(reader);
            reader.Offset = DosHeader.Offset + DosHeader.NextHeaderOffset;

            uint signature = reader.ReadUInt32();

            if (signature != ValidPESignature)
            {
                throw new BadImageFormatException();
            }

            // Read NT headers.
            FileHeader     = FileHeader.FromReader(reader);
            OptionalHeader = OptionalHeader.FromReader(reader);

            // Read section headers.
            reader.Offset   = OptionalHeader.Offset + FileHeader.SizeOfOptionalHeader;
            _sectionHeaders = new List <SectionHeader>(FileHeader.NumberOfSections);
            for (int i = 0; i < FileHeader.NumberOfSections; i++)
            {
                _sectionHeaders.Add(SectionHeader.FromReader(reader));
            }

            // Data between section headers and sections.
            int extraSectionDataLength = (int)(DosHeader.Offset + OptionalHeader.SizeOfHeaders - reader.Offset);

            if (extraSectionDataLength != 0)
            {
                ExtraSectionData = DataSegment.FromReader(reader, extraSectionDataLength);
            }
        }
        /// <summary>
        /// Reads a single debug data entry from an input stream.
        /// </summary>
        /// <param name="reader">The input stream.</param>
        /// <param name="dataReader">The object responsible for reading the contents.</param>
        public SerializedDebugDataEntry(IBinaryStreamReader reader, IDebugDataReader dataReader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }
            _dataReader = dataReader ?? throw new ArgumentNullException(nameof(dataReader));
            Offset      = reader.Offset;
            Rva         = reader.Rva;

            Characteristics   = reader.ReadUInt32();
            TimeDateStamp     = reader.ReadUInt32();
            MajorVersion      = reader.ReadUInt16();
            MinorVersion      = reader.ReadUInt16();
            _type             = (DebugDataType)reader.ReadUInt32();
            _sizeOfData       = reader.ReadUInt32();
            _addressOfRawData = reader.ReadUInt32();
            _pointerToRawData = reader.ReadUInt32();
        }
        /// <summary>
        /// Reads a single debug data entry from an input stream.
        /// </summary>
        /// <param name="context">The reading context.</param>
        /// <param name="directoryReader">The input stream.</param>
        public SerializedDebugDataEntry(
            PEReaderContext context,
            IBinaryStreamReader directoryReader)
        {
            if (directoryReader == null)
            {
                throw new ArgumentNullException(nameof(directoryReader));
            }
            _context = context ?? throw new ArgumentNullException(nameof(context));

            Offset = directoryReader.Offset;
            Rva    = directoryReader.Rva;

            Characteristics   = directoryReader.ReadUInt32();
            TimeDateStamp     = directoryReader.ReadUInt32();
            MajorVersion      = directoryReader.ReadUInt16();
            MinorVersion      = directoryReader.ReadUInt16();
            _type             = (DebugDataType)directoryReader.ReadUInt32();
            _sizeOfData       = directoryReader.ReadUInt32();
            _addressOfRawData = directoryReader.ReadUInt32();
            _pointerToRawData = directoryReader.ReadUInt32();
        }
Esempio n. 31
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;
        }
Esempio n. 32
0
 /// <summary>
 /// Reads a single data directory at the current position of the provided input stream.
 /// </summary>
 /// <param name="reader">The input stream to read from.</param>
 /// <returns>The data directory that was read.</returns>
 public static DataDirectory FromReader(IBinaryStreamReader reader)
 {
     return(new DataDirectory(reader.ReadUInt32(), reader.ReadUInt32()));
 }
Esempio n. 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:
            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(reader.ReadSerString());
            }
            throw new NotSupportedException("Unsupported element type " + typeSignature.ElementType);
        }
Esempio n. 34
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);
        }