protected ImageSectionHeader PrepareNewSection(WindowsAssembly pE, out byte[] data) { ImageSectionHeader newSection = new ImageSectionHeader(); ImageSectionHeader previous = pE.SectionHeaders.Last(); newSection.PointerToRawData = previous.PointerToRawData + previous.SizeOfRawData; newSection.VirtualAddress = NextSectionRVA(pE.NtHeaders.OptionalHeader.SectionAlignment, previous); newSection.VirtualSize = AlignTo(pE.NtHeaders.OptionalHeader.SectionAlignment, (uint)generatedStub.Length); newSection.SizeOfRawData = AlignTo(pE.NtHeaders.OptionalHeader.FileAlignment, (uint)generatedStub.Length); newSection.Name = ".CIR"; newSection.Attributes = ImageSectionAttributes.MemoryExecute | ImageSectionAttributes.MemoryRead | ImageSectionAttributes.ContentCode; data = new byte[0x28]; newSection.Write(new WritingContext(null, new BinaryStreamWriter(new System.IO.MemoryStream(data)), null)); return(newSection); }
/// <summary> /// Writes the PE header. /// </summary> /// <param name="writer">The writer.</param> private void WritePEHeader(EndianAwareBinaryWriter writer) { // Write the PE signature and headers ntHeaders.Signature = ImageNtHeaders.PE_SIGNATURE; // Prepare the file header ntHeaders.FileHeader.Machine = ImageFileHeader.IMAGE_FILE_MACHINE_I386; ntHeaders.FileHeader.NumberOfSections = (ushort)CountNonEmptySections(); ntHeaders.FileHeader.TimeDateStamp = (uint)(DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds; ntHeaders.FileHeader.PointerToSymbolTable = 0; ntHeaders.FileHeader.NumberOfSymbols = 0; ntHeaders.FileHeader.SizeOfOptionalHeader = 0x00E0; ntHeaders.FileHeader.Characteristics = 0x010E; // Prepare the "optional" headers ntHeaders.OptionalHeader.Magic = ImageOptionalHeader.IMAGE_OPTIONAL_HEADER_MAGIC; ntHeaders.OptionalHeader.MajorLinkerVersion = 6; ntHeaders.OptionalHeader.MinorLinkerVersion = 0; ntHeaders.OptionalHeader.SizeOfCode = GetSection(SectionKind.Text).AlignedSize; ntHeaders.OptionalHeader.SizeOfInitializedData = GetSection(SectionKind.Data).AlignedSize + GetSection(SectionKind.ROData).AlignedSize; ntHeaders.OptionalHeader.SizeOfUninitializedData = GetSection(SectionKind.BSS).AlignedSize; ntHeaders.OptionalHeader.AddressOfEntryPoint = (uint)(EntryPoint.VirtualAddress - BaseAddress); ntHeaders.OptionalHeader.BaseOfCode = (uint)(GetSection(SectionKind.Text).VirtualAddress - BaseAddress); ulong sectionAddress = GetSection(SectionKind.Data).VirtualAddress; if (sectionAddress != 0) { ntHeaders.OptionalHeader.BaseOfData = (uint)(sectionAddress - BaseAddress); } ntHeaders.OptionalHeader.ImageBase = (uint)BaseAddress; ntHeaders.OptionalHeader.SectionAlignment = SectionAlignment; ntHeaders.OptionalHeader.FileAlignment = FILE_SECTION_ALIGNMENT; ntHeaders.OptionalHeader.MajorOperatingSystemVersion = 4; ntHeaders.OptionalHeader.MinorOperatingSystemVersion = 0; ntHeaders.OptionalHeader.MajorImageVersion = 0; ntHeaders.OptionalHeader.MinorImageVersion = 0; ntHeaders.OptionalHeader.MajorSubsystemVersion = 4; ntHeaders.OptionalHeader.MinorSubsystemVersion = 0; ntHeaders.OptionalHeader.Win32VersionValue = 0; ntHeaders.OptionalHeader.SizeOfImage = CalculateSizeOfImage(); ntHeaders.OptionalHeader.SizeOfHeaders = FILE_SECTION_ALIGNMENT; ntHeaders.OptionalHeader.CheckSum = 0; ntHeaders.OptionalHeader.Subsystem = 0x03; ntHeaders.OptionalHeader.DllCharacteristics = 0x0540; ntHeaders.OptionalHeader.SizeOfStackReserve = 0x100000; ntHeaders.OptionalHeader.SizeOfStackCommit = 0x1000; ntHeaders.OptionalHeader.SizeOfHeapReserve = 0x100000; ntHeaders.OptionalHeader.SizeOfHeapCommit = 0x1000; ntHeaders.OptionalHeader.LoaderFlags = 0; ntHeaders.OptionalHeader.NumberOfRvaAndSizes = ImageOptionalHeader.IMAGE_NUMBEROF_DIRECTORY_ENTRIES; ntHeaders.OptionalHeader.DataDirectory = new ImageDataDirectory[ImageOptionalHeader.IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; // Populate the CIL data directory ntHeaders.OptionalHeader.DataDirectory[14].VirtualAddress = 0; ntHeaders.OptionalHeader.DataDirectory[14].Size = 0; ntHeaders.Write(writer); foreach (var section in Sections) { if (section.Size == 0) { continue; } ImageSectionHeader image = new ImageSectionHeader(); image.Name = section.Name; image.VirtualSize = section.Size; image.VirtualAddress = (uint)(section.VirtualAddress - BaseAddress); image.SizeOfRawData = (section.SectionKind == SectionKind.BSS) ? 0 : section.Size; image.PointerToRawData = section.FileOffset; image.PointerToRelocations = 0; image.PointerToLinenumbers = 0; image.NumberOfRelocations = 0; image.NumberOfLinenumbers = 0; switch (section.SectionKind) { case SectionKind.BSS: image.Characteristics = 0x40000000 | 0x80000000 | 0x00000080; break; case SectionKind.Data: image.Characteristics = 0x40000000 | 0x80000000 | 0x00000040; break; case SectionKind.ROData: image.Characteristics = 0x40000000 | 0x00000040; break; case SectionKind.Text: image.Characteristics = 0x20000000 | 0x40000000 | 0x80000000 | 0x00000020; break; } image.Write(writer); } }