public static CilExtraSection FromReader(IBinaryStreamReader reader) { var section = new CilExtraSection { Attributes = (CilExtraSectionAttributes)reader.ReadByte() }; if (!section.IsExceptionHandler) { throw new NotSupportedException("Invalid or unsupported extra section."); } int dataSize; if (section.IsFat) { dataSize = reader.ReadByte() | (reader.ReadByte() << 0x08) | (reader.ReadByte() << 0x10); } else { dataSize = reader.ReadByte(); reader.ReadUInt16(); } section.Data = reader.ReadBytes(dataSize); return(section); }
/// <summary> /// Reads a DOS header structure at the current position of the provided input stream. /// </summary> /// <param name="reader">The input stream to read from.</param> /// <returns>The read DOS header.</returns> /// <exception cref="BadImageFormatException">Occurs when the input stream does not point to a valid DOS header.</exception> public static DosHeader FromReader(IBinaryStreamReader reader) { ulong offset = reader.Offset; uint rva = reader.Rva; var stub = new byte[DefaultNewHeaderOffset]; ushort magic = reader.ReadUInt16(); if (magic != ValidPEMagic) { throw new BadImageFormatException(); } reader.Offset += NextHeaderFieldOffset - 2; uint nextHeaderOffset = reader.ReadUInt32(); if (nextHeaderOffset != DefaultNewHeaderOffset) { Array.Resize(ref stub, (int)nextHeaderOffset); } reader.Offset -= NextHeaderFieldOffset + 4; reader.ReadBytes(stub, 0, stub.Length); return(new DosHeader(stub) { Offset = offset, Rva = rva, NextHeaderOffset = nextHeaderOffset }); }
/// <summary> /// Reads a single extra section from the provided input stream. /// </summary> /// <param name="reader">The input stream to read from.</param> /// <returns>The extra section that was read.</returns> public static CilExtraSection FromReader(IBinaryStreamReader reader) { var section = new CilExtraSection { Attributes = (CilExtraSectionAttributes)reader.ReadByte() }; int dataSize; if (section.IsFat) { dataSize = reader.ReadByte() | (reader.ReadByte() << 0x08) | (reader.ReadByte() << 0x10); } else { dataSize = reader.ReadByte(); reader.ReadUInt16(); } section.Data = new byte[dataSize]; reader.ReadBytes(section.Data, 0, dataSize); return(section); }
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); }
protected string ReadString(IBinaryStreamReader reader) { var offset = (uint)(reader.Position - reader.StartPosition); string value; if (_cachedStrings.TryGetValue(offset, out value)) { reader.Position += 1 + Encoding.Unicode.GetByteCount(value) + 1; } else { var length = reader.ReadCompressedUInt32(); if (length <= 0) { return(string.Empty); } value = Encoding.Unicode.GetString(reader.ReadBytes((int)length - 1)); reader.Position++; _cachedStrings.Add(offset, value); } return(value); }
public static DataBlobSignature FromReader(IBinaryStreamReader reader) { long position = reader.Position; return new DataBlobSignature(reader.ReadBytes((int) reader.Length)) { StartOffset = position }; }
/// <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); }
public new static CilRawSmallMethodBody FromReader(IBinaryStreamReader reader) { int codeSize = reader.ReadByte() >> 2; return(new CilRawSmallMethodBody { Code = reader.ReadBytes(codeSize) }); }
public ImageSection(ImageSectionHeader header, IBinaryStreamReader reader) { if (header == null) { throw new ArgumentNullException("header"); } Header = header; Segments.Add(new DataSegment(reader.ReadBytes((int)reader.Length))); }
public static DataBlobSignature FromReader(IBinaryStreamReader reader) { long position = reader.Position; return(new DataBlobSignature(reader.ReadBytes((int)reader.Length)) { StartOffset = position }); }
/// <summary> /// Reads all remaining data from the input stream. /// </summary> /// <param name="reader">The input stream.</param> /// <returns>The remaining bytes of the input stream.</returns> public static byte[] ReadToEnd(this IBinaryStreamReader reader) { int remainingByteCount = (int)(reader.Length - (reader.FileOffset - reader.StartPosition)); var buffer = new byte[remainingByteCount]; int read = reader.ReadBytes(buffer, 0, remainingByteCount); if (read != remainingByteCount) { Array.Resize(ref buffer, read); } return(buffer); }
/// <summary> /// Reads an icon resource entry from an input stream. /// </summary> /// <param name="reader">The input stream.</param> /// <returns>The parsed icon resource entry.</returns> public static IconEntry FromReader(IBinaryStreamReader reader) { var result = new IconEntry { Offset = reader.Offset, Rva = reader.Rva, RawIcon = new byte[reader.Length] }; reader.ReadBytes(result.RawIcon, 0, (int)reader.Length); return(result); }
/// <summary> /// Reads a serialized UTF8 string from the steram. /// </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.ReadByte() == 0xFF) { return(null); } reader.Position--; uint length; if (!reader.TryReadCompressedUInt32(out length)) { return(null); } return(Encoding.UTF8.GetString(reader.ReadBytes((int)length))); }
/// <summary> /// Reads a single data segment at the current position of the provided input stream. /// </summary> /// <param name="reader">The input stream to read from.</param> /// <param name="count">The number of bytes to read.</param> /// <returns>The read data segment.</returns> public static DataSegment FromReader(IBinaryStreamReader reader, int count) { ulong position = reader.Offset; uint rva = reader.Rva; var buffer = new byte[count]; reader.ReadBytes(buffer, 0, count); return(new DataSegment(buffer) { Offset = position, Rva = rva }); }
/// <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)); }
private Guid ReadGuid(IBinaryStreamReader reader) { Guid guid; var offset = (uint)(reader.Position - reader.StartPosition) + 1; if (!_cachedGuids.TryGetValue(offset, out guid)) { _cachedGuids.Add(offset, guid = new Guid(reader.ReadBytes(16))); } else { reader.Position += 16; } return(guid); }
/// <summary> /// Initializes a new instance of <see cref="RsdsDataSegment"/> /// </summary> /// <param name="context">Context for the reader</param> /// <param name="reader">The input stream to read from.</param> /// <returns></returns> public new static RsdsDataSegment FromReader(PEReaderContext context, IBinaryStreamReader reader) { if (reader.Length < RsdsExpectedDataSize) { context.BadImage("RSDS Data was shorter than the minimal expected length"); return(null); } var result = new RsdsDataSegment(); byte[] buffer = new byte[16]; reader.ReadBytes(buffer, 0, 16); result.Guid = new Guid(buffer); result.Age = reader.ReadUInt32(); result.Path = Encoding.UTF8.GetString(reader.ReadBytesUntil(0x00)); return(result); }
/// <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 private key from an input stream. /// </summary> /// <param name="reader">The input stream.</param> /// <returns>The private key.</returns> /// <exception cref="FormatException">Occurs when the input stream is not in the correct format.</exception> /// <exception cref="NotSupportedException">Occurs when an invalid or unsupported algorithm is specified.</exception> public new static StrongNamePrivateKey FromReader(IBinaryStreamReader reader) { // Read BLOBHEADER ReadBlobHeader(reader, StrongNameKeyStructureType.PrivateKeyBlob, 2, SignatureAlgorithm.RsaSign); // Read RSAPUBKEY if ((RsaPublicKeyMagic)reader.ReadUInt32() != RsaPublicKeyMagic.Rsa2) { throw new FormatException("Input stream does not contain a valid RSA private key header magic."); } uint bitLength = reader.ReadUInt32(); uint length8 = bitLength / 8; uint length16 = bitLength / 16; var result = new StrongNamePrivateKey { PublicExponent = reader.ReadUInt32(), Modulus = new byte[length8], P = new byte[length16], Q = new byte[length16], DP = new byte[length16], DQ = new byte[length16], InverseQ = new byte[length16], PrivateExponent = new byte[length8] }; reader.ReadBytes(result.Modulus, 0, result.Modulus.Length); // Read private data. reader.ReadBytes(result.P, 0, result.P.Length); reader.ReadBytes(result.Q, 0, result.Q.Length); reader.ReadBytes(result.DP, 0, result.DP.Length); reader.ReadBytes(result.DQ, 0, result.DQ.Length); reader.ReadBytes(result.InverseQ, 0, result.InverseQ.Length); reader.ReadBytes(result.PrivateExponent, 0, result.PrivateExponent.Length); Array.Reverse(result.Modulus); Array.Reverse(result.P); Array.Reverse(result.Q); Array.Reverse(result.DP); Array.Reverse(result.DQ); Array.Reverse(result.InverseQ); Array.Reverse(result.PrivateExponent); return(result); }
/// <summary> /// Reads a single section header at the current position of the provided input stream. /// </summary> /// <param name="reader">The input stream to read from.</param> /// <returns>The section header that was read.</returns> public static SectionHeader FromReader(IBinaryStreamReader reader) { uint offset = reader.FileOffset; var nameBytes = new byte[8]; reader.ReadBytes(nameBytes, 0, nameBytes.Length); return(new SectionHeader(Encoding.UTF8.GetString(nameBytes).Replace("\0", ""), 0) { _fileOffset = offset, VirtualSize = reader.ReadUInt32(), VirtualAddress = reader.ReadUInt32(), SizeOfRawData = reader.ReadUInt32(), PointerToRawData = reader.ReadUInt32(), PointerToRelocations = reader.ReadUInt32(), PointerToLineNumbers = reader.ReadUInt32(), NumberOfRelocations = reader.ReadUInt16(), NumberOfLineNumbers = reader.ReadUInt16(), Characteristics = (SectionFlags)reader.ReadUInt32() }); }
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)); }
/// <summary> /// Reads a raw method body from the given binary input stream using the tiny method body format. /// </summary> /// <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 /// tiny format.</exception> public new static CilRawTinyMethodBody FromReader(IBinaryStreamReader reader) { ulong fileOffset = reader.Offset; uint rva = reader.Rva; var flag = (CilMethodBodyAttributes)reader.ReadByte(); if ((flag & CilMethodBodyAttributes.Tiny) != CilMethodBodyAttributes.Tiny) { throw new FormatException("Invalid tiny CIL method body header."); } int codeSize = (byte)flag >> 2; var code = new byte[codeSize]; reader.ReadBytes(code, 0, codeSize); var methodBody = new CilRawTinyMethodBody(code); methodBody.UpdateOffsets(fileOffset, rva); return(methodBody); }
/// <summary> /// Reads a private key from an input stream. /// </summary> /// <param name="reader">The input stream.</param> /// <returns>The private key.</returns> /// <exception cref="FormatException">Occurs when the input stream is not in the correct format.</exception> /// <exception cref="NotSupportedException">Occurs when an invalid or unsupported algorithm is specified.</exception> public static StrongNamePublicKey FromReader(IBinaryStreamReader reader) { // Read BLOBHEADER ReadBlobHeader(reader, StrongNameKeyStructureType.PublicKeyBlob, 2, SignatureAlgorithm.RsaSign); // Read RSAPUBKEY if ((RsaPublicKeyMagic)reader.ReadUInt32() != RsaPublicKeyMagic.Rsa1) { throw new FormatException("Input stream does not contain a valid RSA public key header magic."); } uint bitLength = reader.ReadUInt32(); var result = new StrongNamePublicKey { PublicExponent = reader.ReadUInt32(), Modulus = new byte[bitLength / 8] }; reader.ReadBytes(result.Modulus, 0, result.Modulus.Length); return(result); }
/// <summary> /// Aligns the reader to a specified boundary. /// </summary> /// <param name="reader">The reader to align.</param> /// <param name="align">The boundary to use.</param> public static void Align(this IBinaryStreamReader reader, int align) { align--; reader.ReadBytes((((int)reader.Position + align) & ~align) - (int)reader.Position); }
public static DataSegment FromReader(IBinaryStreamReader reader) { return(new DataSegment(reader.ReadBytes( (int)(reader.Length - (reader.Position - reader.StartPosition))))); }
public static DataBlobSignature FromReader(IBinaryStreamReader reader) { return(new DataBlobSignature(reader.ReadBytes((int)reader.Length))); }
public static byte[] ReadToEnd(this IBinaryStreamReader reader) { return(reader.ReadBytes((int)(reader.Length - (reader.Position - reader.StartPosition)))); }