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; }
public static new GenericInstanceTypeSignature FromReader(MetadataHeader header, IBinaryStreamReader reader) { if (!reader.CanRead(sizeof (byte))) return null; long position = reader.Position; var elementType = (ElementType)reader.ReadByte(); var type = ReadTypeDefOrRef(header, reader); var signature = new GenericInstanceTypeSignature(type) { StartOffset = position, IsValueType = elementType == ElementType.ValueType }; uint count; if (!reader.TryReadCompressedUInt32(out count)) return signature; for (int i = 0; i < count; i++) signature.GenericArguments.Add(TypeSignature.FromReader(header, reader)); return signature; }
public static new MethodSignature FromReader(MetadataHeader header, IBinaryStreamReader reader) { if (!reader.CanRead(sizeof (byte))) return null; var signature = new MethodSignature { StartOffset = reader.Position, Attributes = (CallingConventionAttributes)reader.ReadByte() }; if (signature.IsGeneric) { uint genericParameterCount; if (!reader.TryReadCompressedUInt32(out genericParameterCount)) return signature; signature.GenericParameterCount = (int)genericParameterCount; } uint parameterCount; if (!reader.TryReadCompressedUInt32(out parameterCount)) return signature; signature.ReturnType = TypeSignature.FromReader(header, reader); for (int i = 0; i < parameterCount; i++) { signature.Parameters.Add(ParameterSignature.FromReader(header, reader)); } return signature; }
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; }
public static new SafeArrayMarshalDescriptor FromReader(IBinaryStreamReader reader) { var descriptor = new SafeArrayMarshalDescriptor() { StartOffset = reader.Position, }; if (reader.CanRead((sizeof (byte)))) descriptor.ElementType = (VariantType)reader.ReadByte(); return descriptor; }
public static CustomAttributeNamedArgument FromReader(MetadataHeader header, IBinaryStreamReader reader) { var signature = new CustomAttributeNamedArgument { StartOffset = reader.Position, ArgumentMemberType = (reader.CanRead(sizeof (byte)) ? (CustomAttributeArgumentMemberType)reader.ReadByte() : CustomAttributeArgumentMemberType.Field), ArgumentType = TypeSignature.ReadFieldOrPropType(header, reader), MemberName = reader.ReadSerString(), }; signature.Argument = CustomAttributeArgument.FromReader(header, signature.ArgumentType, reader); return signature; }
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); }
/// <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(); }
/// <summary> /// Reads a serialized UTF8 string from the stream. /// </summary> /// <param name="reader">The reader to use for reading the data.</param> /// <returns>The string that was read from the stream.</returns> public static string ReadSerString(this IBinaryStreamReader reader) { if (!reader.CanRead(1) || reader.ReadByte() == 0xFF) { return(null); } reader.FileOffset--; if (!reader.TryReadCompressedUInt32(out uint length)) { return(null); } var data = new byte[length]; length = (uint)reader.ReadBytes(data, 0, (int)length); return(Encoding.UTF8.GetString(data, 0, (int)length)); }
public static new FixedArrayMarshalDescriptor FromReader(IBinaryStreamReader reader) { var descriptor = new FixedArrayMarshalDescriptor() { StartOffset = reader.Position, }; uint value; if (!reader.TryReadCompressedUInt32(out value)) return descriptor; descriptor.NumberOfElements = (int)value; if (reader.CanRead(sizeof(byte))) descriptor.ElementType = (NativeType)reader.ReadByte(); return descriptor; }
public static CustomAttributeNamedArgument FromReader(MetadataHeader header, IBinaryStreamReader reader) { var signature = new CustomAttributeNamedArgument { StartOffset = reader.Position, ArgumentMemberType = (reader.CanRead(sizeof(byte)) ? (CustomAttributeArgumentMemberType)reader.ReadByte() : CustomAttributeArgumentMemberType.Field), ArgumentType = TypeSignature.ReadFieldOrPropType(header, reader), MemberName = reader.ReadSerString(), }; signature.Argument = CustomAttributeArgument.FromReader(header, signature.ArgumentType, reader); return(signature); }
public new static FixedArrayMarshalDescriptor FromReader(IBinaryStreamReader reader) { var descriptor = new FixedArrayMarshalDescriptor(); uint value; if (!reader.TryReadCompressedUInt32(out value)) { return(descriptor); } descriptor.NumberOfElements = (int)value; if (reader.CanRead(sizeof(byte))) { descriptor.ElementType = (NativeType)reader.ReadByte(); } return(descriptor); }
/// <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(); }
/// <summary> /// Reads a single method signature at the current position of the provided stream reader. /// </summary> /// <param name="image">The image the field is defined in.</param> /// <param name="reader">The reader to use.</param> /// <param name="readToEnd">Determines whether any extra data after the signature should be read and /// put into the <see cref="ExtendableBlobSignature.ExtraData"/> property.</param> /// <param name="protection">The recursion protection that is used to detect malicious loops in the metadata.</param> /// <returns>The read signature.</returns> public new static MethodSignature FromReader( MetadataImage image, IBinaryStreamReader reader, bool readToEnd, RecursionProtection protection) { if (!reader.CanRead(sizeof(byte))) { return(null); } var signature = new MethodSignature { Attributes = (CallingConventionAttributes)reader.ReadByte() }; if (signature.IsGeneric) { if (!reader.TryReadCompressedUInt32(out uint genericParameterCount)) { return(signature); } signature.GenericParameterCount = (int)genericParameterCount; } if (!reader.TryReadCompressedUInt32(out uint parameterCount)) { return(signature); } signature.ReturnType = TypeSignature.FromReader(image, reader); for (int i = 0; i < parameterCount; i++) { signature.Parameters.Add(ParameterSignature.FromReader(image, reader, protection)); } if (readToEnd) { signature.ExtraData = reader.ReadToEnd(); } return(signature); }
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); }
/// <summary> /// Reads a permission set signature from the provided input blob stream. /// </summary> /// <param name="parentModule">The module the permission set resides in.</param> /// <param name="reader">The input blob stream.</param> /// <returns>The permission set.</returns> public static PermissionSetSignature FromReader(ModuleDefinition parentModule, IBinaryStreamReader reader) { var result = new PermissionSetSignature(); if (reader.ReadByte() != '.') { return(result); } if (!reader.TryReadCompressedUInt32(out uint count)) { return(result); } for (int i = 0; i < count && reader.CanRead(1); i++) { result.Attributes.Add(SecurityAttribute.FromReader(parentModule, reader)); } return(result); }
public new static MethodSignature FromReader(MetadataHeader header, IBinaryStreamReader reader) { if (!reader.CanRead(sizeof(byte))) { return(null); } var signature = new MethodSignature { StartOffset = reader.Position, Attributes = (CallingConventionAttributes)reader.ReadByte() }; if (signature.IsGeneric) { uint genericParameterCount; if (!reader.TryReadCompressedUInt32(out genericParameterCount)) { return(signature); } signature.GenericParameterCount = (int)genericParameterCount; } uint parameterCount; if (!reader.TryReadCompressedUInt32(out parameterCount)) { return(signature); } signature.ReturnType = TypeSignature.FromReader(header, reader); for (int i = 0; i < parameterCount; i++) { signature.Parameters.Add(ParameterSignature.FromReader(header, reader)); } return(signature); }
internal static GenericInstanceMethodSignature FromReader(ModuleDefinition parentModule, IBinaryStreamReader reader, RecursionProtection protection) { if (!reader.CanRead(sizeof(byte))) { return(null); } var attributes = (CallingConventionAttributes)reader.ReadByte(); var result = new GenericInstanceMethodSignature(attributes); if (!reader.TryReadCompressedUInt32(out uint count)) { return(result); } for (int i = 0; i < count; i++) { result.TypeArguments.Add(TypeSignature.FromReader(parentModule, reader, protection)); } return(result); }
/// <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, IBinaryStreamReader 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); }
public void ReadValue(TypeSignature valueType) { if (valueType.IsTypeOf("System", "Type")) { Elements.Add(TypeNameParser.Parse(_parentModule, _reader.ReadSerString())); return; } switch (valueType.ElementType) { case ElementType.Boolean: Elements.Add(_reader.ReadByte() == 1); break; case ElementType.Char: Elements.Add((char)_reader.ReadUInt16()); break; case ElementType.R4: Elements.Add(_reader.ReadSingle()); break; case ElementType.R8: Elements.Add(_reader.ReadDouble()); break; case ElementType.I1: Elements.Add(_reader.ReadSByte()); break; case ElementType.I2: Elements.Add(_reader.ReadInt16()); break; case ElementType.I4: Elements.Add(_reader.ReadInt32()); break; case ElementType.I8: Elements.Add(_reader.ReadInt64()); break; case ElementType.U1: Elements.Add(_reader.ReadByte()); break; case ElementType.U2: Elements.Add(_reader.ReadUInt16()); break; case ElementType.U4: Elements.Add(_reader.ReadUInt32()); break; case ElementType.U8: Elements.Add(_reader.ReadUInt64()); break; case ElementType.String: Elements.Add(_reader.ReadSerString()); break; case ElementType.Object: var reader = new CustomAttributeArgumentReader(_parentModule, _reader); var type = TypeSignature.ReadFieldOrPropType(_parentModule, _reader); reader.ReadValue(type); Elements.Add(new BoxedArgument(type, type.ElementType == ElementType.SzArray ? reader.Elements.ToArray() : reader.Elements[0])); break; case ElementType.SzArray: var arrayElementType = ((SzArrayTypeSignature)valueType).BaseType; uint elementCount = _reader.CanRead(sizeof(uint)) ? _reader.ReadUInt32() : uint.MaxValue; IsNullArray = elementCount == uint.MaxValue; if (!IsNullArray) { for (uint i = 0; i < elementCount; i++) { ReadValue(arrayElementType); } } break; case ElementType.Class: case ElementType.Enum: case ElementType.ValueType: // Value is an enum, resolve it and get underlying type. // If that fails, most enums are int32s, assume that is the case in an attempt to recover. var enumTypeDef = _parentModule.MetadataResolver.ResolveType(valueType); TypeSignature underlyingType; if (enumTypeDef is null) { underlyingType = _parentModule.CorLibTypeFactory.Int32; } else if (enumTypeDef.IsEnum) { underlyingType = enumTypeDef.GetEnumUnderlyingType() ?? _parentModule.CorLibTypeFactory.Int32; } else { throw new NotSupportedException($"Type {valueType} is not an enum."); } ReadValue(underlyingType); break; default: throw new NotSupportedException($"Unsupported element type {valueType.ElementType}."); } }