コード例 #1
0
ファイル: PEBuilderTests.cs プロジェクト: ESgarbi/corefx
        private static void WritePEImage(
            Stream peStream, 
            MetadataBuilder metadataBuilder, 
            BlobBuilder ilBuilder, 
            MethodDefinitionHandle entryPointHandle,
            Blob mvidFixup = default(Blob),
            byte[] privateKeyOpt = null)
        {
            var peBuilder = new ManagedPEBuilder(
                entryPointHandle.IsNil ? PEHeaderBuilder.CreateLibraryHeader() : PEHeaderBuilder.CreateExecutableHeader(),
                new MetadataRootBuilder(metadataBuilder),
                ilBuilder,
                entryPoint: entryPointHandle,
                flags: CorFlags.ILOnly | (privateKeyOpt != null ? CorFlags.StrongNameSigned : 0),
                deterministicIdProvider: content => s_contentId);

            var peBlob = new BlobBuilder();

            var contentId = peBuilder.Serialize(peBlob);

            if (!mvidFixup.IsDefault)
            {
                new BlobWriter(mvidFixup).WriteGuid(contentId.Guid);
            }

            if (privateKeyOpt != null)
            {
                peBuilder.Sign(peBlob, content => SigningUtilities.CalculateRsaSignature(content, privateKeyOpt));
            }

            peBlob.WriteContentTo(peStream);
        }
コード例 #2
0
ファイル: PEBuilder.cs プロジェクト: ESgarbi/corefx
 public SerializedSection(BlobBuilder builder, string name, SectionCharacteristics characteristics, int relativeVirtualAddress, int sizeOfRawData, int pointerToRawData)
 {
     Name = name;
     Characteristics = characteristics;
     Builder = builder;
     RelativeVirtualAddress = relativeVirtualAddress;
     SizeOfRawData = sizeOfRawData;
     PointerToRawData = pointerToRawData;
 }
コード例 #3
0
        public void Empty()
        {
            var b = new DebugDirectoryBuilder();
            var id = new BlobContentId(new Guid("3C88E66E-E0B9-4508-9290-11E0DB51A1C5"), 0x12345678);

            var blob = new BlobBuilder();
            b.Serialize(blob, new SectionLocation(0x1000, 0x2000), 0x50);
            AssertEx.Equal(new byte[0], blob.ToArray());
        }
コード例 #4
0
        public void AddCodeViewEntry2()
        {
            var b = new DebugDirectoryBuilder();
            var id = new BlobContentId(new Guid("3C88E66E-E0B9-4508-9290-11E0DB51A1C5"), 0x12345678);
            b.AddCodeViewEntry("foo.pdb" + new string('\0', 260 - "foo.pdb".Length - 1), id, 0xABCD);

            var blob = new BlobBuilder();
            b.Serialize(blob, new SectionLocation(0x1000, 0x2000), 0x50);
            var bytes = blob.ToArray();

            AssertEx.Equal(new byte[]
            {
                0x00, 0x00, 0x00, 0x00, // Characteristics
                0x78, 0x56, 0x34, 0x12, // Stamp
                0xCD, 0xAB, 0x4D, 0x50, // Version
                0x02, 0x00, 0x00, 0x00, // Type
                0x1C, 0x01, 0x00, 0x00, // SizeOfData
                0x6C, 0x10, 0x00, 0x00, // AddressOfRawData
                0x6C, 0x20, 0x00, 0x00, // PointerToRawData
                // data
                (byte)'R', (byte)'S', (byte)'D', (byte)'S',
                0x6E, 0xE6, 0x88, 0x3C, 0xB9, 0xE0, 0x08, 0x45, 0x92, 0x90, 0x11, 0xE0, 0xDB, 0x51, 0xA1, 0xC5, // GUID
                0x01, 0x00, 0x00, 0x00, // age
                (byte)'f', (byte)'o', (byte)'o', (byte)'.', (byte)'p', (byte)'d', (byte)'b', 0x00, // path
                // path padding:
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            }, bytes);

            using (var pinned = new PinnedBlob(bytes))
            {
                var actual = PEReader.ReadDebugDirectoryEntries(pinned.CreateReader(0, DebugDirectoryEntry.Size));
                Assert.Equal(1, actual.Length);
                Assert.Equal(id.Stamp, actual[0].Stamp);
                Assert.Equal(0xABCD, actual[0].MajorVersion);
                Assert.Equal(0x504d, actual[0].MinorVersion);
                Assert.Equal(DebugDirectoryEntryType.CodeView, actual[0].Type);
                Assert.Equal(0x0000011c, actual[0].DataSize);
                Assert.Equal(0x0000106c, actual[0].DataRelativeVirtualAddress);
                Assert.Equal(0x0000206c, actual[0].DataPointer);
            }
        }
