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(); }
// 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); }
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); } }