Exemplo n.º 1
0
        public void Serialize(BlobBuilder builder, PEDirectoriesBuilder headers, out ContentId contentId)
        {
            var  serializedSections = SerializeSections();
            Blob stampFixup;

            WritePESignature(builder);
            WriteCoffHeader(builder, serializedSections, out stampFixup);
            WritePEHeader(builder, headers, serializedSections);
            WriteSectionHeaders(builder, serializedSections);
            builder.Align(FileAlignment);

            foreach (var section in serializedSections)
            {
                builder.LinkSuffix(section.Builder);
                builder.Align(FileAlignment);
            }

            contentId = IdProvider(builder);

            // patch timestamp in COFF header:
            var stampWriter = new BlobWriter(stampFixup);

            stampWriter.WriteBytes(contentId.Stamp);
            Debug.Assert(stampWriter.RemainingBytes == 0);
        }
Exemplo n.º 2
0
        public ManagedPEBuilder(
            PEHeaderBuilder header,
            TypeSystemMetadataSerializer metadataSerializer,
            BlobBuilder ilStream,
            BlobBuilder mappedFieldData,
            BlobBuilder managedResourceData,
            Action <BlobBuilder, SectionLocation> nativeResourceSectionSerializer, // opt
            int strongNameSignatureSize,
            MethodDefinitionHandle entryPoint,
            string pdbPathOpt,              // TODO: DebugTableBuilder
            ContentId nativePdbContentId,   // TODO: DebugTableBuilder
            ContentId portablePdbContentId, // TODO: DebugTableBuilder
            CorFlags corFlags,
            Func <IEnumerable <Blob>, ContentId> deterministicIdProvider = null)
            : base(header, deterministicIdProvider)
        {
            _metadataSerializer  = metadataSerializer;
            _ilStream            = ilStream;
            _mappedFieldData     = mappedFieldData;
            _managedResourceData = managedResourceData;
            _nativeResourceSectionSerializerOpt = nativeResourceSectionSerializer;
            _strongNameSignatureSize            = strongNameSignatureSize;
            _entryPoint           = entryPoint;
            _pdbPathOpt           = pdbPathOpt;
            _nativePdbContentId   = nativePdbContentId;
            _portablePdbContentId = portablePdbContentId;
            _corFlags             = corFlags;

            _peDirectoriesBuilder = new PEDirectoriesBuilder();
        }
Exemplo n.º 3
0
        public ManagedPEBuilder(
            PEHeaderBuilder header,
            MetadataRootBuilder metadataRootBuilder,
            BlobBuilder ilStream,
            BlobBuilder mappedFieldData = null,
            BlobBuilder managedResources = null,
            ResourceSectionBuilder nativeResources = null,
            DebugDirectoryBuilder debugDirectoryBuilder = null,
            int strongNameSignatureSize = DefaultStrongNameSignatureSize,
            MethodDefinitionHandle entryPoint = default(MethodDefinitionHandle),
            CorFlags flags = CorFlags.ILOnly,
            Func<IEnumerable<Blob>, BlobContentId> deterministicIdProvider = null)
            : base(header, deterministicIdProvider)
        {
            if (header == null)
            {
                Throw.ArgumentNull(nameof(header));
            }

            if (metadataRootBuilder == null)
            {
                Throw.ArgumentNull(nameof(metadataRootBuilder));
            }

            if (ilStream == null)
            {
                Throw.ArgumentNull(nameof(ilStream));
            }

            if (strongNameSignatureSize < 0)
            {
                Throw.ArgumentOutOfRange(nameof(strongNameSignatureSize));
            }

            _metadataRootBuilder = metadataRootBuilder;
            _ilStream = ilStream;
            _mappedFieldDataOpt = mappedFieldData;
            _managedResourcesOpt = managedResources;
            _nativeResourcesOpt = nativeResources;
            _strongNameSignatureSize = strongNameSignatureSize;
            _entryPointOpt = entryPoint;
            _debugDirectoryBuilderOpt = debugDirectoryBuilder ?? CreateDefaultDebugDirectoryBuilder();
            _corFlags = flags;

            _peDirectoriesBuilder = new PEDirectoriesBuilder();
        }