コード例 #5
0
        public void AddEmbeddedPortablePdbEntry_Args()
        {
            var bb = new BlobBuilder();

            var builder = new DebugDirectoryBuilder();
            Assert.Throws<ArgumentNullException>(() => builder.AddEmbeddedPortablePdbEntry(null, 0x0100));
            Assert.Throws<ArgumentOutOfRangeException>(() => builder.AddEmbeddedPortablePdbEntry(bb, 0x0000));
            Assert.Throws<ArgumentOutOfRangeException>(() => builder.AddEmbeddedPortablePdbEntry(bb, 0x00ff));
            builder.AddEmbeddedPortablePdbEntry(bb, 0x0100);
            builder.AddEmbeddedPortablePdbEntry(bb, 0xffff);
        }
コード例 #6
0
ファイル: MetadataSerializer.cs プロジェクト: nbilling/corefx
        public void SerializeMetadata(BlobBuilder builder, Func<BlobBuilder, ContentId> idProvider, out ContentId contentId)
        {
            SerializeMetadataImpl(builder, methodBodyStreamRva: 0, mappedFieldDataStreamRva: 0);

            contentId = idProvider(builder);

            // fill in the id:
            var idWriter = new BlobWriter(_pdbIdBlob);
            idWriter.WriteBytes(contentId.Guid);
            idWriter.WriteBytes(contentId.Stamp);
            Debug.Assert(idWriter.RemainingBytes == 0);
        }
コード例 #7
0
ファイル: MethodBodyEncoder.cs プロジェクト: RoryVL/roslyn
 internal MethodBodyEncoder(
     BlobBuilder builder,
     ushort maxStack,
     int exceptionRegionCount,
     StandaloneSignatureHandle localVariablesSignature,
     MethodBodyAttributes attributes)
 {
     Builder = builder;
     _maxStack = maxStack;
     _localVariablesSignature = localVariablesSignature;
     _attributes = (byte)attributes;
     _exceptionRegionCount = exceptionRegionCount;
 }
コード例 #8
0
        public void BasicValidation()
        {
            using (var peStream = new MemoryStream())
            {
                var ilBuilder = new BlobBuilder();
                var metadataBuilder = new MetadataBuilder();
                var entryPoint = BasicValidationEmit(metadataBuilder, ilBuilder);
                WritePEImage(peStream, metadataBuilder, ilBuilder, entryPoint);

                peStream.Position = 0;
                VerifyPE(peStream);
            }
        }
コード例 #9
0
ファイル: MetadataSerializer.cs プロジェクト: nbilling/corefx
        /// <summary>
        /// Serialized #Pdb stream.
        /// </summary>
        protected override void SerializeStandalonePdbStream(BlobBuilder builder)
        {
            int startPosition = builder.Position;

            // the id will be filled in later
            _pdbIdBlob = builder.ReserveBytes(MetadataSizes.PdbIdSize);
            
            builder.WriteInt32(_entryPoint.IsNil ? 0 : MetadataTokens.GetToken(_entryPoint));

            builder.WriteUInt64(MetadataSizes.ExternalTablesMask);
            MetadataWriterUtilities.SerializeRowCounts(builder, MetadataSizes.ExternalRowCounts);

            int endPosition = builder.Position;
            Debug.Assert(MetadataSizes.CalculateStandalonePdbStreamSize() == endPosition - startPosition);
        }
コード例 #10
0
        public void AddEmbeddedPortablePdbEntry(BlobBuilder debugMetadata, ushort portablePdbVersion)
        {
            if (debugMetadata == null)
            {
                Throw.ArgumentNull(nameof(debugMetadata));
            }

            int dataSize = WriteEmbeddedPortablePdbData(_dataBuilder, debugMetadata);

            AddEntry(
                type: DebugDirectoryEntryType.EmbeddedPortablePdb, 
                version: PortablePdbVersions.DebugDirectoryEmbeddedVersion(portablePdbVersion),
                stamp: 0,
                dataSize: dataSize);
        }
