Beispiel #1
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();
        }
Beispiel #2
0
        // ReSharper restore MemberCanBePrivate.Global

        public static COFFHeader Parse(BinaryReader reader)
        {
            var signature = reader.ReadUInt32();

            if (NTSignature != signature)
            {
                throw new Exception("Invalid COFF header signature");
            }
            var header = new COFFHeader
            {
                Machine              = (COFFMachine)reader.ReadUInt16(),
                NumberOfSections     = reader.ReadUInt16(),
                TimeDateStamp        = reader.ReadUInt32(),
                PointerToSymbolTable = reader.ReadUInt32(),
                NumberOfSymbols      = reader.ReadUInt32(),
                SizeOfOptionalHeader = reader.ReadUInt16(),
                Characteristics      = (CoffFlags)reader.ReadUInt16()
            };

            return(header);
        }
Beispiel #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);
            }
        }