Exemplo n.º 4
0
        public ManagedPEBuilder(
            PEHeaderBuilder header,
            MetadataRootBuilder metadataRootBuilder,
            BlobBuilder ilStream,
            BlobBuilder mappedFieldData                 = null,
            BlobBuilder managedResources                = null,
            ResourceSectionBuilder nativeResources      = null,
            DebugDirectoryBuilder debugDirectoryBuilder = null,
            int strongNameSignatureSize                 = DefaultStrongNameSignatureSize,
            MethodDefinitionHandle entryPoint           = default(MethodDefinitionHandle),
            CorFlags flags = CorFlags.ILOnly,
            Func <IEnumerable <Blob>, BlobContentId> deterministicIdProvider = null)
            : base(header, deterministicIdProvider)
        {
            if (header == null)
            {
                Throw.ArgumentNull(nameof(header));
            }

            if (metadataRootBuilder == null)
            {
                Throw.ArgumentNull(nameof(metadataRootBuilder));
            }

            if (ilStream == null)
            {
                Throw.ArgumentNull(nameof(ilStream));
            }

            if (strongNameSignatureSize < 0)
            {
                Throw.ArgumentOutOfRange(nameof(strongNameSignatureSize));
            }

            _metadataRootBuilder      = metadataRootBuilder;
            _ilStream                 = ilStream;
            _mappedFieldDataOpt       = mappedFieldData;
            _managedResourcesOpt      = managedResources;
            _nativeResourcesOpt       = nativeResources;
            _strongNameSignatureSize  = strongNameSignatureSize;
            _entryPointOpt            = entryPoint;
            _debugDirectoryBuilderOpt = debugDirectoryBuilder ?? CreateDefaultDebugDirectoryBuilder();
            _corFlags                 = flags;

            _peDirectoriesBuilder = new PEDirectoriesBuilder();
        }
