/// <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(); }
/// <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); }