コード例 #11
0
        private static void WritePEImage(Stream peStream, MetadataBuilder metadataBuilder, BlobBuilder ilBuilder, MethodDefinitionHandle entryPointHandle)
        {
            var mappedFieldDataBuilder = new BlobBuilder();
            var managedResourceDataBuilder = new BlobBuilder();

            var peBuilder = new PEBuilder(
                machine: 0,
                sectionAlignment: 0x2000,
                fileAlignment: 0x200,
                imageBase: 0x00400000,
                majorLinkerVersion: 0x30, // (what is ref.emit using?)
                minorLinkerVersion: 0,
                majorOperatingSystemVersion: 4,
                minorOperatingSystemVersion: 0,
                majorImageVersion: 0,
                minorImageVersion: 0,
                majorSubsystemVersion: 4,
                minorSubsystemVersion: 0,
                subsystem: Subsystem.WindowsCui,
                dllCharacteristics: DllCharacteristics.DynamicBase | DllCharacteristics.NxCompatible | DllCharacteristics.NoSeh | DllCharacteristics.TerminalServerAware,
                imageCharacteristics: entryPointHandle.IsNil ? Characteristics.Dll : Characteristics.ExecutableImage,
                sizeOfStackReserve: 0x00100000,
                sizeOfStackCommit: 0x1000,
                sizeOfHeapReserve: 0x00100000,
                sizeOfHeapCommit: 0x1000);

            var peDirectoriesBuilder = new PEDirectoriesBuilder();

            peBuilder.AddManagedSections(
                peDirectoriesBuilder,
                new TypeSystemMetadataSerializer(metadataBuilder, "v4.0.30319", isMinimalDelta: false),
                ilBuilder,
                mappedFieldDataBuilder,
                managedResourceDataBuilder,
                nativeResourceSectionSerializer: null,
                strongNameSignatureSize: 0,
                entryPoint: entryPointHandle,
                pdbPathOpt: null,
                nativePdbContentId: default(ContentId),
                portablePdbContentId: default(ContentId),
                corFlags: CorFlags.ILOnly);

            var peBlob = new BlobBuilder();
            ContentId peContentId;
            peBuilder.Serialize(peBlob, peDirectoriesBuilder, out peContentId);

            peBlob.WriteContentTo(peStream);
        }
コード例 #12
0
ファイル: BlobBuilder.cs プロジェクト: Corillian/corefx
        public BlobBuilder(int capacity = DefaultChunkSize)
        {
            if (capacity < 0)
            {
                Throw.ArgumentOutOfRange(nameof(capacity));
            }

            // the writer assumes little-endian architecture:
            if (!BitConverter.IsLittleEndian)
            {
                Throw.LitteEndianArchitectureRequired();
            }

            _nextOrPrevious = this;
            _buffer = new byte[Math.Max(MinChunkSize, capacity)];
        }
コード例 #13
0
ファイル: TestBuilders.cs プロジェクト: Corillian/corefx
        public static byte[] BuildPEWithDebugDirectory(DebugDirectoryBuilder debugDirectoryBuilder)
        {
            var peStream = new MemoryStream();
            var ilBuilder = new BlobBuilder();
            var metadataBuilder = new MetadataBuilder();

            var peBuilder = new ManagedPEBuilder(
                PEHeaderBuilder.CreateLibraryHeader(),
                new MetadataRootBuilder(metadataBuilder),
                ilBuilder,
                debugDirectoryBuilder: debugDirectoryBuilder);

            var peImageBuilder = new BlobBuilder();
            peBuilder.Serialize(peImageBuilder);
            return peImageBuilder.ToArray();
        }
コード例 #14
0
ファイル: ManagedPEBuilder.cs プロジェクト: ChuangYang/corefx
        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();
        }
コード例 #15
0
ファイル: MethodBodyEncoder.cs プロジェクト: RoryVL/roslyn
        public MethodBodiesEncoder(BlobBuilder builder = null)
        {
            if (builder == null)
            {
                builder = new BlobBuilder();
            }

            // Fat methods are 4-byte aligned. We calculate the alignment relative to the start of the ILStream.
            //
            // See ECMA-335 paragraph 25.4.5, Method data section:
            // "At the next 4-byte boundary following the method body can be extra method data sections."
            if ((builder.Count % 4) != 0)
            {
                // TODO: error message
                throw new ArgumentException("Builder has to be aligned to 4 byte boundary", nameof(builder));
            }

            Builder = builder;
        }
コード例 #16
0
ファイル: BlobWriterImpl.cs プロジェクト: ESgarbi/corefx
 internal static void WriteCompressedInteger(BlobBuilder writer, uint value)
 {
     unchecked
     {
         if (value <= SingleByteCompressedIntegerMaxValue)
         {
             writer.WriteByte((byte)value);
         }
         else if (value <= TwoByteCompressedIntegerMaxValue)
         {
             writer.WriteUInt16BE((ushort)(0x8000 | value));
         }
         else if (value <= MaxCompressedIntegerValue)
         {
             writer.WriteUInt32BE(0xc0000000 | value);
         }
         else
         {
             Throw.ValueArgumentOutOfRange();
         }
     }
 }
