internal override IEnumerable <Element> GetElements()
        {
            // ****************************************************************

            List <ExportFunction> functions = new List <ExportFunction>(m_functions.Values);

            functions.Sort();

            ElementCollection content           = new ElementCollection();
            ElementCollection header            = content.ElementCollection();
            ElementCollection functionAddresses = content.ElementCollection();
            ElementCollection functionNames     = content.ElementCollection();
            ElementCollection functionOrdinals  = content.ElementCollection();
            ElementCollection names             = content.ElementCollection();

            header.UInt32(0);                                    // Export flags
            header.UInt32(0);                                    // date
            header.UInt16(0);                                    // major version
            header.UInt16(0);                                    // minor version
            header.RelativeMemoryAddress32(m_moduleNameElement); // module name
            header.UInt32(1);                                    // ordinal base

            header.UInt32((UInt32)functions.Count);              // address table entries
            header.UInt32((UInt32)functions.Count);              // number of name pointers
            header.RelativeMemoryAddress32(functionAddresses);   // function addresses
            header.RelativeMemoryAddress32(functionNames);       // function names
            header.RelativeMemoryAddress32(functionOrdinals);    // function ordinals

            // Module name
            names.Elements.Add(m_moduleNameElement);

            for (int i = 0; i < functions.Count; i++)
            {
                ExportFunction function = functions[i];

                functionAddresses.RelativeMemoryAddress32(function.Function);
                functionNames.RelativeMemoryAddress32(function.NameElement);
                functionOrdinals.UInt16((UInt16)i);

                names.Elements.Add(function.NameElement);
            }

            return(content.Elements);
        }
Esempio n. 2
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);
        }