/// <summary> /// Add a new section to the PE file. /// </summary> /// <param name="name">Name of the section to add. At max. 8 characters.</param> /// <param name="size">Size in bytes of the new section.</param> /// <param name="characteristics">Section characteristics.</param> public void AddSection(string name, int size, ScnCharacteristicsType characteristics) { if (ImageNtHeaders is null) { throw new Exception("IMAGE_NT_HEADERS must not be null."); } if (ImageDosHeader is null) { throw new Exception("IMAGE_DOS_HEADER must not be null"); } uint getNewSizeOfImage() { var factor = size / (double)ImageNtHeaders.OptionalHeader.SectionAlignment; var additionalSize = (uint)Math.Ceiling(factor) * ImageNtHeaders !.OptionalHeader.SectionAlignment; return(ImageNtHeaders.OptionalHeader.SizeOfImage + additionalSize); } uint getNewSecHeaderOffset() { var sizeOfSection = 0x28; var x = (uint)ImageNtHeaders !.FileHeader.SizeOfOptionalHeader + 0x18; var startOfSectionHeader = ImageDosHeader.E_lfanew + x; return((uint)(startOfSectionHeader + (ImageNtHeaders.FileHeader.NumberOfSections * sizeOfSection))); } uint getNewSecVA() { var lastSec = ImageSectionHeaders.OrderByDescending(sh => sh.VirtualAddress).First(); var vaLastSecEnd = lastSec.VirtualAddress + lastSec.VirtualSize; var factor = vaLastSecEnd / (double)ImageNtHeaders.OptionalHeader.SectionAlignment; return((uint)(Math.Ceiling(factor) * ImageNtHeaders.OptionalHeader.SectionAlignment)); } // Append new section to end of file var paNewSec = RawFile.AppendBytes(new Byte[size]); // Add new entry in section table var newSection = new ImageSectionHeader(RawFile, getNewSecHeaderOffset(), ImageNtHeaders.OptionalHeader.ImageBase) { Name = name, VirtualSize = (uint)size, VirtualAddress = getNewSecVA(), SizeOfRawData = (uint)size, PointerToRawData = (uint)paNewSec, PointerToRelocations = 0, PointerToLinenumbers = 0, NumberOfRelocations = 0, NumberOfLinenumbers = 0, Characteristics = characteristics }; // Increase number of sections ImageNtHeaders.FileHeader.NumberOfSections = (ushort)(ImageNtHeaders.FileHeader.NumberOfSections + 1); // Adjust image size by image alignment ImageNtHeaders.OptionalHeader.SizeOfImage = getNewSizeOfImage(); // Reparse section headers _nativeStructureParsers.ReparseSectionHeaders(); }