コード例 #17
0
        private static int WriteCodeViewData(BlobBuilder builder, string pdbPath, Guid pdbGuid)
        {
            int start = builder.Count;

            builder.WriteByte((byte)'R');
            builder.WriteByte((byte)'S');
            builder.WriteByte((byte)'D');
            builder.WriteByte((byte)'S');

            // PDB id:
            builder.WriteGuid(pdbGuid);

            // age
            builder.WriteUInt32(1);

            // UTF-8 encoded zero-terminated path to PDB
            int pathStart = builder.Count;
            builder.WriteUTF8(pdbPath, allowUnpairedSurrogates: true);
            builder.WriteByte(0);

            return builder.Count - start;
        }
コード例 #18
0
        private static int WriteEmbeddedPortablePdbData(BlobBuilder builder, BlobBuilder debugMetadata)
        {
            int start = builder.Count;

            // header (signature, decompressed size):
            builder.WriteUInt32(PortablePdbVersions.DebugDirectoryEmbeddedSignature);
            builder.WriteInt32(debugMetadata.Count);

            // compressed data:
            var compressed = new MemoryStream();
            using (var deflate = new DeflateStream(compressed, CompressionLevel.Optimal, leaveOpen: true))
            {
                foreach (var blob in debugMetadata.GetBlobs())
                {
                    var segment = blob.GetBytes();
                    deflate.Write(segment.Array, segment.Offset, segment.Count);
                }
            }

            // TODO: avoid multiple copies:
            builder.WriteBytes(compressed.ToArray());

            return builder.Count - start;
        }
コード例 #19
0
ファイル: ManagedPEBuilder.cs プロジェクト: ChuangYang/corefx
        private BlobBuilder SerializeRelocationSection(SectionLocation location)
        {
            var sectionBuilder = new BlobBuilder();
            WriteRelocationSection(sectionBuilder, Header.Machine, _lazyEntryPointAddress);

            _peDirectoriesBuilder.BaseRelocationTable = new DirectoryEntry(location.RelativeVirtualAddress, sectionBuilder.Count);
            return sectionBuilder;
        }
コード例 #20
0
ファイル: ManagedPEBuilder.cs プロジェクト: ChuangYang/corefx
        private BlobBuilder SerializeResourceSection(SectionLocation location)
        {
            Debug.Assert(_nativeResourcesOpt != null);

            var sectionBuilder = new BlobBuilder();
            _nativeResourcesOpt.Serialize(sectionBuilder, location);

            _peDirectoriesBuilder.ResourceTable = new DirectoryEntry(location.RelativeVirtualAddress, sectionBuilder.Count);
            return sectionBuilder;
        }
コード例 #21
0
ファイル: ManagedPEBuilder.cs プロジェクト: ChuangYang/corefx
        private BlobBuilder SerializeTextSection(SectionLocation location)
        {
            var sectionBuilder = new BlobBuilder();
            var metadataBuilder = new BlobBuilder();

            var metadataSizes = _metadataRootBuilder.Sizes;

            var textSection = new ManagedTextSection(
                imageCharacteristics: Header.ImageCharacteristics,
                machine: Header.Machine,
                ilStreamSize: _ilStream.Count,
                metadataSize: metadataSizes.MetadataSize,
                resourceDataSize: _managedResourcesOpt?.Count ?? 0,
                strongNameSignatureSize: _strongNameSignatureSize,
                debugDataSize: _debugDirectoryBuilderOpt?.Size ?? 0,
                mappedFieldDataSize: _mappedFieldDataOpt?.Count ?? 0);

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

            DirectoryEntry debugDirectoryEntry;
            BlobBuilder debugTableBuilderOpt;
            if (_debugDirectoryBuilderOpt != null)
            {
                int debugDirectoryOffset = textSection.ComputeOffsetToDebugDirectory();
                debugTableBuilderOpt = new BlobBuilder(_debugDirectoryBuilderOpt.TableSize);
                _debugDirectoryBuilderOpt.Serialize(debugTableBuilderOpt, location, debugDirectoryOffset);

                // Only the size of the fixed part of the debug table goes here.
                debugDirectoryEntry = new DirectoryEntry(
                    location.RelativeVirtualAddress + debugDirectoryOffset,
                    _debugDirectoryBuilderOpt.TableSize);
            }
            else
            {
                debugTableBuilderOpt = null;
                debugDirectoryEntry = default(DirectoryEntry);
            }

            _lazyEntryPointAddress = textSection.GetEntryPointAddress(location.RelativeVirtualAddress);

            textSection.Serialize(
                sectionBuilder,
                location.RelativeVirtualAddress,
                _entryPointOpt.IsNil ? 0 : MetadataTokens.GetToken(_entryPointOpt),
                _corFlags,
                Header.ImageBase,
                metadataBuilder,
                _ilStream,
                _mappedFieldDataOpt,
                _managedResourcesOpt,
                debugTableBuilderOpt,
                out _lazyStrongNameSignature);

            _peDirectoriesBuilder.AddressOfEntryPoint = _lazyEntryPointAddress;
            _peDirectoriesBuilder.DebugTable = debugDirectoryEntry;
            _peDirectoriesBuilder.ImportAddressTable = textSection.GetImportAddressTableDirectoryEntry(location.RelativeVirtualAddress);
            _peDirectoriesBuilder.ImportTable = textSection.GetImportTableDirectoryEntry(location.RelativeVirtualAddress);
            _peDirectoriesBuilder.CorHeaderTable = textSection.GetCorHeaderDirectoryEntry(location.RelativeVirtualAddress);
            
            return sectionBuilder;
        }
