/// <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); }
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); }
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); }
private static object ReadValue(ModuleDefinition parentModule, TypeSignature valueType, IBinaryStreamReader reader) { switch (valueType.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(parentModule, TypeSignature.ReadFieldOrPropType(parentModule, reader), reader)); case ElementType.Class: case ElementType.Enum: case ElementType.ValueType: var enumTypeDef = parentModule.MetadataResolver.ResolveType(valueType); if (enumTypeDef != null && enumTypeDef.IsEnum) { return(ReadValue(parentModule, enumTypeDef.GetEnumUnderlyingType(), reader)); } break; } if (valueType.IsTypeOf("System", "Type")) { return(TypeNameParser.Parse(parentModule, reader.ReadSerString())); } throw new NotSupportedException($"Unsupported element type {valueType.ElementType}."); }
/// <summary> /// Reads an optional header from the provided input stream. /// </summary> /// <param name="reader">The input stream.</param> /// <param name="ignoreNumberOfRvasAndSizes">Indicates whether the number of data directories should be ignored /// and <see cref="DefaultNumberOfRvasAndSizes"/> should be used instead.</param> /// <returns>The optional header.</returns> /// <exception cref="BadImageFormatException">Occurs when the input stream is malformed.</exception> public static OptionalHeader FromReader(IBinaryStreamReader reader, bool ignoreNumberOfRvasAndSizes = true) { var header = new OptionalHeader { Offset = reader.Offset, Rva = reader.Rva, Magic = (OptionalHeaderMagic)reader.ReadUInt16(), MajorLinkerVersion = reader.ReadByte(), MinorLinkerVersion = reader.ReadByte(), SizeOfCode = reader.ReadUInt32(), SizeOfInitializedData = reader.ReadUInt32(), SizeOfUninitializedData = reader.ReadUInt32(), AddressOfEntrypoint = reader.ReadUInt32(), BaseOfCode = reader.ReadUInt32() }; switch (header.Magic) { case OptionalHeaderMagic.Pe32: header.BaseOfData = reader.ReadUInt32(); header.ImageBase = reader.ReadUInt32(); break; case OptionalHeaderMagic.Pe32Plus: header.ImageBase = reader.ReadUInt64(); break; default: throw new BadImageFormatException("Unrecognized or unsupported optional header format."); } header.SectionAlignment = reader.ReadUInt32(); header.FileAlignment = reader.ReadUInt32(); header.MajorOperatingSystemVersion = reader.ReadUInt16(); header.MinorOperatingSystemVersion = reader.ReadUInt16(); header.MajorImageVersion = reader.ReadUInt16(); header.MinorImageVersion = reader.ReadUInt16(); header.MajorSubsystemVersion = reader.ReadUInt16(); header.MinorSubsystemVersion = reader.ReadUInt16(); header.Win32VersionValue = reader.ReadUInt32(); header.SizeOfImage = reader.ReadUInt32(); header.SizeOfHeaders = reader.ReadUInt32(); header.CheckSum = reader.ReadUInt32(); header.SubSystem = (SubSystem)reader.ReadUInt16(); header.DllCharacteristics = (DllCharacteristics)reader.ReadUInt16(); if (header.Magic == OptionalHeaderMagic.Pe32) { header.SizeOfStackReserve = reader.ReadUInt32(); header.SizeOfStackCommit = reader.ReadUInt32(); header.SizeOfHeapReserve = reader.ReadUInt32(); header.SizeOfHeapCommit = reader.ReadUInt32(); } else { header.SizeOfStackReserve = reader.ReadUInt64(); header.SizeOfStackCommit = reader.ReadUInt64(); header.SizeOfHeapReserve = reader.ReadUInt64(); header.SizeOfHeapCommit = reader.ReadUInt64(); } header.LoaderFlags = reader.ReadUInt32(); header.NumberOfRvaAndSizes = reader.ReadUInt32(); int dataDirectories = ignoreNumberOfRvasAndSizes ? DefaultNumberOfRvasAndSizes : (int)header.NumberOfRvaAndSizes; for (int i = 0; i < dataDirectories; i++) { header.DataDirectories.Add(DataDirectory.FromReader(reader)); } return(header); }
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); }
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}."); } }
/// <summary> /// Either reads a 32 bit number or a 64 bit number. /// </summary> /// <param name="reader">The reader to use for reading the data.</param> /// <param name="is32Bit">Determines whether to read a 32 or a 64 bit integer.</param> /// <returns>The read integer.</returns> public static ulong ReadNativeInt(this IBinaryStreamReader reader, bool is32Bit) { return(is32Bit ? reader.ReadUInt32() : reader.ReadUInt64()); }