Пример #1
0
        /// <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);
        }