コード例 #22
0
        internal void SerializeMetadataTables(
            BlobBuilder writer,
            MetadataSizes metadataSizes,
            int methodBodyStreamRva,
            int mappedFieldDataStreamRva)
        {
            int startPosition = writer.Position;

            this.SerializeTablesHeader(writer, metadataSizes);

            if (metadataSizes.IsPresent(TableIndex.Module))
            {
                SerializeModuleTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.TypeRef))
            {
                this.SerializeTypeRefTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.TypeDef))
            {
                this.SerializeTypeDefTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.Field))
            {
                this.SerializeFieldTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.MethodDef))
            {
                this.SerializeMethodDefTable(writer, metadataSizes, methodBodyStreamRva);
            }

            if (metadataSizes.IsPresent(TableIndex.Param))
            {
                this.SerializeParamTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.InterfaceImpl))
            {
                this.SerializeInterfaceImplTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.MemberRef))
            {
                this.SerializeMemberRefTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.Constant))
            {
                this.SerializeConstantTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.CustomAttribute))
            {
                this.SerializeCustomAttributeTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.FieldMarshal))
            {
                this.SerializeFieldMarshalTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.DeclSecurity))
            {
                this.SerializeDeclSecurityTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.ClassLayout))
            {
                this.SerializeClassLayoutTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.FieldLayout))
            {
                this.SerializeFieldLayoutTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.StandAloneSig))
            {
                this.SerializeStandAloneSigTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.EventMap))
            {
                this.SerializeEventMapTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.Event))
            {
                this.SerializeEventTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.PropertyMap))
            {
                this.SerializePropertyMapTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.Property))
            {
                this.SerializePropertyTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.MethodSemantics))
            {
                this.SerializeMethodSemanticsTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.MethodImpl))
            {
                this.SerializeMethodImplTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.ModuleRef))
            {
                this.SerializeModuleRefTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.TypeSpec))
            {
                this.SerializeTypeSpecTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.ImplMap))
            {
                this.SerializeImplMapTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.FieldRva))
            {
                this.SerializeFieldRvaTable(writer, metadataSizes, mappedFieldDataStreamRva);
            }

            if (metadataSizes.IsPresent(TableIndex.EncLog))
            {
                this.SerializeEncLogTable(writer);
            }

            if (metadataSizes.IsPresent(TableIndex.EncMap))
            {
                this.SerializeEncMapTable(writer);
            }

            if (metadataSizes.IsPresent(TableIndex.Assembly))
            {
                this.SerializeAssemblyTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.AssemblyRef))
            {
                this.SerializeAssemblyRefTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.File))
            {
                this.SerializeFileTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.ExportedType))
            {
                this.SerializeExportedTypeTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.ManifestResource))
            {
                this.SerializeManifestResourceTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.NestedClass))
            {
                this.SerializeNestedClassTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.GenericParam))
            {
                this.SerializeGenericParamTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.MethodSpec))
            {
                this.SerializeMethodSpecTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.GenericParamConstraint))
            {
                this.SerializeGenericParamConstraintTable(writer, metadataSizes);
            }

            // debug tables
            if (metadataSizes.IsPresent(TableIndex.Document))
            {
                this.SerializeDocumentTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.MethodDebugInformation))
            {
                this.SerializeMethodDebugInformationTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.LocalScope))
            {
                this.SerializeLocalScopeTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.LocalVariable))
            {
                this.SerializeLocalVariableTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.LocalConstant))
            {
                this.SerializeLocalConstantTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.ImportScope))
            {
                this.SerializeImportScopeTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.StateMachineMethod))
            {
                this.SerializeStateMachineMethodTable(writer, metadataSizes);
            }

            if (metadataSizes.IsPresent(TableIndex.CustomDebugInformation))
            {
                this.SerializeCustomDebugInformationTable(writer, metadataSizes);
            }

            writer.WriteByte(0);
            writer.Align(4);

            int endPosition = writer.Position;
            Debug.Assert(metadataSizes.MetadataTableStreamSize == endPosition - startPosition);
        }