Exemplo n.º 5
0
        private void WritePEHeader(BlobBuilder builder, PEDirectoriesBuilder directories, ImmutableArray <SerializedSection> sections)
        {
            builder.WriteUInt16((ushort)(Header.Is32Bit ? PEMagic.PE32 : PEMagic.PE32Plus));
            builder.WriteByte(Header.MajorLinkerVersion);
            builder.WriteByte(Header.MinorLinkerVersion);

            // SizeOfCode:
            builder.WriteUInt32((uint)SumRawDataSizes(sections, SectionCharacteristics.ContainsCode));

            // SizeOfInitializedData:
            builder.WriteUInt32((uint)SumRawDataSizes(sections, SectionCharacteristics.ContainsInitializedData));

            // SizeOfUninitializedData:
            builder.WriteUInt32((uint)SumRawDataSizes(sections, SectionCharacteristics.ContainsUninitializedData));

            // AddressOfEntryPoint:
            builder.WriteUInt32((uint)directories.AddressOfEntryPoint);

            // BaseOfCode:
            int codeSectionIndex = IndexOfSection(sections, SectionCharacteristics.ContainsCode);

            builder.WriteUInt32((uint)(codeSectionIndex != -1 ? sections[codeSectionIndex].RelativeVirtualAddress : 0));

            if (Header.Is32Bit)
            {
                // BaseOfData:
                int dataSectionIndex = IndexOfSection(sections, SectionCharacteristics.ContainsInitializedData);
                builder.WriteUInt32((uint)(dataSectionIndex != -1 ? sections[dataSectionIndex].RelativeVirtualAddress : 0));

                builder.WriteUInt32((uint)Header.ImageBase);
            }
            else
            {
                builder.WriteUInt64(Header.ImageBase);
            }

            // NT additional fields:
            builder.WriteUInt32((uint)Header.SectionAlignment);
            builder.WriteUInt32((uint)Header.FileAlignment);
            builder.WriteUInt16(Header.MajorOperatingSystemVersion);
            builder.WriteUInt16(Header.MinorOperatingSystemVersion);
            builder.WriteUInt16(Header.MajorImageVersion);
            builder.WriteUInt16(Header.MinorImageVersion);
            builder.WriteUInt16(Header.MajorSubsystemVersion);
            builder.WriteUInt16(Header.MinorSubsystemVersion);

            // Win32VersionValue (reserved, should be 0)
            builder.WriteUInt32(0);

            // SizeOfImage:
            var lastSection = sections[sections.Length - 1];

            builder.WriteUInt32((uint)BitArithmetic.Align(lastSection.RelativeVirtualAddress + lastSection.VirtualSize, Header.SectionAlignment));

            // SizeOfHeaders:
            builder.WriteUInt32((uint)BitArithmetic.Align(Header.ComputeSizeOfPEHeaders(sections.Length), Header.FileAlignment));

            // Checksum:
            // Shall be zero for strong name signing.
            _lazyChecksum = builder.ReserveBytes(sizeof(uint));
            new BlobWriter(_lazyChecksum).WriteUInt32(0);

            builder.WriteUInt16((ushort)Header.Subsystem);
            builder.WriteUInt16((ushort)Header.DllCharacteristics);

            if (Header.Is32Bit)
            {
                builder.WriteUInt32((uint)Header.SizeOfStackReserve);
                builder.WriteUInt32((uint)Header.SizeOfStackCommit);
                builder.WriteUInt32((uint)Header.SizeOfHeapReserve);
                builder.WriteUInt32((uint)Header.SizeOfHeapCommit);
            }
            else
            {
                builder.WriteUInt64(Header.SizeOfStackReserve);
                builder.WriteUInt64(Header.SizeOfStackCommit);
                builder.WriteUInt64(Header.SizeOfHeapReserve);
                builder.WriteUInt64(Header.SizeOfHeapCommit);
            }

            // LoaderFlags
            builder.WriteUInt32(0);

            // The number of data-directory entries in the remainder of the header.
            builder.WriteUInt32(16);

            // directory entries:
            builder.WriteUInt32((uint)directories.ExportTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)directories.ExportTable.Size);
            builder.WriteUInt32((uint)directories.ImportTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)directories.ImportTable.Size);
            builder.WriteUInt32((uint)directories.ResourceTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)directories.ResourceTable.Size);
            builder.WriteUInt32((uint)directories.ExceptionTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)directories.ExceptionTable.Size);

            // Authenticode CertificateTable directory. Shall be zero before the PE is signed.
            builder.WriteUInt32(0);
            builder.WriteUInt32(0);

            builder.WriteUInt32((uint)directories.BaseRelocationTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)directories.BaseRelocationTable.Size);
            builder.WriteUInt32((uint)directories.DebugTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)directories.DebugTable.Size);
            builder.WriteUInt32((uint)directories.CopyrightTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)directories.CopyrightTable.Size);
            builder.WriteUInt32((uint)directories.GlobalPointerTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)directories.GlobalPointerTable.Size);
            builder.WriteUInt32((uint)directories.ThreadLocalStorageTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)directories.ThreadLocalStorageTable.Size);
            builder.WriteUInt32((uint)directories.LoadConfigTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)directories.LoadConfigTable.Size);
            builder.WriteUInt32((uint)directories.BoundImportTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)directories.BoundImportTable.Size);
            builder.WriteUInt32((uint)directories.ImportAddressTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)directories.ImportAddressTable.Size);
            builder.WriteUInt32((uint)directories.DelayImportTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)directories.DelayImportTable.Size);
            builder.WriteUInt32((uint)directories.CorHeaderTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)directories.CorHeaderTable.Size);

            // Reserved, should be 0
            builder.WriteUInt64(0);
        }
