Example #1
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, ref BinaryStreamReader directoryReader)
        {
            if (!directoryReader.IsValid)
            {
                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();

            uint versionLength = directoryReader.ReadUInt32();

            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();
        }
Example #2
0
        /// <summary>
        /// Reads a single safe array marshal descriptor from the provided input stream.
        /// </summary>
        /// <param name="parentModule">The module defining the descriptor.</param>
        /// <param name="reader">The input stream.</param>
        /// <returns>The descriptor.</returns>
        public new static SafeArrayMarshalDescriptor FromReader(ModuleDefinition parentModule, ref BinaryStreamReader reader)
        {
            if (!reader.TryReadCompressedUInt32(out uint type))
            {
                return(new SafeArrayMarshalDescriptor(SafeArrayVariantType.NotSet));
            }

            var variantType = (SafeArrayVariantType)type & SafeArrayVariantType.TypeMask;
            var flags       = (SafeArrayTypeFlags)type & ~SafeArrayTypeFlags.Mask;

            var result = new SafeArrayMarshalDescriptor(variantType, flags);

            if (reader.CanRead(1))
            {
                string typeName = reader.ReadSerString();
                if (typeName != null)
                {
                    result.UserDefinedSubType = TypeNameParser.Parse(parentModule, typeName);
                }
            }

            return(result);
        }