コード例 #23
0
 private void SerializeCustomDebugInformationTable(BlobBuilder writer, MetadataSizes metadataSizes)
 {
     // Note: we can sort the table at this point since no other table can reference its rows via RowId or CodedIndex (which would need updating otherwise).
     // OrderBy performs a stable sort, so multiple attributes with the same parent and kind will be sorted in the order they were added to the table.
     foreach (CustomDebugInformationRow row in _customDebugInformationTable.OrderBy((x, y) =>
     {
         int result = (int)x.Parent - (int)y.Parent;
         return (result != 0) ? result : MetadataTokens.GetHeapOffset(x.Kind) - MetadataTokens.GetHeapOffset(y.Kind);
     }))
     {
         writer.WriteReference(row.Parent, metadataSizes.HasCustomDebugInformationSize);
         writer.WriteReference((uint)GetHeapOffset(row.Kind), metadataSizes.GuidIndexSize);
         writer.WriteReference((uint)GetHeapOffset(row.Value), metadataSizes.BlobIndexSize);
     }
 }
コード例 #24
0
ファイル: ManagedPEBuilder.cs プロジェクト: ChuangYang/corefx
        public void Sign(BlobBuilder peImage, Func<IEnumerable<Blob>, byte[]> signatureProvider)
        {
            if (peImage == null)
            {
                throw new ArgumentNullException(nameof(peImage));
            }

            if (signatureProvider == null)
            {
                throw new ArgumentNullException(nameof(signatureProvider));
            }

            var content = GetContentToSign(peImage);
            byte[] signature = signatureProvider(content);

            // signature may be shorter (the rest of the reserved space is padding):
            if (signature == null || signature.Length > _lazyStrongNameSignature.Length)
            {
                throw new InvalidOperationException(SR.SignatureProviderReturnedInvalidSignature);
            }

            // TODO: Native csc also calculates and fills checksum in the PE header
            // Using MapFileAndCheckSum() from imagehlp.dll.

            var writer = new BlobWriter(_lazyStrongNameSignature);
            writer.WriteBytes(signature);
        }
コード例 #25
0
        /// <summary>
        /// Compares the current content of this writer with another one.
        /// </summary>
        /// <exception cref="InvalidOperationException">Content is not available, the builder has been linked with another one.</exception>
        public bool ContentEquals(BlobBuilder other)
        {
            if (!IsHead)
            {
                Throw.InvalidOperationBuilderAlreadyLinked();
            }

            if (ReferenceEquals(this, other))
            {
                return(true);
            }

            if (other == null)
            {
                return(false);
            }

            if (!other.IsHead)
            {
                Throw.InvalidOperationBuilderAlreadyLinked();
            }

            if (Count != other.Count)
            {
                return(false);
            }

            var leftEnumerator  = GetChunks();
            var rightEnumerator = other.GetChunks();
            int leftStart       = 0;
            int rightStart      = 0;

            bool leftContinues  = leftEnumerator.MoveNext();
            bool rightContinues = rightEnumerator.MoveNext();

            while (leftContinues && rightContinues)
            {
                Debug.Assert(leftStart == 0 || rightStart == 0);

                var left  = leftEnumerator.Current;
                var right = rightEnumerator.Current;

                int minLength = Math.Min(left.Length - leftStart, right.Length - rightStart);
                if (!ByteSequenceComparer.Equals(left._buffer, leftStart, right._buffer, rightStart, minLength))
                {
                    return(false);
                }

                leftStart  += minLength;
                rightStart += minLength;

                // nothing remains in left chunk to compare:
                if (leftStart == left.Length)
                {
                    leftContinues = leftEnumerator.MoveNext();
                    leftStart     = 0;
                }

                // nothing remains in left chunk to compare:
                if (rightStart == right.Length)
                {
                    rightContinues = rightEnumerator.MoveNext();
                    rightStart     = 0;
                }
            }

            return(leftContinues == rightContinues);
        }
コード例 #26
0
 // internal for testing
 internal void ClearChunk()
 {
     _length = 0;
     _previousLengthOrFrozenSuffixLengthDelta = 0;
     _nextOrPrevious = this;
 }
コード例 #27
0
 internal Blobs(BlobBuilder builder)
 {
     _chunks = new Chunks(builder);
 }
