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
        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);
            }
        }
Beispiel #3
0
        public static PEHeader Parse(BinaryReader reader)
        {
            var signature = (PEHeaderType)reader.ReadUInt16();

            if (!Enum.IsDefined(typeof(PEHeaderType), signature))
            {
                throw new Exception("Invalid PE header signature");
            }

            var header = new PEHeader
            {
                Type                    = signature,
                LinkerVersion           = new Version(reader.ReadByte(), reader.ReadByte()),
                SizeOfCode              = reader.ReadUInt32(),
                SizeOfInitializedData   = reader.ReadUInt32(),
                SizeOfUninitializedData = reader.ReadUInt32(),
                AddressOfEntryPoint     = reader.ReadUInt32(),
                BaseOfCode              = reader.ReadUInt32()
            };

            if (signature == PEHeaderType.PE64)
            {
                header.ImageBase = reader.ReadUInt64();
            }
            else
            {
                header.BaseOfData = reader.ReadUInt32();
                header.ImageBase  = reader.ReadUInt32();
            }

            header.SectionAlignment       = reader.ReadUInt32();
            header.FileAlignment          = reader.ReadUInt32();
            header.OperatingSystemVersion = new Version(reader.ReadUInt16(), reader.ReadUInt16());
            header.ImageVersion           = new Version(reader.ReadUInt16(), reader.ReadUInt16());
            header.SubsystemVersion       = new Version(reader.ReadUInt16(), reader.ReadUInt16());
            header.Win32VersionValue      = reader.ReadUInt32();
            header.SizeOfImage            = reader.ReadUInt32();
            header.SizeOfHeaders          = reader.ReadUInt32();
            header.Checksum           = reader.ReadUInt32();
            header.Subsystem          = (PESubsystem)reader.ReadUInt16();
            header.DllCharacteristics = (PEDllCharacteristics)reader.ReadUInt16();

            if (signature == PEHeaderType.PE64)
            {
                header.SizeOfStackReserve = reader.ReadUInt64();
                header.SizeOfStackCommit  = reader.ReadUInt64();
                header.SizeOfHeapReserve  = reader.ReadUInt64();
                header.SizeOfHeapCommit   = reader.ReadUInt64();
            }
            else
            {
                header.SizeOfStackReserve = reader.ReadUInt32();
                header.SizeOfStackCommit  = reader.ReadUInt32();
                header.SizeOfHeapReserve  = reader.ReadUInt32();
                header.SizeOfHeapCommit   = reader.ReadUInt32();
            }

            header.LoaderFlags = reader.ReadUInt32();

            header.DataDirectories = new PEDataDirectory[reader.ReadUInt32()];
            for (var i = 0; i < header.DataDirectories.Length; i++)
            {
                header.DataDirectories[i] = PEDataDirectory.Parse(reader);
            }

            return(header);
        }