Exemplo n.º 1
0
        public static DOSHeader Parse(BinaryReader reader)
        {
            var signature = reader.ReadUInt16();

            if (DOSSignature != signature)
            {
                throw new Exception("Invalid DOS header signature");
            }

            var header = new DOSHeader
            {
                BytesOnLastPage       = reader.ReadUInt16(),
                PageCount             = reader.ReadUInt16(),
                RelocationCount       = reader.ReadUInt16(),
                HeaderSize            = reader.ReadUInt16(),
                MinExtraParagraphs    = reader.ReadUInt16(),
                MaxExtraParagraphs    = reader.ReadUInt16(),
                InitialSS             = reader.ReadUInt16(),
                InitialSP             = reader.ReadUInt16(),
                Checksum              = reader.ReadUInt16(),
                InitialIP             = reader.ReadUInt16(),
                InitialCS             = reader.ReadUInt16(),
                RelocationTableOffset = reader.ReadUInt16(),
                OverlayNumber         = reader.ReadUInt16()
            };

            // reserved words
            for (var i = 0; i < 4; i++)
            {
                reader.ReadUInt16();
            }

            header.OemID   = reader.ReadUInt16();
            header.OemInfo = reader.ReadUInt16();

            // reserved words
            for (var i = 0; i < 10; i++)
            {
                reader.ReadUInt16();
            }

            header.CoffHeaderOffset = reader.ReadUInt32();

            return(header);
        }
Exemplo n.º 2
0
        public void WritePortableExecutable(BinaryWriter writer)
        {
            writer.BaseStream.Seek(0, SeekOrigin.Begin);
            DOSHeader.Write(writer);
            writer.Write(_dosStubBytes);
            COFFHeader.Write(writer);
            PEHeaderOffset = (uint)writer.BaseStream.Position;
            PEHeader.Write(writer);
            for (var i = 0; i < COFFHeader.NumberOfSections; i++)
            {
                SectionHeaders[i].Write(writer);
            }

            writer.Write(_filler);
            for (var i = 0; i < COFFHeader.NumberOfSections; i++)
            {
                writer.Write(Sections[i]);
            }

            writer.Write(_remainingBytes);

            // Write Import Directory:
            var importDirectoryEntry = PEHeader.DataDirectories[(int)DataDirectoryName.Import];

            if (importDirectoryEntry.VirtualAddress > 0)
            {
                var importDirectoryFileOffset = GetOffsetFromRVA(importDirectoryEntry.VirtualAddress);
                writer.Seek((int)importDirectoryFileOffset, SeekOrigin.Begin);
                ImportDirectory.Write(writer);
            }

            // Update PE checksum:
            writer.Seek(0, SeekOrigin.Begin);
            var fileBytes = new byte[writer.BaseStream.Length];

            writer.BaseStream.Read(fileBytes, 0, (int)writer.BaseStream.Length);
            var checksumOffset = PEHeaderOffset + PEHeader.ChecksumRelativeAddress;
            var checksum       = PortableExecutableUtils.CalculcateChecksum(fileBytes, checksumOffset);

            writer.Seek((int)checksumOffset, SeekOrigin.Begin);
            writer.Write(checksum);
            writer.Flush();
        }
Exemplo n.º 3
0
        public void Parse(BinaryReader reader)
        {
            DOSHeader = DOSHeader.Parse(reader);
            var dosStubSize = (int)(DOSHeader.CoffHeaderOffset - reader.BaseStream.Position);

            _dosStubBytes  = reader.ReadBytes(dosStubSize);
            COFFHeader     = COFFHeader.Parse(reader);
            PEHeaderOffset = (uint)reader.BaseStream.Position;
            PEHeader       = PEHeader.Parse(reader);

            for (var i = 0; i < COFFHeader.NumberOfSections; i++)
            {
                SectionHeaders.Add(PESectionHeader.Parse(reader));
            }

            var fillerSize = (int)(SectionHeaders[0].PointerToRawData - reader.BaseStream.Position);

            _filler = reader.ReadBytes(fillerSize);

            for (var i = 0; i < COFFHeader.NumberOfSections; i++)
            {
                var sectionBytes = reader.ReadBytes((int)SectionHeaders[i].SizeOfRawData);
                Sections.Add(sectionBytes);
            }

            var remainingByteCount = (int)(reader.BaseStream.Length - reader.BaseStream.Position);

            _remainingBytes = reader.ReadBytes(remainingByteCount);
            // file ends here

            // Parse Import Directory:
            var importDirectoryEntry = PEHeader.DataDirectories[(int)DataDirectoryName.Import];

            if (importDirectoryEntry.VirtualAddress > 0)
            {
                var importDirectoryFileOffset = GetOffsetFromRVA(importDirectoryEntry.VirtualAddress);
                reader.BaseStream.Seek(importDirectoryFileOffset, SeekOrigin.Begin);
                ImportDirectory = ImportDirectory.Parse(reader);
            }
        }