コード例 #28
0
        /// <summary>
        /// Serialize the Debug Table and Data.
        /// </summary>
        /// <param name="builder">Builder.</param>
        /// <param name="sectionLocation">The containing PE section location.</param>
        /// <param name="sectionOffset">Offset of the table within the containing section.</param>
        internal void Serialize(BlobBuilder builder, SectionLocation sectionLocation, int sectionOffset)
        {
            int dataOffset = sectionOffset + TableSize;
            foreach (var entry in _entries)
            {
                int addressOfRawData;
                int pointerToRawData;
                if (entry.DataSize > 0)
                {
                    addressOfRawData = sectionLocation.RelativeVirtualAddress + dataOffset;
                    pointerToRawData = sectionLocation.PointerToRawData + dataOffset;
                }
                else
                {
                    addressOfRawData = 0;
                    pointerToRawData = 0;
                }

                builder.WriteUInt32(0); // characteristics, always 0
                builder.WriteUInt32(entry.Stamp);
                builder.WriteUInt32(entry.Version);
                builder.WriteInt32((int)entry.Type);
                builder.WriteInt32(entry.DataSize);
                builder.WriteInt32(addressOfRawData);
                builder.WriteInt32(pointerToRawData);

                dataOffset += entry.DataSize;
            }

            builder.LinkSuffix(_dataBuilder);
        }
コード例 #29
0
ファイル: ManagedPEBuilder.cs プロジェクト: ChuangYang/corefx
        private static void WriteRelocationSection(BlobBuilder builder, Machine machine, int entryPointAddress)
        {
            Debug.Assert(builder.Count == 0);

            builder.WriteUInt32((((uint)entryPointAddress + 2) / 0x1000) * 0x1000);
            builder.WriteUInt32((machine == Machine.IA64) ? 14u : 12u);
            uint offsetWithinPage = ((uint)entryPointAddress + 2) % 0x1000;
            uint relocType = (machine == Machine.Amd64 || machine == Machine.IA64) ? 10u : 3u;
            ushort s = (ushort)((relocType << 12) | offsetWithinPage);
            builder.WriteUInt16(s);
            if (machine == Machine.IA64)
            {
                builder.WriteUInt32(relocType << 12);
            }

            builder.WriteUInt16(0); // next chunk's RVA
        }
コード例 #30
0
ファイル: ManagedPEBuilder.cs プロジェクト: ChuangYang/corefx
        private IEnumerable<Blob> GetContentToSign(BlobBuilder peImage)
        {
            // Signed content includes 
            // - PE header without its alignment padding
            // - all sections including their alignment padding and excluding strong name signature blob

            int remainingHeader = Header.ComputeSizeOfPeHeaders(GetSections().Length);
            foreach (var blob in peImage.GetBlobs())
            {
                if (remainingHeader > 0)
                {
                    int length = Math.Min(remainingHeader, blob.Length);
                    yield return new Blob(blob.Buffer, blob.Start, length);
                    remainingHeader -= length;
                }
                else if (blob.Buffer == _lazyStrongNameSignature.Buffer)
                {
                    yield return new Blob(blob.Buffer, blob.Start, _lazyStrongNameSignature.Start - blob.Start);
                    yield return new Blob(blob.Buffer, _lazyStrongNameSignature.Start + _lazyStrongNameSignature.Length, blob.Length - _lazyStrongNameSignature.Length);
                }
                else
                {
                    yield return new Blob(blob.Buffer, blob.Start, blob.Length);
                }
            }
        }
コード例 #31
0
 private void SerializeImportScopeTable(BlobBuilder writer, MetadataSizes metadataSizes)
 {
     foreach (var row in _importScopeTable)
     {
         writer.WriteReference(row.Parent, metadataSizes.ImportScopeIndexSize);
         writer.WriteReference((uint)GetHeapOffset(row.Imports), metadataSizes.BlobIndexSize);
     }
 }