Exemplo n.º 6
0
        private void WritePEHeader(BlobBuilder builder, PEDirectoriesBuilder headers, ImmutableArray<SerializedSection> sections)
        {
            builder.WriteUInt16((ushort)(Is32Bit ? PEMagic.PE32 : PEMagic.PE32Plus));
            builder.WriteByte(MajorLinkerVersion);
            builder.WriteByte(MinorLinkerVersion);

            // SizeOfCode:
            builder.WriteUInt32((uint)SumRawDataSizes(sections, SectionCharacteristics.ContainsCode));

            // SizeOfInitializedData:
            builder.WriteUInt32((uint)SumRawDataSizes(sections, SectionCharacteristics.ContainsInitializedData));

            // SizeOfUninitializedData:
            builder.WriteUInt32((uint)SumRawDataSizes(sections, SectionCharacteristics.ContainsUninitializedData));

            // AddressOfEntryPoint:
            builder.WriteUInt32((uint)headers.AddressOfEntryPoint);

            // BaseOfCode:
            int codeSectionIndex = IndexOfSection(sections, SectionCharacteristics.ContainsCode);
            builder.WriteUInt32((uint)(codeSectionIndex != -1 ? sections[codeSectionIndex].RelativeVirtualAddress : 0));

            if (Is32Bit)
            {
                // BaseOfData:
                int dataSectionIndex = IndexOfSection(sections, SectionCharacteristics.ContainsInitializedData);
                builder.WriteUInt32((uint)(dataSectionIndex != -1 ? sections[dataSectionIndex].RelativeVirtualAddress : 0));

                builder.WriteUInt32((uint)ImageBase);
            }
            else
            {
                builder.WriteUInt64(ImageBase);
            }

            // NT additional fields:
            builder.WriteUInt32((uint)SectionAlignment);
            builder.WriteUInt32((uint)FileAlignment);
            builder.WriteUInt16(MajorOperatingSystemVersion);
            builder.WriteUInt16(MinorOperatingSystemVersion);
            builder.WriteUInt16(MajorImageVersion);
            builder.WriteUInt16(MinorImageVersion);
            builder.WriteUInt16(MajorSubsystemVersion);
            builder.WriteUInt16(MinorSubsystemVersion);

            // Win32VersionValue (reserved, should be 0)
            builder.WriteUInt32(0);

            // SizeOfImage:
            var lastSection = sections[sections.Length - 1];
            builder.WriteUInt32((uint)BitArithmeticUtilities.Align(lastSection.RelativeVirtualAddress + lastSection.VirtualSize, SectionAlignment));

            // SizeOfHeaders:
            builder.WriteUInt32((uint)BitArithmeticUtilities.Align(ComputeSizeOfPeHeaders(sections.Length, Is32Bit), FileAlignment));

            // Checksum (TODO: not supported):
            builder.WriteUInt32(0);

            builder.WriteUInt16((ushort)Subsystem);
            builder.WriteUInt16((ushort)DllCharacteristics);

            if (Is32Bit)
            {
                builder.WriteUInt32((uint)SizeOfStackReserve);
                builder.WriteUInt32((uint)SizeOfStackCommit);
                builder.WriteUInt32((uint)SizeOfHeapReserve);
                builder.WriteUInt32((uint)SizeOfHeapCommit);
            }
            else
            {
                builder.WriteUInt64(SizeOfStackReserve);
                builder.WriteUInt64(SizeOfStackCommit);
                builder.WriteUInt64(SizeOfHeapReserve);
                builder.WriteUInt64(SizeOfHeapCommit);
            }

            // LoaderFlags
            builder.WriteUInt32(0);

            // The number of data-directory entries in the remainder of the header.
            builder.WriteUInt32(16);

            // directory entries:
            builder.WriteUInt32((uint)headers.ExportTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)headers.ExportTable.Size);
            builder.WriteUInt32((uint)headers.ImportTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)headers.ImportTable.Size);
            builder.WriteUInt32((uint)headers.ResourceTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)headers.ResourceTable.Size);
            builder.WriteUInt32((uint)headers.ExceptionTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)headers.ExceptionTable.Size);
            builder.WriteUInt32((uint)headers.CertificateTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)headers.CertificateTable.Size);
            builder.WriteUInt32((uint)headers.BaseRelocationTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)headers.BaseRelocationTable.Size);
            builder.WriteUInt32((uint)headers.DebugTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)headers.DebugTable.Size);
            builder.WriteUInt32((uint)headers.CopyrightTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)headers.CopyrightTable.Size);
            builder.WriteUInt32((uint)headers.GlobalPointerTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)headers.GlobalPointerTable.Size);
            builder.WriteUInt32((uint)headers.ThreadLocalStorageTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)headers.ThreadLocalStorageTable.Size);
            builder.WriteUInt32((uint)headers.LoadConfigTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)headers.LoadConfigTable.Size);
            builder.WriteUInt32((uint)headers.BoundImportTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)headers.BoundImportTable.Size);
            builder.WriteUInt32((uint)headers.ImportAddressTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)headers.ImportAddressTable.Size);
            builder.WriteUInt32((uint)headers.DelayImportTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)headers.DelayImportTable.Size);
            builder.WriteUInt32((uint)headers.CorHeaderTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)headers.CorHeaderTable.Size);

            // Reserved, should be 0
            builder.WriteUInt64(0);
        }
