Example #1
0
        /// <summary>
        /// Reads a version resource from an input stream.
        /// </summary>
        /// <param name="reader">The input stream.</param>
        /// <returns>The parsed version resource.</returns>
        /// <exception cref="FormatException">
        /// Occurs when the input stream does not point to a valid version resource.
        /// </exception>
        public static VersionInfoResource FromReader(IBinaryStreamReader reader)
        {
            uint start = reader.FileOffset;

            // Read header.
            var header = VersionTableEntryHeader.FromReader(reader);

            if (header.Key != VsVersionInfoKey)
            {
                throw new FormatException($"Input stream does not point to a {VsVersionInfoKey} entry.");
            }

            var result = new VersionInfoResource();

            // Read fixed version info.
            reader.Align(4);
            result.FixedVersionInfo = FixedVersionInfo.FromReader(reader);

            // Read children.
            while (reader.FileOffset - start < header.Length)
            {
                reader.Align(4);
                result.AddEntry(ReadNextEntry(reader));
            }

            return(result);
        }
Example #2
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);
        }
Example #3
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);
        }
        /// <summary>
        /// Reads a single metadata stream header from an input stream.
        /// </summary>
        /// <param name="reader">The input stream.</param>
        /// <returns>The header.</returns>
        public static MetadataStreamHeader FromReader(IBinaryStreamReader reader)
        {
            uint   offset = reader.ReadUInt32();
            uint   size   = reader.ReadUInt32();
            string name   = reader.ReadAsciiString();

            reader.Align(4);
            return(new MetadataStreamHeader(offset, size, name));
        }
Example #5
0
        private static VersionTableEntry ReadNextEntry(IBinaryStreamReader reader)
        {
            uint start = reader.FileOffset;

            var header = VersionTableEntryHeader.FromReader(reader);

            reader.Align(4);

            return(header.Key switch
            {
                VarFileInfo.VarFileInfoKey => VarFileInfo.FromReader(start, header, reader),
                StringFileInfo.StringFileInfoKey => StringFileInfo.FromReader(start, header, reader),
                _ => throw new FormatException($"Invalid or unsupported entry {header.Key}.")
            });
        private static KeyValuePair <string, string> ReadEntry(IBinaryStreamReader reader)
        {
            uint start = reader.FileOffset;

            // Read header.
            var header = VersionTableEntryHeader.FromReader(reader);

            reader.Align(4);

            // Read value.
            var data  = new byte[header.ValueLength * sizeof(char)];
            int count = reader.ReadBytes(data, 0, data.Length);

            // Exclude zero terminator.
            count = Math.Max(count - 2, 0);
            string value = Encoding.Unicode.GetString(data, 0, count);

            // Skip any unprocessed bytes.
            reader.FileOffset = start + header.Length;

            return(new KeyValuePair <string, string>(header.Key, value));
        }
Example #7
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);
        }
        /// <summary>
        /// Reads a single StringTable structure from the provided input stream.
        /// </summary>
        /// <param name="reader">The input stream.</param>
        /// <returns>The read structure.</returns>
        public static StringTable FromReader(IBinaryStreamReader reader)
        {
            uint start = reader.FileOffset;

            // Read header.
            var header = VersionTableEntryHeader.FromReader(reader);

            if (header.Key.Length != 8 || !uint.TryParse(header.Key, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out uint rawKey))
            {
                throw new FormatException("Invalid string table language identifier or code page.");
            }

            var result = new StringTable((ushort)(rawKey >> 16), (ushort)(rawKey & 0xFFFF));

            // Read entries.
            while (reader.FileOffset - start < header.Length)
            {
                reader.Align(4);
                var entry = ReadEntry(reader);
                result.Add(entry.Key, entry.Value);
            }

            return(result);
        }