/// <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(ref BinaryStreamReader 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 }); }
static void ReadGuids(BinaryStreamReader reader, Guid[] guids) { byte[] buf = new byte[16]; for (int i = 0; i < guids.Length; i++) { reader.ReadBytes(buf, 0, buf.Length); guids[i] = new Guid(buf); } }
private string ReadName(BinaryStreamReader reader) { ushort length = reader.ReadUInt16(); byte[] buf = new byte[length * 2]; // two-byte Unicode characters reader.ReadBytes(buf, 0, buf.Length); string result = Encoding.Unicode.GetString(buf, 0, buf.Length); return(result); }
private static void MeasureManyFilesLoad(string[] dllFiles) { var buffer = new byte[1024]; var start = DateTime.UtcNow; foreach (var dll in dllFiles) { using (var dllStream = File.OpenRead(dll)) { var pe = new PEFile(); pe.ReadFrom(new BinaryStreamReader(dllStream, buffer)); } } TimeSpan headersOnly = DateTime.UtcNow - start; byte[] buf = new byte[1024]; byte[] contentBuf = new byte[1024 * 1024]; start = DateTime.UtcNow; foreach (var dll in dllFiles) { using (var dllStream = File.OpenRead(dll)) { var pe = new PEFile(); var reader = new BinaryStreamReader(dllStream, buf); pe.ReadFrom(reader); while (reader.Position < dllStream.Length) { reader.ReadBytes(contentBuf, 0, (int)Math.Min(contentBuf.Length, dllStream.Length - reader.Position)); } } } TimeSpan headersAndContent = DateTime.UtcNow - start; start = DateTime.UtcNow; foreach (var dll in dllFiles) { System.Reflection.Assembly.Load(File.ReadAllBytes(dll)); } TimeSpan reflectionLoad = DateTime.UtcNow - start; Console.WriteLine( dllFiles.Length + " dlls\t" + "Headers only: " + headersOnly.TotalSeconds.ToString("#0.000") + " sec." + " " + "Headers and content: " + headersAndContent.TotalSeconds.ToString("#0.000") + " sec." + " " + "Reflection: " + reflectionLoad.TotalSeconds.ToString("#0.000") + " sec." + ""); }
static void Main(string[] args) { // open the MIDI file using (var br = new BinaryStreamReader(@"..\..\GORILLAZ_-_Feel_Good_Inc.mid")) { // check for the FourCC code at the beginning of the file if ("MThd" != br.ReadFixedString(4, Encoding.ASCII)) { throw new ApplicationException("The file is not a MIDI file"); } // read a big-endian 32-bit integer length from the the file var len = br.ReadInt32BE(); // now read that many bytes into a buffer var ba = br.ReadBytes(len); // create a new binary reader over ba // not necessary, but for illustrative purposes: int trackCount; using (var br2 = new BinaryCollectionReader(ba)) { // read the file type as a big-endian 16-bit short Console.WriteLine("MIDI File Type: " + br2.ReadInt16BE().ToString()); // read the track count as a big-endian 16-bit short Console.WriteLine("MIDI Track Count: " + (trackCount = br2.ReadInt16BE()).ToString()); // read the timebase as a big-endian 16-bit short Console.WriteLine("MIDI TimeBase: " + br2.ReadInt16BE().ToString()); } var tracksRead = 0; while (tracksRead < trackCount) { var name = br.ReadFixedString(4, Encoding.ASCII); len = br.ReadInt32BE(); var data = br.ReadBytes(len); if ("MTrk" == name) { Console.WriteLine("Track #" + tracksRead.ToString() + " is " + len + " bytes."); ++tracksRead; } } } }
/// <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(ref BinaryStreamReader 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 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(ref BinaryStreamReader reader, int count) { ulong position = reader.Offset; uint rva = reader.Rva; byte[] 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, 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(); }
void ReadDosHeader(BinaryStreamReader reader) { if (this.DosHeader == null) { this.DosHeader = new DosHeader(); } var signature = (MZSignature)reader.ReadInt16(); if (signature != MZSignature.MZ) { throw new BadImageFormatException("MZ signature expected, " + ((ushort)signature).ToString("X4") + "h found."); } this.DosHeader.cblp = reader.ReadUInt16(); this.DosHeader.cp = reader.ReadUInt16(); this.DosHeader.crlc = reader.ReadUInt16(); this.DosHeader.cparhdr = reader.ReadUInt16(); this.DosHeader.minalloc = reader.ReadUInt16(); this.DosHeader.maxalloc = reader.ReadUInt16(); this.DosHeader.ss = reader.ReadUInt16(); this.DosHeader.sp = reader.ReadUInt16(); this.DosHeader.csum = reader.ReadUInt16(); this.DosHeader.ip = reader.ReadUInt16(); this.DosHeader.cs = reader.ReadUInt16(); this.DosHeader.lfarlc = reader.ReadUInt16(); this.DosHeader.ovno = reader.ReadUInt16(); this.DosHeader.res1 = reader.ReadUInt64(); this.DosHeader.oemid = reader.ReadUInt16(); this.DosHeader.oeminfo = reader.ReadUInt16(); this.DosHeader.ReservedNumber0 = reader.ReadUInt32(); this.DosHeader.ReservedNumber1 = reader.ReadUInt32(); this.DosHeader.ReservedNumber2 = reader.ReadUInt32(); this.DosHeader.ReservedNumber3 = reader.ReadUInt32(); this.DosHeader.ReservedNumber4 = reader.ReadUInt32(); this.DosHeader.lfanew = reader.ReadUInt32(); if (this.DosHeader.lfanew > DosHeader.Size) { this.DosStub = new byte[this.DosHeader.lfanew - DosHeader.Size]; reader.ReadBytes(this.DosStub, 0, this.DosStub.Length); } }
/// <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, ref BinaryStreamReader 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 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(ref BinaryStreamReader reader) { // Read BLOBHEADER ReadBlobHeader(ref 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); }
static void Main(string[] args) { var pe = new PEFile(); var stream = new MemoryStream(Properties.Resources.console_anycpu); var reader = new BinaryStreamReader(stream, new byte[1024]); pe.ReadFrom(reader); uint lowestPointerToRawData = uint.MaxValue; uint lowestVirtualAddress = uint.MaxValue; uint highestVirtualAddress = uint.MinValue; foreach (var s in pe.SectionHeaders) { lowestPointerToRawData = Math.Min(lowestPointerToRawData, s.PointerToRawData); lowestVirtualAddress = Math.Min(lowestVirtualAddress, s.VirtualAddress); highestVirtualAddress = Math.Max(highestVirtualAddress, s.VirtualAddress + (uint)s.VirtualSize); } byte[] allSectionContent = new byte[highestVirtualAddress - lowestVirtualAddress]; foreach (var s in pe.SectionHeaders) { reader.Position = s.PointerToRawData; reader.ReadBytes(allSectionContent, (int)(s.VirtualAddress - lowestVirtualAddress), (int)s.VirtualSize); } pe.PEHeader.NumberOfSections = 1; var singleSection = pe.SectionHeaders[0]; singleSection.VirtualSize = (uint)allSectionContent.Length; pe.SectionHeaders = new[] { singleSection }; using (var peFileStream = File.Create("console.anycpu.insane.exe")) { var writer = new BinaryStreamWriter(peFileStream); pe.WriteTo(writer); writer.Position = lowestPointerToRawData; writer.WriteBytes(allSectionContent, 0, allSectionContent.Length); } }
private static KeyValuePair <string, string> ReadEntry(ref BinaryStreamReader reader) { ulong start = reader.Offset; // Read header. var header = VersionTableEntryHeader.FromReader(ref 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.Offset = 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="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 /// tiny format.</exception> public new static CilRawTinyMethodBody FromReader(IErrorListener errorListener, ref BinaryStreamReader reader) { ulong fileOffset = reader.Offset; uint rva = reader.Rva; var flag = (CilMethodBodyAttributes)reader.ReadByte(); if ((flag & CilMethodBodyAttributes.Tiny) != CilMethodBodyAttributes.Tiny) { errorListener.BadImage("Invalid tiny CIL method body header."); return(null); } 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(ref BinaryStreamReader reader) { // Read BLOBHEADER ReadBlobHeader(ref 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> /// 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(ref BinaryStreamReader reader) { ulong offset = reader.Offset; uint rva = reader.Rva; var nameBytes = new byte[8]; reader.ReadBytes(nameBytes, 0, nameBytes.Length); return(new SectionHeader(Encoding.UTF8.GetString(nameBytes).Replace("\0", ""), 0) { Offset = offset, Rva = rva, 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() }); }
public ISymbolReader GetSymbolReader(ModuleDefinition module, Stream symbolStream) { if (module.Image.HasDebugTables()) { return(null); } if (module.HasDebugHeader) { var header = module.GetDebugHeader(); var entry = header.GetEmbeddedPortablePdbEntry(); if (entry != null) { return(new EmbeddedPortablePdbReaderProvider().GetSymbolReader(module, "")); } } Mixin.CheckStream(symbolStream); Mixin.CheckReadSeek(symbolStream); var position = symbolStream.Position; const int portablePdbHeader = 0x424a5342; var reader = new BinaryStreamReader(symbolStream); var intHeader = reader.ReadInt32(); symbolStream.Position = position; if (intHeader == portablePdbHeader) { return(new PortablePdbReaderProvider().GetSymbolReader(module, symbolStream)); } const string nativePdbHeader = "Microsoft C/C++ MSF 7.00"; var bytesHeader = reader.ReadBytes(nativePdbHeader.Length); symbolStream.Position = position; var isNativePdb = true; for (var i = 0; i < bytesHeader.Length; i++) { if (bytesHeader [i] != (byte)nativePdbHeader [i]) { isNativePdb = false; break; } } if (isNativePdb) { try { return(SymbolProvider.GetReaderProvider(SymbolKind.NativePdb).GetSymbolReader(module, symbolStream)); } catch (Exception) { // We might not include support for native pdbs. } } const long mdbHeader = 0x45e82623fd7fa614; var longHeader = reader.ReadInt64(); symbolStream.Position = position; if (longHeader == mdbHeader) { try { return(SymbolProvider.GetReaderProvider(SymbolKind.Mdb).GetSymbolReader(module, symbolStream)); } catch (Exception) { // We might not include support for mdbs. } } if (throw_if_no_symbol) { throw new SymbolsNotFoundException(string.Format("No symbols found in stream")); } return(null); }
static byte[] ReadBinaryHeap(BinaryStreamReader reader, uint size) { byte[] heapBytes = new byte[size]; reader.ReadBytes(heapBytes, 0, (int)size); return(heapBytes); }