Exemplo n.º 7
0
        public void Serialize(BlobBuilder builder, PEDirectoriesBuilder headers, out ContentId contentId)
        {
            var serializedSections = SerializeSections();
            Blob stampFixup;

            WritePESignature(builder);
            WriteCoffHeader(builder, serializedSections, out stampFixup);
            WritePEHeader(builder, headers, serializedSections);
            WriteSectionHeaders(builder, serializedSections);
            builder.Align(FileAlignment);

            foreach (var section in serializedSections)
            {
                builder.LinkSuffix(section.Builder);
                builder.Align(FileAlignment);
            }

            contentId = IdProvider(builder);

            // patch timestamp in COFF header:
            var stampWriter = new BlobWriter(stampFixup);
            stampWriter.WriteBytes(contentId.Stamp);
            Debug.Assert(stampWriter.RemainingBytes == 0);
        }
Exemplo n.º 8
0
        public static void AddManagedSections(
            this PEBuilder peBuilder,
            PEDirectoriesBuilder peDirectoriesBuilder,
            TypeSystemMetadataSerializer metadataSerializer,
            BlobBuilder ilStream,
            BlobBuilder mappedFieldData,
            BlobBuilder managedResourceData,
            Action<BlobBuilder, PESectionLocation> nativeResourceSectionSerializer, // opt
            int strongNameSignatureSize, // TODO
            MethodDefinitionHandle entryPoint,
            string pdbPathOpt, // TODO
            ContentId nativePdbContentId, // TODO
            ContentId portablePdbContentId, // TODO
            CorFlags corFlags)
        {
            int entryPointAddress = 0;

            // .text
            peBuilder.AddSection(".text", SectionCharacteristics.MemRead | SectionCharacteristics.MemExecute | SectionCharacteristics.ContainsCode, location =>
            {
                var sectionBuilder = new BlobBuilder();
                var metadataBuilder = new BlobBuilder();

                var metadataSizes = metadataSerializer.MetadataSizes;

                var textSection = new ManagedTextSection(
                    metadataSizes.MetadataSize,
                    ilStreamSize: ilStream.Count,
                    mappedFieldDataSize: mappedFieldData.Count,
                    resourceDataSize: managedResourceData.Count,
                    strongNameSignatureSize: strongNameSignatureSize,
                    imageCharacteristics: peBuilder.ImageCharacteristics,
                    machine: peBuilder.Machine,
                    pdbPathOpt: pdbPathOpt,
                    isDeterministic: peBuilder.IsDeterministic);

                int methodBodyStreamRva = location.RelativeVirtualAddress + textSection.OffsetToILStream;
                int mappedFieldDataStreamRva = location.RelativeVirtualAddress + textSection.CalculateOffsetToMappedFieldDataStream();
                metadataSerializer.SerializeMetadata(metadataBuilder, methodBodyStreamRva, mappedFieldDataStreamRva);

                BlobBuilder debugTableBuilderOpt;
                if (pdbPathOpt != null || peBuilder.IsDeterministic)
                {
                    debugTableBuilderOpt = new BlobBuilder();
                    textSection.WriteDebugTable(debugTableBuilderOpt, location, nativePdbContentId, portablePdbContentId);
                }
                else
                {
                    debugTableBuilderOpt = null;
                }

                entryPointAddress = textSection.GetEntryPointAddress(location.RelativeVirtualAddress);

                textSection.Serialize(
                    sectionBuilder,
                    location.RelativeVirtualAddress,
                    entryPoint.IsNil ? 0 : MetadataTokens.GetToken(entryPoint),
                    corFlags,
                    peBuilder.ImageBase,
                    metadataBuilder,
                    ilStream,
                    mappedFieldData,
                    managedResourceData,
                    debugTableBuilderOpt);

                peDirectoriesBuilder.AddressOfEntryPoint = entryPointAddress;
                peDirectoriesBuilder.DebugTable = textSection.GetDebugDirectoryEntry(location.RelativeVirtualAddress);
                peDirectoriesBuilder.ImportAddressTable = textSection.GetImportAddressTableDirectoryEntry(location.RelativeVirtualAddress);
                peDirectoriesBuilder.ImportTable = textSection.GetImportTableDirectoryEntry(location.RelativeVirtualAddress);
                peDirectoriesBuilder.CorHeaderTable = textSection.GetCorHeaderDirectoryEntry(location.RelativeVirtualAddress);

                return sectionBuilder;
            });

            // .rsrc
            if (nativeResourceSectionSerializer != null)
            {
                peBuilder.AddSection(".rsrc", SectionCharacteristics.MemRead | SectionCharacteristics.ContainsInitializedData, location => 
                {
                    var sectionBuilder = new BlobBuilder();
                    nativeResourceSectionSerializer(sectionBuilder, location);
                    peDirectoriesBuilder.ResourceTable = new DirectoryEntry(location.RelativeVirtualAddress, sectionBuilder.Count);
                    return sectionBuilder;
                });
            }

            // .reloc
            if (peBuilder.Machine == Machine.I386 || peBuilder.Machine == 0)
            {
                peBuilder.AddSection(".reloc", SectionCharacteristics.MemRead | SectionCharacteristics.MemDiscardable | SectionCharacteristics.ContainsInitializedData, location =>
                {
                    var sectionBuilder = new BlobBuilder();
                    WriteRelocSection(sectionBuilder, peBuilder.Machine, entryPointAddress);

                    peDirectoriesBuilder.BaseRelocationTable = new DirectoryEntry(location.RelativeVirtualAddress, sectionBuilder.Count);
                    return sectionBuilder;
                });
            }
        }
