Exemple #1
0
        /// <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();
        }