예제 #1
0
        /// <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
            });
        }
예제 #2
0
 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);
     }
 }
예제 #3
0
        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);
        }
예제 #4
0
    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." +
            "");
    }
예제 #5
0
        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;
                    }
                }
            }
        }
예제 #6
0
        /// <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);
        }
예제 #7
0
        /// <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
            });
        }
예제 #8
0
        /// <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();
        }
예제 #9
0
        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);
            }
        }
예제 #10
0
        /// <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);
        }
예제 #11
0
        /// <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);
        }
예제 #12
0
        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);
            }
        }
예제 #13
0
        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));
        }
예제 #14
0
        /// <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);
        }
예제 #15
0
        /// <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);
        }
예제 #16
0
        /// <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()
            });
        }
예제 #17
0
        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);
        }
예제 #18
0
 static byte[] ReadBinaryHeap(BinaryStreamReader reader, uint size)
 {
     byte[] heapBytes = new byte[size];
     reader.ReadBytes(heapBytes, 0, (int)size);
     return(heapBytes);
 }