Exemplo n.º 9
0
        private void WritePEHeader(BlobBuilder builder, PEDirectoriesBuilder directories, ImmutableArray<SerializedSection> sections)
        {
            builder.WriteUInt16((ushort)(Header.Is32Bit ? PEMagic.PE32 : PEMagic.PE32Plus));
            builder.WriteByte(Header.MajorLinkerVersion);
            builder.WriteByte(Header.MinorLinkerVersion);

            // SizeOfCode:
            builder.WriteUInt32((uint)SumRawDataSizes(sections, SectionCharacteristics.ContainsCode));

            // SizeOfInitializedData:
            builder.WriteUInt32((uint)SumRawDataSizes(sections, SectionCharacteristics.ContainsInitializedData));

            // SizeOfUninitializedData:
            builder.WriteUInt32((uint)SumRawDataSizes(sections, SectionCharacteristics.ContainsUninitializedData));

            // AddressOfEntryPoint:
            builder.WriteUInt32((uint)directories.AddressOfEntryPoint);

            // BaseOfCode:
            int codeSectionIndex = IndexOfSection(sections, SectionCharacteristics.ContainsCode);
            builder.WriteUInt32((uint)(codeSectionIndex != -1 ? sections[codeSectionIndex].RelativeVirtualAddress : 0));

            if (Header.Is32Bit)
            {
                // BaseOfData:
                int dataSectionIndex = IndexOfSection(sections, SectionCharacteristics.ContainsInitializedData);
                builder.WriteUInt32((uint)(dataSectionIndex != -1 ? sections[dataSectionIndex].RelativeVirtualAddress : 0));

                builder.WriteUInt32((uint)Header.ImageBase);
            }
            else
            {
                builder.WriteUInt64(Header.ImageBase);
            }

            // NT additional fields:
            builder.WriteUInt32((uint)Header.SectionAlignment);
            builder.WriteUInt32((uint)Header.FileAlignment);
            builder.WriteUInt16(Header.MajorOperatingSystemVersion);
            builder.WriteUInt16(Header.MinorOperatingSystemVersion);
            builder.WriteUInt16(Header.MajorImageVersion);
            builder.WriteUInt16(Header.MinorImageVersion);
            builder.WriteUInt16(Header.MajorSubsystemVersion);
            builder.WriteUInt16(Header.MinorSubsystemVersion);
                                
            // Win32VersionValue (reserved, should be 0)
            builder.WriteUInt32(0);

            // SizeOfImage:
            var lastSection = sections[sections.Length - 1];
            builder.WriteUInt32((uint)BitArithmetic.Align(lastSection.RelativeVirtualAddress + lastSection.VirtualSize, Header.SectionAlignment));

            // SizeOfHeaders:
            builder.WriteUInt32((uint)BitArithmetic.Align(Header.ComputeSizeOfPEHeaders(sections.Length), Header.FileAlignment));

            // Checksum:
            // Shall be zero for strong name signing. 
            _lazyChecksum = builder.ReserveBytes(sizeof(uint));
            new BlobWriter(_lazyChecksum).WriteUInt32(0);

            builder.WriteUInt16((ushort)Header.Subsystem);
            builder.WriteUInt16((ushort)Header.DllCharacteristics);

            if (Header.Is32Bit)
            {
                builder.WriteUInt32((uint)Header.SizeOfStackReserve);
                builder.WriteUInt32((uint)Header.SizeOfStackCommit);
                builder.WriteUInt32((uint)Header.SizeOfHeapReserve);
                builder.WriteUInt32((uint)Header.SizeOfHeapCommit);
            }
            else
            {
                builder.WriteUInt64(Header.SizeOfStackReserve);
                builder.WriteUInt64(Header.SizeOfStackCommit);
                builder.WriteUInt64(Header.SizeOfHeapReserve);
                builder.WriteUInt64(Header.SizeOfHeapCommit);
            }

            // LoaderFlags
            builder.WriteUInt32(0);

            // The number of data-directory entries in the remainder of the header.
            builder.WriteUInt32(16);

            // directory entries:
            builder.WriteUInt32((uint)directories.ExportTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)directories.ExportTable.Size);
            builder.WriteUInt32((uint)directories.ImportTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)directories.ImportTable.Size);
            builder.WriteUInt32((uint)directories.ResourceTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)directories.ResourceTable.Size);
            builder.WriteUInt32((uint)directories.ExceptionTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)directories.ExceptionTable.Size);

            // Authenticode CertificateTable directory. Shall be zero before the PE is signed.
            builder.WriteUInt32(0);
            builder.WriteUInt32(0);

            builder.WriteUInt32((uint)directories.BaseRelocationTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)directories.BaseRelocationTable.Size);
            builder.WriteUInt32((uint)directories.DebugTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)directories.DebugTable.Size);
            builder.WriteUInt32((uint)directories.CopyrightTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)directories.CopyrightTable.Size);
            builder.WriteUInt32((uint)directories.GlobalPointerTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)directories.GlobalPointerTable.Size);
            builder.WriteUInt32((uint)directories.ThreadLocalStorageTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)directories.ThreadLocalStorageTable.Size);
            builder.WriteUInt32((uint)directories.LoadConfigTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)directories.LoadConfigTable.Size);
            builder.WriteUInt32((uint)directories.BoundImportTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)directories.BoundImportTable.Size);
            builder.WriteUInt32((uint)directories.ImportAddressTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)directories.ImportAddressTable.Size);
            builder.WriteUInt32((uint)directories.DelayImportTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)directories.DelayImportTable.Size);
            builder.WriteUInt32((uint)directories.CorHeaderTable.RelativeVirtualAddress);
            builder.WriteUInt32((uint)directories.CorHeaderTable.Size);

            // Reserved, should be 0
            builder.WriteUInt64(0);
        }
