/// <summary> /// Assemble the image, and write it to the given BinaryWriter /// </summary> /// <param name="writer"Writer to write the image to></param> public void Assemble(BinaryWriter writer) { uint now = (uint)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; ElementCollection image = new ElementCollection(); ElementCollection headers = image.ElementCollection(); ElementCollection headersDos = headers.ElementCollection(); ElementCollection headersNt = headers.ElementCollection(); ElementCollection headersNtSignature = headersNt.ElementCollection(); ElementCollection headersNtFile = headersNt.ElementCollection(); ElementCollection headersNtOptional = headersNt.ElementCollection(); ElementCollection headersSections = headers.ElementCollection(); ElementCollection sections = image.ElementCollection(); // IMAGE > HEADERS > DOS headersDos.ByteArray(s_dosHeader); headersDos.FileAddress32(headersNt); headersDos.ByteArray(s_dosStub); headersDos.Alignment(8, 0); // IMAGE > HEADERS > NT > SIGNATURE headersNtSignature.UInt32(c_signature); // IMAGE > HEADERS > NT > FILE headersNtFile.UInt16(GetMachine()); // Machine headersNtFile.UInt16((UInt16)m_sections.Count); // NumberOfSection headersNtFile.UInt32(now); // TimeDateStamp headersNtFile.UInt32(0); // PointerToSymbolTable headersNtFile.UInt32(0); // NumberOfSymbols headersNtFile.FileSize16(headersNtOptional); // SizeOfOptionalHeader headersNtFile.UInt16(0x010F); // Characteristics // IMAGE > HEADERS > NT > OPTIONAL headersNtOptional.UInt16(GetMagic()); headersNtOptional.UInt8(0); // MajorLinkerVersion headersNtOptional.UInt8(0); // MinorLinkerVersion headersNtOptional.Elements.Add(new SizeOfCodeSectionsElement(m_sections)); // SizeOfCode headersNtOptional.Elements.Add(new SizeOfInitializedDataSectionsElement(m_sections)); // SizeOfInitializedData headersNtOptional.Elements.Add(new SizeOfUninitializedDataSectionsElement(m_sections)); // SizeOfUninitializedData headersNtOptional.RelativeMemoryAddress32(m_entryPoint); // AddressOfEntryPoint headersNtOptional.Elements.Add(new BaseOfCodeSectionsElement(m_sections)); // BaseOfCode if (IsBaseOfDataRequired()) { headersNtOptional.Elements.Add(new BaseOfInitializedDataSectionsElement(m_sections)); // BaseOfData } headersNtOptional.UIntP(GetImageBase()); // ImageBase headersNtOptional.UInt32(m_sectionAlignment); // SectionAlignment headersNtOptional.UInt32(m_fileAlignment); // FileAlignment headersNtOptional.UInt16(0); // MajorOperatingSystemVersion headersNtOptional.UInt16(0); // MinorOperatingSystemVersion headersNtOptional.UInt16(0); // MajorImageVersion headersNtOptional.UInt16(0); // MinorImageVersion headersNtOptional.UInt16((UInt16)m_subsystem.Major); // MajorSubsystemVersion headersNtOptional.UInt16((UInt16)m_subsystem.Minor); // MinorSubsystemVersion headersNtOptional.UInt32(0); // Win32VersionValue headersNtOptional.MemorySize32(image); // SizeOfImage headersNtOptional.FileSize32(headers); // SizeOfHeaders headersNtOptional.UInt32(0); // CheckSum headersNtOptional.UInt16((UInt16)m_subsystem.Id); // Subsystem headersNtOptional.UInt16(0x0400); // DllCharacteristics headersNtOptional.UIntP(m_sizeOfStackReserve); // SizeOfStackReserve headersNtOptional.UIntP(m_sizeOfStackCommit); // SizeOfStackCommit headersNtOptional.UIntP(m_sizeOfHeapReserve); // SizeOfHeapReserve headersNtOptional.UIntP(m_sizeOfHeapCommit); // SizeOfHeapCommit headersNtOptional.UInt32(0x00000000); // LoaderFlags headersNtOptional.UInt32((UInt32)m_directoryElements.Length); // NumberOfRvaAndSizes foreach (Element directoryElement in m_directoryElements) { if (directoryElement == null) { headersNtOptional.UInt32(0); // VirtualAddress headersNtOptional.UInt32(0); // Size } else { headersNtOptional.RelativeMemoryAddress32(directoryElement); // VirtualAddress headersNtOptional.MemorySize32(directoryElement); // Size } } // IMAGE > HEADERS > SECTIONS foreach (ImageSection section in m_sections) { headersSections.FixedSizeString(section.Name, 8); headersSections.MemorySize32(section); // VirtualSize headersSections.RelativeMemoryAddress32(section); // VirtualAddress headersSections.FileSize32(section); // SizeOfRawData headersSections.FileAddress32(section); // PointerToRawData headersSections.UInt32(0); // PointerToRelocations headersSections.UInt32(0); // PointerToLinenumbers headersSections.UInt16(0); // NumberOfRelocations headersSections.UInt16(0); // NumberOfLinenumbers headersSections.UInt32(section.Type.Characteristics); // Characteristics } // IMAGE > SECTIONS foreach (ImageSection section in m_sections) { sections.Alignment(m_fileAlignment, m_sectionAlignment, 0); sections.Elements.Add(section); } (new Assembler()).Assemble(image, GetImageBase(), GetPointerSize(), writer); }