コード例 #32
0
        /// <exception cref="ArgumentNullException"><paramref name="suffix"/> is null.</exception>
        /// <exception cref="InvalidOperationException">Builder is not writable, it has been linked with another one.</exception>
        public void LinkSuffix(BlobBuilder suffix)
        {
            if (suffix is null)
            {
                Throw.ArgumentNull(nameof(suffix));
            }

            // TODO: consider copying data from right to left while there is space

            if (!IsHead || !suffix.IsHead)
            {
                Throw.InvalidOperationBuilderAlreadyLinked();
            }

            // avoid chaining empty chunks:
            if (suffix.Count == 0)
            {
                return;
            }

            bool isEmpty = Count == 0;

            // swap buffers of the heads:
            var  suffixBuffer         = suffix._buffer;
            uint suffixLength         = suffix._length;
            int  suffixPreviousLength = suffix.PreviousLength;
            int  oldSuffixLength      = suffix.Length;

            suffix._buffer = _buffer;
            suffix._length = FrozenLength; // suffix is not a head anymore
            _buffer        = suffixBuffer;
            _length        = suffixLength;

            PreviousLength += suffix.Length + suffixPreviousLength;

            // Update the _previousLength of the suffix so that suffix.Count = suffix._previousLength + suffix.Length doesn't change.
            // Note that the resulting previous length might be negative.
            // The value is not used, other than for calculating the value of Count property.
            suffix._previousLengthOrFrozenSuffixLengthDelta = suffixPreviousLength + oldSuffixLength - suffix.Length;

            if (!isEmpty)
            {
                // First and last chunks:
                //
                // [First]->[]->[Last] <- [this]    [SuffixFirst]->[]->[SuffixLast]  <- [suffix]
                //    ^___________|                       ^_________________|
                //
                // Degenerate cases:
                // this == First == Last and/or suffix == SuffixFirst == SuffixLast.
                var first       = FirstChunk;
                var suffixFirst = suffix.FirstChunk;
                var last        = _nextOrPrevious;
                var suffixLast  = suffix._nextOrPrevious;

                // Relink like so:
                // [First]->[]->[Last] -> [suffix] -> [SuffixFirst]->[]->[SuffixLast]  <- [this]
                //    ^_______________________________________________________|
                _nextOrPrevious        = suffixLast;
                suffix._nextOrPrevious = (suffixFirst != suffix) ? suffixFirst : (first != this) ? first : suffix;

                if (last != this)
                {
                    last._nextOrPrevious = suffix;
                }

                if (suffixLast != suffix)
                {
                    suffixLast._nextOrPrevious = (first != this) ? first : suffix;
                }
            }

            CheckInvariants();
            suffix.CheckInvariants();
        }
コード例 #33
0
        private void SerializeStateMachineMethodTable(BlobBuilder writer, MetadataSizes metadataSizes)
        {
#if DEBUG
            for (int i = 1; i < _stateMachineMethodTable.Count; i++)
            {
                Debug.Assert(_stateMachineMethodTable[i - 1].MoveNextMethod < _stateMachineMethodTable[i].MoveNextMethod);
            }
#endif
            foreach (var row in _stateMachineMethodTable)
            {
                writer.WriteReference(row.MoveNextMethod, metadataSizes.MethodDefIndexSize);
                writer.WriteReference(row.KickoffMethod, metadataSizes.MethodDefIndexSize);
            }
        }
コード例 #34
0
 public DebugDirectoryBuilder()
 {
     _entries = new List<Entry>(2);
     _dataBuilder = new BlobBuilder();
 }
コード例 #35
0
        internal static void WriteConstant(BlobBuilder writer, object?value)
        {
            if (value == null)
            {
                // The encoding of Type for the nullref value for FieldInit is ELEMENT_TYPE_CLASS with a Value of a 32-bit.
                writer.WriteUInt32(0);
                return;
            }

            var type = value.GetType();

            if (type.GetTypeInfo().IsEnum)
            {
                type = Enum.GetUnderlyingType(type);
            }

            if (type == typeof(bool))
            {
                writer.WriteBoolean((bool)value);
            }
            else if (type == typeof(int))
            {
                writer.WriteInt32((int)value);
            }
            else if (type == typeof(string))
            {
                writer.WriteUTF16((string)value);
            }
            else if (type == typeof(byte))
            {
                writer.WriteByte((byte)value);
            }
            else if (type == typeof(char))
            {
                writer.WriteUInt16((char)value);
            }
            else if (type == typeof(double))
            {
                writer.WriteDouble((double)value);
            }
            else if (type == typeof(short))
            {
                writer.WriteInt16((short)value);
            }
            else if (type == typeof(long))
            {
                writer.WriteInt64((long)value);
            }
            else if (type == typeof(sbyte))
            {
                writer.WriteSByte((sbyte)value);
            }
            else if (type == typeof(float))
            {
                writer.WriteSingle((float)value);
            }
            else if (type == typeof(ushort))
            {
                writer.WriteUInt16((ushort)value);
            }
            else if (type == typeof(uint))
            {
                writer.WriteUInt32((uint)value);
            }
            else if (type == typeof(ulong))
            {
                writer.WriteUInt64((ulong)value);
            }
            else
            {
                throw new ArgumentException(SR.Format(SR.InvalidConstantValueOfType, type));
            }
        }