Exemplo n.º 10
0
        public static void AddManagedSections(
            this PEBuilder peBuilder,
            PEDirectoriesBuilder peDirectoriesBuilder,
            TypeSystemMetadataSerializer metadataSerializer,
            BlobBuilder ilStream,
            BlobBuilder mappedFieldData,
            BlobBuilder managedResourceData,
            Action <BlobBuilder, PESectionLocation> nativeResourceSectionSerializer, // opt
            int strongNameSignatureSize,                                             // TODO
            MethodDefinitionHandle entryPoint,
            string pdbPathOpt,                                                       // TODO
            ContentId nativePdbContentId,                                            // TODO
            ContentId portablePdbContentId,                                          // TODO
            CorFlags corFlags)
        {
            int entryPointAddress = 0;

            // .text
            peBuilder.AddSection(".text", SectionCharacteristics.MemRead | SectionCharacteristics.MemExecute | SectionCharacteristics.ContainsCode, location =>
            {
                var sectionBuilder  = new BlobBuilder();
                var metadataBuilder = new BlobBuilder();

                var metadataSizes = metadataSerializer.MetadataSizes;

                var textSection = new ManagedTextSection(
                    metadataSizes.MetadataSize,
                    ilStreamSize: ilStream.Count,
                    mappedFieldDataSize: mappedFieldData.Count,
                    resourceDataSize: managedResourceData.Count,
                    strongNameSignatureSize: strongNameSignatureSize,
                    imageCharacteristics: peBuilder.ImageCharacteristics,
                    machine: peBuilder.Machine,
                    pdbPathOpt: pdbPathOpt,
                    isDeterministic: peBuilder.IsDeterministic);

                int methodBodyStreamRva      = location.RelativeVirtualAddress + textSection.OffsetToILStream;
                int mappedFieldDataStreamRva = location.RelativeVirtualAddress + textSection.CalculateOffsetToMappedFieldDataStream();
                metadataSerializer.SerializeMetadata(metadataBuilder, methodBodyStreamRva, mappedFieldDataStreamRva);

                BlobBuilder debugTableBuilderOpt;
                if (pdbPathOpt != null || peBuilder.IsDeterministic)
                {
                    debugTableBuilderOpt = new BlobBuilder();
                    textSection.WriteDebugTable(debugTableBuilderOpt, location, nativePdbContentId, portablePdbContentId);
                }
                else
                {
                    debugTableBuilderOpt = null;
                }

                entryPointAddress = textSection.GetEntryPointAddress(location.RelativeVirtualAddress);

                textSection.Serialize(
                    sectionBuilder,
                    location.RelativeVirtualAddress,
                    entryPoint.IsNil ? 0 : MetadataTokens.GetToken(entryPoint),
                    corFlags,
                    peBuilder.ImageBase,
                    metadataBuilder,
                    ilStream,
                    mappedFieldData,
                    managedResourceData,
                    debugTableBuilderOpt);

                peDirectoriesBuilder.AddressOfEntryPoint = entryPointAddress;
                peDirectoriesBuilder.DebugTable          = textSection.GetDebugDirectoryEntry(location.RelativeVirtualAddress);
                peDirectoriesBuilder.ImportAddressTable  = textSection.GetImportAddressTableDirectoryEntry(location.RelativeVirtualAddress);
                peDirectoriesBuilder.ImportTable         = textSection.GetImportTableDirectoryEntry(location.RelativeVirtualAddress);
                peDirectoriesBuilder.CorHeaderTable      = textSection.GetCorHeaderDirectoryEntry(location.RelativeVirtualAddress);

                return(sectionBuilder);
            });

            // .rsrc
            if (nativeResourceSectionSerializer != null)
            {
                peBuilder.AddSection(".rsrc", SectionCharacteristics.MemRead | SectionCharacteristics.ContainsInitializedData, location =>
                {
                    var sectionBuilder = new BlobBuilder();
                    nativeResourceSectionSerializer(sectionBuilder, location);
                    peDirectoriesBuilder.ResourceTable = new DirectoryEntry(location.RelativeVirtualAddress, sectionBuilder.Count);
                    return(sectionBuilder);
                });
            }

            // .reloc
            if (peBuilder.Machine == Machine.I386 || peBuilder.Machine == 0)
            {
                peBuilder.AddSection(".reloc", SectionCharacteristics.MemRead | SectionCharacteristics.MemDiscardable | SectionCharacteristics.ContainsInitializedData, location =>
                {
                    var sectionBuilder = new BlobBuilder();
                    WriteRelocSection(sectionBuilder, peBuilder.Machine, entryPointAddress);

                    peDirectoriesBuilder.BaseRelocationTable = new DirectoryEntry(location.RelativeVirtualAddress, sectionBuilder.Count);
                    return(sectionBuilder);
                });
            }
        }