Пример #1
0
        private static void WritePEImage(
            Stream peStream,
            MetadataBuilder metadataBuilder,
            BlobBuilder ilBuilder,
            MethodDefinitionHandle entryPointHandle
            )
        {
            // Create executable with the managed metadata from the specified MetadataBuilder.
            var peHeaderBuilder = new PEHeaderBuilder(
                imageCharacteristics: Characteristics.ExecutableImage | Characteristics.Dll
                );

            var peBuilder = new ManagedPEBuilder(
                peHeaderBuilder,
                new MetadataRootBuilder(metadataBuilder),
                ilBuilder,
                entryPoint: entryPointHandle,
                flags: CorFlags.ILOnly,
                deterministicIdProvider: content => s_contentId);

            // Write executable into the specified stream.
            var           peBlob    = new BlobBuilder();
            BlobContentId contentId = peBuilder.Serialize(peBlob);

            peBlob.WriteContentTo(peStream);
        }
Пример #2
0
        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);
        }
Пример #3
0
 public ExtendedPEBuilder(
     PEHeaderBuilder header,
     MetadataRootBuilder metadataRootBuilder,
     BlobBuilder ilStream,
     BlobBuilder mappedFieldData,
     BlobBuilder managedResources,
     ResourceSectionBuilder nativeResources,
     DebugDirectoryBuilder debugDirectoryBuilder,
     int strongNameSignatureSize,
     MethodDefinitionHandle entryPoint,
     CorFlags flags,
     Func <IEnumerable <Blob>, BlobContentId> deterministicIdProvider,
     bool withMvidSection
     )
     : base(
         header,
         metadataRootBuilder,
         ilStream,
         mappedFieldData,
         managedResources,
         nativeResources,
         debugDirectoryBuilder,
         strongNameSignatureSize,
         entryPoint,
         flags,
         deterministicIdProvider
         )
 {
     _withMvidSection = withMvidSection;
 }
Пример #4
0
        public unsafe void NativeResources()
        {
            var peStream        = new MemoryStream();
            var ilBuilder       = new BlobBuilder();
            var metadataBuilder = new MetadataBuilder();

            var peBuilder = new ManagedPEBuilder(
                PEHeaderBuilder.CreateLibraryHeader(),
                new MetadataRootBuilder(metadataBuilder),
                ilBuilder,
                nativeResources: new TestResourceSectionBuilder(),
                deterministicIdProvider: content => s_contentId);

            var peBlob = new BlobBuilder();

            var contentId = peBuilder.Serialize(peBlob);

            peBlob.WriteContentTo(peStream);

            peStream.Position = 0;
            var peReader      = new PEReader(peStream);
            var sectionHeader = peReader.PEHeaders.SectionHeaders.Single(s => s.Name == ".rsrc");

            var image = peReader.GetEntireImage();

            var reader = new BlobReader(image.Pointer + sectionHeader.PointerToRawData, sectionHeader.SizeOfRawData);

            Assert.Equal(0x12345678, reader.ReadInt32());
            Assert.Equal(sectionHeader.PointerToRawData, reader.ReadInt32());
            Assert.Equal(sectionHeader.VirtualAddress, reader.ReadInt32());
        }
Пример #5
0
        private static void SerializeHelperLibrary(string assemblyName, string rootNamespace, string path)
        {
            var ilBuilder       = new BlobBuilder();
            var metadataBuilder = new MetadataBuilder();

            EmitHelperLibraryMetadata(assemblyName, rootNamespace, metadataBuilder, ilBuilder);

            // Following code does not work:
            //
            //   var peHeaderBuilder = PEHeaderBuilder.CreateLibraryHeader();
            //
            // PEHeaderBuilder.CreateLibraryHeader() method does not set Characteristics.ExecutableImage bit.
            // If we serialize an assembly without setting it, .NET Core runtime refuses to load.
            // So, we explicitly set it by using PEHeaderBuilder constructor.

            var peHeaderBuilder =
                new PEHeaderBuilder(imageCharacteristics: Characteristics.ExecutableImage | Characteristics.Dll);
            var peBuilder = new ManagedPEBuilder(peHeaderBuilder, new MetadataRootBuilder(metadataBuilder), ilBuilder);

            var peBlob = new BlobBuilder();

            peBuilder.Serialize(peBlob);

            using (var stream = File.Create(path))
            {
                peBlob.WriteContentTo(stream);
            }
        }
Пример #6
0
        public void ManagedPEBuilder_Errors()
        {
            var hdr = new PEHeaderBuilder();
            var ms  = new MetadataRootBuilder(new MetadataBuilder());
            var il  = new BlobBuilder();

            Assert.Throws <ArgumentNullException>(() => new ManagedPEBuilder(null, ms, il));
            Assert.Throws <ArgumentNullException>(() => new ManagedPEBuilder(hdr, null, il));
            Assert.Throws <ArgumentNullException>(() => new ManagedPEBuilder(hdr, ms, null));
            Assert.Throws <ArgumentOutOfRangeException>(() => new ManagedPEBuilder(hdr, ms, il, strongNameSignatureSize: -1));
        }
Пример #7
0
        public void ManagedPEBuilder_Errors()
        {
            var hdr = new PEHeaderBuilder();
            var ms  = new TypeSystemMetadataSerializer(new MetadataBuilder(), "v4.0.30319", false);
            var il  = new BlobBuilder();

            Assert.Throws <ArgumentNullException>(() => new ManagedPEBuilder(null, ms, il));
            Assert.Throws <ArgumentNullException>(() => new ManagedPEBuilder(hdr, null, il));
            Assert.Throws <ArgumentNullException>(() => new ManagedPEBuilder(hdr, ms, null));
            Assert.Throws <ArgumentOutOfRangeException>(() => new ManagedPEBuilder(hdr, ms, il, strongNameSignatureSize: -1));
        }
Пример #8
0
        public void SerializeToStream(Stream peStream)
        {
            var peHeaderBuilder = new PEHeaderBuilder();
            var peBuilder       = new ManagedPEBuilder(peHeaderBuilder, new MetadataRootBuilder(_metadataBuilder), _ilBuilder,
                                                       deterministicIdProvider: content => s_contentId);

            var peBlob    = new BlobBuilder();
            var contentId = peBuilder.Serialize(peBlob);

            new BlobWriter(_mvidFixup).WriteGuid(contentId.Guid);
            peBlob.WriteContentTo(peStream);
        }
Пример #9
0
        /// <summary>
        /// Constructor initializes the various control structures and combines the section list.
        /// </summary>
        /// <param name="target">Target environment specifier</param>
        /// <param name="peHeaderBuilder">PE file header builder</param>
        /// <param name="getRuntimeFunctionsTable">Callback to retrieve the runtime functions table</param>
        public R2RPEBuilder(
            TargetDetails target,
            PEHeaderBuilder peHeaderBuilder,
            ISymbolNode r2rHeaderExportSymbol,
            string outputFileSimpleName,
            Func <RuntimeFunctionsTableNode> getRuntimeFunctionsTable,
            int customPESectionAlignment,
            Func <IEnumerable <Blob>, BlobContentId> deterministicIdProvider)
            : base(peHeaderBuilder, deterministicIdProvider: deterministicIdProvider)
        {
            _target = target;
            _getRuntimeFunctionsTable = getRuntimeFunctionsTable;
            _sectionRvaDeltas         = new List <SectionRVADelta>();

            _sectionBuilder = new SectionBuilder(target);

            _textSectionIndex = _sectionBuilder.AddSection(TextSectionName, SectionCharacteristics.ContainsCode | SectionCharacteristics.MemExecute | SectionCharacteristics.MemRead, 512);
            _dataSectionIndex = _sectionBuilder.AddSection(DataSectionName, SectionCharacteristics.ContainsInitializedData | SectionCharacteristics.MemWrite | SectionCharacteristics.MemRead, 512);

            _customPESectionAlignment = customPESectionAlignment;

            if (r2rHeaderExportSymbol != null)
            {
                _sectionBuilder.AddSection(R2RPEBuilder.ExportDataSectionName, SectionCharacteristics.ContainsInitializedData | SectionCharacteristics.MemRead, 512);
                _sectionBuilder.AddExportSymbol("RTR_HEADER", 1, r2rHeaderExportSymbol);
                _sectionBuilder.SetDllNameForExportDirectoryTable(outputFileSimpleName);
            }

            if (_sectionBuilder.FindSection(R2RPEBuilder.RelocSectionName) == null)
            {
                // Always inject the relocation section to the end of section list
                _sectionBuilder.AddSection(
                    R2RPEBuilder.RelocSectionName,
                    SectionCharacteristics.ContainsInitializedData |
                    SectionCharacteristics.MemRead |
                    SectionCharacteristics.MemDiscardable,
                    PEHeaderConstants.SectionAlignment);
            }

            ImmutableArray <Section> .Builder sectionListBuilder = ImmutableArray.CreateBuilder <Section>();
            foreach (SectionInfo sectionInfo in _sectionBuilder.GetSections())
            {
                ILCompiler.PEWriter.Section builderSection = _sectionBuilder.FindSection(sectionInfo.SectionName);
                Debug.Assert(builderSection != null);
                sectionListBuilder.Add(new Section(builderSection.Name, builderSection.Characteristics));
            }

            _sections                = sectionListBuilder.ToImmutableArray();
            _sectionRVAs             = new int[_sections.Length];
            _sectionPointerToRawData = new int[_sections.Length];
            _sectionRawSizes         = new int[_sections.Length];
        }
Пример #10
0
        public void ValidateFactoryMethods()
        {
            var peHeaderExe = PEHeaderBuilder.CreateExecutableHeader();

            Assert.NotNull(peHeaderExe);
            Assert.True((peHeaderExe.ImageCharacteristics & Characteristics.ExecutableImage) != 0);

            var peHeaderLib = PEHeaderBuilder.CreateLibraryHeader();

            Assert.NotNull(peHeaderLib);
            Assert.True((peHeaderLib.ImageCharacteristics & Characteristics.ExecutableImage) != 0);
            Assert.True((peHeaderLib.ImageCharacteristics & Characteristics.Dll) != 0);
        }
Пример #11
0
        /// <summary>
        /// Sets the PE file header for the dynamic assembly being emitted.
        /// </summary>
        /// <param name="header">The PE file header for the dynamic assembly.</param>
        /// <remarks>
        /// If no PE header is set using this method before calling <see cref="emit"/>,
        /// a default header is used.
        /// </remarks>
        /// <exception cref="InvalidOperationException">The PE file for the assembly has already been emitted.</exception>
        public void setPEHeader(PEHeaderBuilder header)
        {
            if (header == null)
            {
                throw new ArgumentNullException(nameof(header));
            }

            if (m_isPEFileCreated)
            {
                throw new InvalidOperationException("The PE file for this assembly has already been created.");
            }

            m_peHeader = header;
        }
Пример #12
0
        public void BlahBlahBlah()
        {
            var peHeader = PEHeaderBuilder.CreateLibraryHeader();

            var meta = new MetadataBuilder();

            var module = meta.AddModule(1,
                                        meta.GetOrAddString("Module1"),
                                        meta.GetOrAddGuid(Guid.Parse("11112222-3333-4444-5555-666677778888")),
                                        meta.GetOrAddGuid(Guid.Parse("88887777-6666-5555-4444-333322221111")),
                                        meta.GetOrAddGuid(Guid.Parse("22223333-4444-5555-6666-777788889999"))
                                        );

            var tObject = meta.AddTypeReference(
                EntityHandle.ModuleDefinition,
                meta.GetOrAddString("System"),
                meta.GetOrAddString("Object"));

            var fields  = new FieldDefinitionHandle();  //EMPTY!!
            var methods = new MethodDefinitionHandle(); //EMPTY!!

            meta.AddTypeDefinition(
                TypeAttributes.Class | TypeAttributes.Public,
                meta.GetOrAddString("Namespace1"),
                meta.GetOrAddString("Class1"),
                tObject,
                fields,
                methods);

            meta.GetOrAddString("Module1");



            var metadataRoot = new MetadataRootBuilder(meta);

            var ilBlob = new BlobBuilder();

            ilBlob.WriteByte(0);
            ilBlob.WriteByte(42);

            var pe = new ManagedPEBuilder(peHeader, metadataRoot, ilBlob);

            var blob = new BlobBuilder();

            pe.Serialize(blob);

            Assembly.Load(blob.ToArray());
        }
Пример #13
0
        public void EmitToStream(Stream stream)
        {
            foreach (var typeDef in _emittedTypes)
            {
                MethodDefinitionHandle?firstMethodHandle = null;

                foreach (var methodDef in typeDef.Methods)
                {
                    int bodyOffset = _methodBodyStream.AddMethodBody(methodDef.Code);

                    BlobHandle signature = MakeSignatureHandle(methodDef.Signature);

                    MethodDefinitionHandle methodHandle = _metadataBuilder.AddMethodDefinition(
                        MethodAttributes.PrivateScope | MethodAttributes.Static,
                        MethodImplAttributes.IL | MethodImplAttributes.Managed,
                        _metadataBuilder.GetOrAddString(methodDef.Name),
                        signature,
                        bodyOffset,
                        parameterList: default(ParameterHandle));

                    if (firstMethodHandle == null)
                    {
                        firstMethodHandle = methodHandle;
                    }
                }

                _metadataBuilder.AddTypeDefinition(
                    default(TypeAttributes),
                    default(StringHandle),
                    _metadataBuilder.GetOrAddString(typeDef.Name),
                    typeDef.IsValueType ?
                    MakeTypeRefHandle(_typeSystemContext.GetWellKnownType(WellKnownType.ValueType)) :
                    MakeTypeRefHandle(_typeSystemContext.GetWellKnownType(WellKnownType.Object)),
                    fieldList: MetadataTokens.FieldDefinitionHandle(1),
                    methodList: firstMethodHandle.Value);
            }

            BlobBuilder peBlob = new BlobBuilder();

            new ManagedPEBuilder(PEHeaderBuilder.CreateLibraryHeader(), new MetadataRootBuilder(_metadataBuilder), _methodBodyStream.Builder).Serialize(peBlob);

            peBlob.WriteContentTo(stream);

            // Clear some variables to catch any caller trying to emit data after writing the output file
            _emittedTypes     = null;
            _metadataBuilder  = null;
            _methodBodyStream = default(MethodBodyStreamEncoder);
        }
Пример #14
0
        /// <summary>
        /// Assembles this instance.
        /// </summary>
        public void Assemble()
        {
            // TODO: Complete this so that it actually generate the hello world sample
            // TODO: Use the data generated from the parser instead of hard coding here
            PEHeaderBuilder header   = new PEHeaderBuilder();
            MetadataBuilder metadata = new MetadataBuilder();

            metadata.AddAssembly(metadata.GetOrAddString("HelloWorld"), new Version(), default(StringHandle), default(BlobHandle), (System.Reflection.AssemblyFlags) 0, AssemblyHashAlgorithm.None);
            MetadataRootBuilder metadataRootBuilder = new MetadataRootBuilder(metadata);
            BlobBuilder         stream           = new BlobBuilder();
            ManagedPEBuilder    managedPEBuilder = new ManagedPEBuilder(header, metadataRootBuilder, stream);
            BlobBuilder         output           = new BlobBuilder();

            managedPEBuilder.Serialize(output);
            File.WriteAllBytes(@"C:\Temp\HelloWorld.dll", output.ToArray());
        }
Пример #15
0
        public unsafe void NativeResources_BadImpl()
        {
            var peStream        = new MemoryStream();
            var ilBuilder       = new BlobBuilder();
            var metadataBuilder = new MetadataBuilder();

            var peBuilder = new ManagedPEBuilder(
                PEHeaderBuilder.CreateLibraryHeader(),
                new MetadataRootBuilder(metadataBuilder),
                ilBuilder,
                nativeResources: new BadResourceSectionBuilder(),
                deterministicIdProvider: content => s_contentId);

            var peBlob = new BlobBuilder();

            Assert.Throws <NotImplementedException>(() => peBuilder.Serialize(peBlob));
        }
Пример #16
0
        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());
        }
Пример #17
0
        private ImmutableArray <Diagnostic> EmitAssembly(BoundProgram program)
        {
            var header              = new PEHeaderBuilder();
            var metadataBuilder     = new MetadataBuilder();
            var metadataRootBuilder = new MetadataRootBuilder(metadataBuilder);
            var blobBuilder         = new BlobBuilder();
            var peBuilder           = new ManagedPEBuilder(header, metadataRootBuilder, blobBuilder);

            peBuilder.Serialize(blobBuilder);

            // TODO: Produce portable assembly contents here
            using (var stream = new StreamWriter(program.PackageName + ".dll"))
            {
                blobBuilder.WriteContentTo(stream.BaseStream);
            }

            return(ImmutableArray <Diagnostic> .Empty);
        }
Пример #18
0
            public override ConstraintResult ApplyTo <TActual>(TActual actual)
            {
                string actualContract;

                switch (actual)
                {
                case string sourceCode:
                    actualContract = isVisualBasic
                            ? AssemblyUtils.GenerateContract(generator, sourceCode, Microsoft.CodeAnalysis.VisualBasic.LanguageVersion.Latest, assemblyResolver)
                            : AssemblyUtils.GenerateContract(generator, sourceCode, Microsoft.CodeAnalysis.CSharp.LanguageVersion.Latest, assemblyResolver);
                    break;

                case Compilation compilation:
                    using (var stream = new MemoryStream())
                    {
                        AssemblyUtils.EmitCompilation(compilation, stream);
                        stream.Seek(0, SeekOrigin.Begin);
                        actualContract = AssemblyUtils.GenerateContract(generator, stream, assemblyResolver);
                    }
                    break;

                case MetadataBuilder metadataBuilder:
                    var blobBuilder = new BlobBuilder();

                    var peBuilder = new ManagedPEBuilder(
                        PEHeaderBuilder.CreateLibraryHeader(),
                        new MetadataRootBuilder(metadataBuilder),
                        ilStream: new BlobBuilder());

                    peBuilder.Serialize(blobBuilder);

                    using (var stream = new MemoryStream(blobBuilder.ToArray(), writable: false))
                        actualContract = AssemblyUtils.GenerateContract(generator, stream, assemblyResolver);
                    break;

                default:
                    throw new ArgumentException("Expected source code as string or library IL as MetadataBuilder.", nameof(actual));
                }

                return(new ContractConstraintResult(this, actualContract, expected));
            }
Пример #19
0
        private static void WritePEImage(
            Stream peStream,
            MetadataBuilder metadataBuilder,
            BlobBuilder ilBuilder,
            MethodDefinitionHandle entryPointHandle,
            Blob mvidFixup              = default(Blob),
            byte[] privateKeyOpt        = null,
            bool publicSigned           = false,
            Machine machine             = 0,
            BlobBuilder?mappedFieldData = null)
        {
            var peHeaderBuilder = new PEHeaderBuilder(imageCharacteristics: entryPointHandle.IsNil ? Characteristics.Dll : Characteristics.ExecutableImage,
                                                      machine: machine);

            var peBuilder = new ManagedPEBuilder(
                peHeaderBuilder,
                new MetadataRootBuilder(metadataBuilder),
                ilBuilder,
                entryPoint: entryPointHandle,
                flags: CorFlags.ILOnly | (privateKeyOpt != null || publicSigned ? CorFlags.StrongNameSigned : 0),
                deterministicIdProvider: content => s_contentId,
                mappedFieldData: mappedFieldData);

            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);
        }
Пример #20
0
        private static void WritePEImage(
            Stream peStream,
            MetadataBuilder metadataBuilder,
            BlobBuilder ilBuilder,
            MethodDefinitionHandle entryPointHandle,
            byte[] privateKeyOpt = null)
        {
            var mappedFieldDataBuilder     = new BlobBuilder();
            var managedResourceDataBuilder = new BlobBuilder();

            var peBuilder = new ManagedPEBuilder(
                entryPointHandle.IsNil ? PEHeaderBuilder.CreateLibraryHeader() : PEHeaderBuilder.CreateExecutableHeader(),
                new TypeSystemMetadataSerializer(metadataBuilder, "v4.0.30319", isMinimalDelta: false),
                ilBuilder,
                mappedFieldDataBuilder,
                managedResourceDataBuilder,
                nativeResourceSectionSerializer: null,
                strongNameSignatureSize: 128,
                entryPoint: entryPointHandle,
                pdbPathOpt: null,
                nativePdbContentId: default(ContentId),
                portablePdbContentId: default(ContentId),
                corFlags: CorFlags.ILOnly | (privateKeyOpt != null ? CorFlags.StrongNameSigned : 0),
                deterministicIdProvider: content => s_contentId);

            var peBlob = new BlobBuilder();

            ContentId contentId;

            peBuilder.Serialize(peBlob, out contentId);

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

            peBlob.WriteContentTo(peStream);
        }
        public byte[] GenerateAssemblyBytes()
        {
            var name = _currentAssembly.GetName();

            var assemblyHandle = _metadataBuilder.AddAssembly(
                GetString(name.Name),
                name.Version,
                GetString(name.CultureName),
                GetBlob(name.GetPublicKey()),
                _assemblyNameFlagsConvert(name.Flags),
                _assemblyHashAlgorithmConvert(name.HashAlgorithm));

            CreateReferencedAssemblies(_currentAssembly.GetReferencedAssemblies());
            CreateCustomAttributes(assemblyHandle, _currentAssembly.GetCustomAttributesData());

            CreateModules(_currentAssembly.GetModules());
            CreateTypes(_currentAssembly.GetTypes());

            var entryPoint = GetMethodDefinitionHandle(_currentAssembly.EntryPoint);


            var metadataRootBuilder = new MetadataRootBuilder(_metadataBuilder);
            var header = PEHeaderBuilder.CreateLibraryHeader();

            var peBuilder = new ManagedPEBuilder(
                header,
                metadataRootBuilder,
                _ilBuilder,
                debugDirectoryBuilder: _debugDirectoryBuilder,
                entryPoint: entryPoint);

            var peImageBuilder = new BlobBuilder();

            peBuilder.Serialize(peImageBuilder);

            return(peImageBuilder.ToArray());
        }
Пример #22
0
        public static byte[] MakeRefasm(MetadataReader metaReader, PEReader peReader, LoggerBase logger, IImportFilter filter = null)
        {
            var metaBuilder = new MetadataBuilder();

            var importer = new MetadataImporter(metaReader, metaBuilder, logger);

            if (filter != null)
            {
                importer.Filter = filter;
                logger.Info?.Invoke("Using custom entity filter");
            }
            else if (importer.IsInternalsVisible())
            {
                importer.Filter = new AllowPublicAndInternals();
                logger.Info?.Invoke("InternalsVisibleTo attributes found, using AllowPublicAndInternals entity filter");
            }
            else
            {
                importer.Filter = new AllowPublic();
                logger.Info?.Invoke("Using AllowPublic entity filter");
            }

            var mvidBlob = importer.Import();

            logger.Debug?.Invoke($"Building reference assembly");

            var metaRootBuilder = new MetadataRootBuilder(metaBuilder, metaReader.MetadataVersion, true);

            var peHeaderBuilder = new PEHeaderBuilder(
                peReader.PEHeaders.CoffHeader.Machine,
                peReader.PEHeaders.PEHeader.SectionAlignment,
                peReader.PEHeaders.PEHeader.FileAlignment,
                peReader.PEHeaders.PEHeader.ImageBase,
                peReader.PEHeaders.PEHeader.MajorLinkerVersion,
                peReader.PEHeaders.PEHeader.MinorLinkerVersion,
                peReader.PEHeaders.PEHeader.MajorOperatingSystemVersion,
                peReader.PEHeaders.PEHeader.MinorOperatingSystemVersion,
                peReader.PEHeaders.PEHeader.MajorImageVersion,
                peReader.PEHeaders.PEHeader.MinorImageVersion,
                peReader.PEHeaders.PEHeader.MajorSubsystemVersion,
                peReader.PEHeaders.PEHeader.MinorSubsystemVersion,
                peReader.PEHeaders.PEHeader.Subsystem,
                peReader.PEHeaders.PEHeader.DllCharacteristics,
                peReader.PEHeaders.CoffHeader.Characteristics,
                peReader.PEHeaders.PEHeader.SizeOfStackReserve,
                peReader.PEHeaders.PEHeader.SizeOfStackCommit,
                peReader.PEHeaders.PEHeader.SizeOfHeapReserve,
                peReader.PEHeaders.PEHeader.SizeOfHeapCommit
                );

            var ilStream = new BlobBuilder();

            var peBuilder = new ManagedPEBuilder(peHeaderBuilder, metaRootBuilder, ilStream,
                                                 deterministicIdProvider: blobs =>
            {
                var hasher = IncrementalHash.CreateHash(HashAlgorithmName.SHA256) ?? throw new Exception("Cannot create hasher");

                foreach (var segment in blobs.Select(b => b.GetBytes()))
                {
                    hasher.AppendData(segment.Array, segment.Offset, segment.Count);
                }

                return(BlobContentId.FromHash(hasher.GetHashAndReset()));
            });

            var blobBuilder = new BlobBuilder();
            var contentId   = peBuilder.Serialize(blobBuilder);

            mvidBlob.CreateWriter().WriteGuid(contentId.Guid);

            return(blobBuilder.ToArray());
        }
Пример #23
0
        internal static bool WritePeToStream(
            EmitContext context,
            CommonMessageProvider messageProvider,
            Func <Stream> getPeStream,
            Func <Stream> getPortablePdbStreamOpt,
            PdbWriter nativePdbWriterOpt,
            string pdbPathOpt,
            bool metadataOnly,
            bool isDeterministic,
            bool emitTestCoverageData,
            RSAParameters?privateKeyOpt,
            CancellationToken cancellationToken)
        {
            // If PDB writer is given, we have to have PDB path.
            Debug.Assert(nativePdbWriterOpt == null || pdbPathOpt != null);

            var mdWriter = FullMetadataWriter.Create(context, messageProvider, metadataOnly, isDeterministic,
                                                     emitTestCoverageData, getPortablePdbStreamOpt != null, cancellationToken);

            var properties = context.Module.SerializationProperties;

            nativePdbWriterOpt?.SetMetadataEmitter(mdWriter);

            // Since we are producing a full assembly, we should not have a module version ID
            // imposed ahead-of time. Instead we will compute a deterministic module version ID
            // based on the contents of the generated stream.
            Debug.Assert(properties.PersistentIdentifier == default(Guid));

            var ilBuilder = new BlobBuilder(32 * 1024);
            var mappedFieldDataBuilder = new BlobBuilder();
            var managedResourceBuilder = new BlobBuilder(1024);

            Blob mvidFixup, mvidStringFixup;

            mdWriter.BuildMetadataAndIL(
                nativePdbWriterOpt,
                ilBuilder,
                mappedFieldDataBuilder,
                managedResourceBuilder,
                out mvidFixup,
                out mvidStringFixup);

            MethodDefinitionHandle entryPointHandle;
            MethodDefinitionHandle debugEntryPointHandle;

            mdWriter.GetEntryPoints(out entryPointHandle, out debugEntryPointHandle);

            if (!debugEntryPointHandle.IsNil)
            {
                nativePdbWriterOpt?.SetEntryPoint(MetadataTokens.GetToken(debugEntryPointHandle));
            }

            if (nativePdbWriterOpt != null)
            {
                if (context.Module.SourceLinkStreamOpt != null)
                {
                    nativePdbWriterOpt.EmbedSourceLink(context.Module.SourceLinkStreamOpt);
                }

                if (mdWriter.Module.OutputKind == OutputKind.WindowsRuntimeMetadata)
                {
                    // Dev12: If compiling to winmdobj, we need to add to PDB source spans of
                    //        all types and members for better error reporting by WinMDExp.
                    nativePdbWriterOpt.WriteDefinitionLocations(mdWriter.Module.GetSymbolToLocationMap());
                }
                else
                {
#if DEBUG
                    // validate that all definitions are writable
                    // if same scenario would happen in an winmdobj project
                    nativePdbWriterOpt.AssertAllDefinitionsHaveTokens(mdWriter.Module.GetSymbolToLocationMap());
#endif
                }

                nativePdbWriterOpt.WriteRemainingEmbeddedDocuments(mdWriter.Module.DebugDocumentsBuilder.EmbeddedDocuments);
            }

            Stream peStream = getPeStream();
            if (peStream == null)
            {
                return(false);
            }

            BlobContentId pdbContentId = nativePdbWriterOpt?.GetContentId() ?? default;

            // the writer shall not be used after this point for writing:
            nativePdbWriterOpt = null;

            ushort portablePdbVersion  = 0;
            var    metadataRootBuilder = mdWriter.GetRootBuilder();

            var peHeaderBuilder = new PEHeaderBuilder(
                machine: properties.Machine,
                sectionAlignment: properties.SectionAlignment,
                fileAlignment: properties.FileAlignment,
                imageBase: properties.BaseAddress,
                majorLinkerVersion: properties.LinkerMajorVersion,
                minorLinkerVersion: properties.LinkerMinorVersion,
                majorOperatingSystemVersion: 4,
                minorOperatingSystemVersion: 0,
                majorImageVersion: 0,
                minorImageVersion: 0,
                majorSubsystemVersion: properties.MajorSubsystemVersion,
                minorSubsystemVersion: properties.MinorSubsystemVersion,
                subsystem: properties.Subsystem,
                dllCharacteristics: properties.DllCharacteristics,
                imageCharacteristics: properties.ImageCharacteristics,
                sizeOfStackReserve: properties.SizeOfStackReserve,
                sizeOfStackCommit: properties.SizeOfStackCommit,
                sizeOfHeapReserve: properties.SizeOfHeapReserve,
                sizeOfHeapCommit: properties.SizeOfHeapCommit);

            // TODO: replace SHA1 with non-crypto alg: https://github.com/dotnet/roslyn/issues/24737
            var peIdProvider = isDeterministic ?
                               new Func <IEnumerable <Blob>, BlobContentId>(content => BlobContentId.FromHash(CryptographicHashProvider.ComputeHash(HashAlgorithmName.SHA1, content))) :
                               null;

            // We need to calculate the PDB checksum, so we may as well use the calculated hash for PDB ID regardless of whether deterministic build is requested.
            var portablePdbContentHash = default(ImmutableArray <byte>);

            BlobBuilder portablePdbToEmbed = null;
            if (mdWriter.EmitPortableDebugMetadata)
            {
                mdWriter.AddRemainingEmbeddedDocuments(mdWriter.Module.DebugDocumentsBuilder.EmbeddedDocuments);

                // The algorithm must be specified for deterministic builds (checked earlier).
                Debug.Assert(!isDeterministic || context.Module.PdbChecksumAlgorithm.Name != null);

                var portablePdbIdProvider = (context.Module.PdbChecksumAlgorithm.Name != null) ?
                                            new Func <IEnumerable <Blob>, BlobContentId>(content => BlobContentId.FromHash(portablePdbContentHash = CryptographicHashProvider.ComputeHash(context.Module.PdbChecksumAlgorithm, content))) :
                                            null;

                var portablePdbBlob    = new BlobBuilder();
                var portablePdbBuilder = mdWriter.GetPortablePdbBuilder(metadataRootBuilder.Sizes.RowCounts, debugEntryPointHandle, portablePdbIdProvider);
                pdbContentId       = portablePdbBuilder.Serialize(portablePdbBlob);
                portablePdbVersion = portablePdbBuilder.FormatVersion;

                if (getPortablePdbStreamOpt == null)
                {
                    // embed to debug directory:
                    portablePdbToEmbed = portablePdbBlob;
                }
                else
                {
                    // write to Portable PDB stream:
                    Stream portablePdbStream = getPortablePdbStreamOpt();
                    if (portablePdbStream != null)
                    {
                        try
                        {
                            portablePdbBlob.WriteContentTo(portablePdbStream);
                        }
                        catch (Exception e) when(!(e is OperationCanceledException))
                        {
                            throw new SymUnmanagedWriterException(e.Message, e);
                        }
                    }
                }
            }

            DebugDirectoryBuilder debugDirectoryBuilder;
            if (pdbPathOpt != null || isDeterministic || portablePdbToEmbed != null)
            {
                debugDirectoryBuilder = new DebugDirectoryBuilder();
                if (pdbPathOpt != null)
                {
                    string paddedPath = isDeterministic ? pdbPathOpt : PadPdbPath(pdbPathOpt);
                    debugDirectoryBuilder.AddCodeViewEntry(paddedPath, pdbContentId, portablePdbVersion);

                    if (!portablePdbContentHash.IsDefault)
                    {
                        // Emit PDB Checksum entry for Portable and Embedded PDBs. The checksum is not as useful when the PDB is embedded,
                        // however it allows the client to efficiently validate a standalone Portable PDB that
                        // has been extracted from Embedded PDB and placed next to the PE file.
                        debugDirectoryBuilder.AddPdbChecksumEntry(context.Module.PdbChecksumAlgorithm.Name, portablePdbContentHash);
                    }
                }

                if (isDeterministic)
                {
                    debugDirectoryBuilder.AddReproducibleEntry();
                }

                if (portablePdbToEmbed != null)
                {
                    debugDirectoryBuilder.AddEmbeddedPortablePdbEntry(portablePdbToEmbed, portablePdbVersion);
                }
            }
            else
            {
                debugDirectoryBuilder = null;
            }

            var strongNameProvider = context.Module.CommonCompilation.Options.StrongNameProvider;
            var corFlags           = properties.CorFlags;

            var peBuilder = new ExtendedPEBuilder(
                peHeaderBuilder,
                metadataRootBuilder,
                ilBuilder,
                mappedFieldDataBuilder,
                managedResourceBuilder,
                CreateNativeResourceSectionSerializer(context.Module),
                debugDirectoryBuilder,
                CalculateStrongNameSignatureSize(context.Module, privateKeyOpt),
                entryPointHandle,
                corFlags,
                peIdProvider,
                metadataOnly && !context.IncludePrivateMembers);

            var peBlob      = new BlobBuilder();
            var peContentId = peBuilder.Serialize(peBlob, out Blob mvidSectionFixup);

            PatchModuleVersionIds(mvidFixup, mvidSectionFixup, mvidStringFixup, peContentId.Guid);

            if (privateKeyOpt != null && corFlags.HasFlag(CorFlags.StrongNameSigned))
            {
                Debug.Assert(strongNameProvider.Capability == SigningCapability.SignsPeBuilder);
                strongNameProvider.SignPeBuilder(peBuilder, peBlob, privateKeyOpt.Value);
            }

            try
            {
                peBlob.WriteContentTo(peStream);
            }
            catch (Exception e) when(!(e is OperationCanceledException))
            {
                throw new PeWritingException(e);
            }

            return(true);
        }
Пример #24
0
        public void ManagedPEBuilder_Errors()
        {
            var hdr = new PEHeaderBuilder();
            var ms = new MetadataRootBuilder(new MetadataBuilder());
            var il = new BlobBuilder();

            Assert.Throws<ArgumentNullException>(() => new ManagedPEBuilder(null, ms, il));
            Assert.Throws<ArgumentNullException>(() => new ManagedPEBuilder(hdr, null, il));
            Assert.Throws<ArgumentNullException>(() => new ManagedPEBuilder(hdr, ms, null));
            Assert.Throws<ArgumentOutOfRangeException>(() => new ManagedPEBuilder(hdr, ms, il, strongNameSignatureSize: -1));
        }
Пример #25
0
        public static bool WritePeToStream(
            EmitContext context,
            CommonMessageProvider messageProvider,
            Func <Stream> getPeStream,
            Func <Stream> getPortablePdbStreamOpt,
            PdbWriter nativePdbWriterOpt,
            string pdbPathOpt,
            bool allowMissingMethodBodies,
            bool isDeterministic,
            CancellationToken cancellationToken)
        {
            // If PDB writer is given, we have to have PDB path.
            Debug.Assert(nativePdbWriterOpt == null || pdbPathOpt != null);

            var mdWriter = FullMetadataWriter.Create(context, messageProvider, allowMissingMethodBodies, isDeterministic, getPortablePdbStreamOpt != null, cancellationToken);

            var properties = context.Module.Properties;

            nativePdbWriterOpt?.SetMetadataEmitter(mdWriter);

            // Since we are producing a full assembly, we should not have a module version ID
            // imposed ahead-of time. Instead we will compute a deterministic module version ID
            // based on the contents of the generated stream.
            Debug.Assert(properties.PersistentIdentifier == default(Guid));

            var ilBuilder = new BlobBuilder(32 * 1024);
            var mappedFieldDataBuilder = new BlobBuilder();
            var managedResourceBuilder = new BlobBuilder(1024);

            Blob mvidFixup;

            mdWriter.BuildMetadataAndIL(
                nativePdbWriterOpt,
                ilBuilder,
                mappedFieldDataBuilder,
                managedResourceBuilder,
                out mvidFixup);

            MethodDefinitionHandle entryPointHandle;
            MethodDefinitionHandle debugEntryPointHandle;

            mdWriter.GetEntryPoints(out entryPointHandle, out debugEntryPointHandle);

            if (!debugEntryPointHandle.IsNil)
            {
                nativePdbWriterOpt?.SetEntryPoint((uint)MetadataTokens.GetToken(debugEntryPointHandle));
            }

            if (nativePdbWriterOpt != null)
            {
                var assembly = mdWriter.Module.AsAssembly;
                if (assembly != null && assembly.Kind == OutputKind.WindowsRuntimeMetadata)
                {
                    // Dev12: If compiling to winmdobj, we need to add to PDB source spans of
                    //        all types and members for better error reporting by WinMDExp.
                    nativePdbWriterOpt.WriteDefinitionLocations(mdWriter.Module.GetSymbolToLocationMap());
                }
                else
                {
#if DEBUG
                    // validate that all definitions are writable
                    // if same scenario would happen in an winmdobj project
                    nativePdbWriterOpt.AssertAllDefinitionsHaveTokens(mdWriter.Module.GetSymbolToLocationMap());
#endif
                }
            }

            Stream peStream = getPeStream();
            if (peStream == null)
            {
                return(false);
            }

            BlobContentId pdbContentId = nativePdbWriterOpt?.GetContentId() ?? default(BlobContentId);

            // the writer shall not be used after this point for writing:
            nativePdbWriterOpt = null;

            ushort portablePdbVersion = 0;
            var    metadataSerializer = mdWriter.GetTypeSystemMetadataSerializer();

            var peHeaderBuilder = new PEHeaderBuilder(
                machine: properties.Machine,
                sectionAlignment: properties.SectionAlignment,
                fileAlignment: properties.FileAlignment,
                imageBase: properties.BaseAddress,
                majorLinkerVersion: properties.LinkerMajorVersion,
                minorLinkerVersion: properties.LinkerMinorVersion,
                majorOperatingSystemVersion: 4,
                minorOperatingSystemVersion: 0,
                majorImageVersion: 0,
                minorImageVersion: 0,
                majorSubsystemVersion: properties.MajorSubsystemVersion,
                minorSubsystemVersion: properties.MinorSubsystemVersion,
                subsystem: properties.Subsystem,
                dllCharacteristics: properties.DllCharacteristics,
                imageCharacteristics: properties.ImageCharacteristics,
                sizeOfStackReserve: properties.SizeOfStackReserve,
                sizeOfStackCommit: properties.SizeOfStackCommit,
                sizeOfHeapReserve: properties.SizeOfHeapReserve,
                sizeOfHeapCommit: properties.SizeOfHeapCommit);

            var deterministicIdProvider = isDeterministic ?
                                          new Func <IEnumerable <Blob>, BlobContentId>(content => BlobContentId.FromHash(CryptographicHashProvider.ComputeSha1(content))) :
                                          null;

            if (mdWriter.EmitStandaloneDebugMetadata)
            {
                Debug.Assert(getPortablePdbStreamOpt != null);

                var debugMetadataBuilder    = new BlobBuilder();
                var debugMetadataSerializer = mdWriter.GetStandaloneDebugMetadataSerializer(metadataSerializer.MetadataSizes, debugEntryPointHandle, deterministicIdProvider);
                debugMetadataSerializer.SerializeMetadata(debugMetadataBuilder, out pdbContentId);
                portablePdbVersion = debugMetadataSerializer.FormatVersion;

                // write to Portable PDB stream:
                Stream portablePdbStream = getPortablePdbStreamOpt();
                if (portablePdbStream != null)
                {
                    debugMetadataBuilder.WriteContentTo(portablePdbStream);
                }
            }

            DebugDirectoryBuilder debugDirectoryBuilder;
            if (pdbPathOpt != null || isDeterministic)
            {
                debugDirectoryBuilder = new DebugDirectoryBuilder();
                if (pdbPathOpt != null)
                {
                    string paddedPath = isDeterministic ? pdbPathOpt : PadPdbPath(pdbPathOpt);
                    debugDirectoryBuilder.AddCodeViewEntry(paddedPath, pdbContentId, portablePdbVersion);
                }

                if (isDeterministic)
                {
                    debugDirectoryBuilder.AddReproducibleEntry();
                }
            }
            else
            {
                debugDirectoryBuilder = null;
            }

            var peBuilder = new ManagedPEBuilder(
                peHeaderBuilder,
                metadataSerializer,
                ilBuilder,
                mappedFieldDataBuilder,
                managedResourceBuilder,
                CreateNativeResourceSectionSerializer(context.Module),
                debugDirectoryBuilder,
                CalculateStrongNameSignatureSize(context.Module),
                entryPointHandle,
                properties.CorFlags,
                deterministicIdProvider);

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

            // Patch MVID
            if (!mvidFixup.IsDefault)
            {
                var writer = new BlobWriter(mvidFixup);
                writer.WriteGuid(peContentId.Guid);
                Debug.Assert(writer.RemainingBytes == 0);
            }

            try
            {
                peBlob.WriteContentTo(peStream);
            }
            catch (Exception e) when(!(e is OperationCanceledException))
            {
                throw new PeWritingException(e);
            }

            return(true);
        }
Пример #26
0
        public byte[] GenerateAssemblyBytes()
        {
            if (_currentAssembly.EntryPoint != null)
            {
                // See "<Module>" type definition below.
                throw new NotSupportedException("Entry point is not supported.");
            }

            var name = _currentAssembly.GetName();

            var assemblyPublicKey = name.GetPublicKey();
            var assemblyHandle    = _metadataBuilder.AddAssembly(
                GetString(name.Name),
                name.Version,
                GetString(name.CultureName),
                assemblyPublicKey.Length > 0 ? GetBlob(name.GetPublicKey()) : default(BlobHandle),
                ConvertGeneratedAssemblyNameFlags(name),
                ConvertAssemblyHashAlgorithm(name.HashAlgorithm));

            // Add "<Module>" type definition *before* any type definition.
            //
            // TODO: [osman] methodList argument should be as following:
            //
            //   methodList: entryPoint.IsNil ? MetadataTokens.MethodDefinitionHandle(1) : entryPoint
            //
            // But, in order to work above code, we need to serialize
            // entry point *without* serializing any type definition.
            // This is not needed for libraries since they don't have any entry point.
            _metadataBuilder.AddTypeDefinition(
                default(TypeAttributes),
                default(StringHandle),
                GetString("<Module>"),
                default(EntityHandle),
                MetadataTokens.FieldDefinitionHandle(1),
                MetadataTokens.MethodDefinitionHandle(1));

            CreateReferencedAssemblies(_currentAssembly.GetReferencedAssemblies());
            CreateCustomAttributes(assemblyHandle, _currentAssembly.GetCustomAttributesData());

            CreateModules(_currentAssembly.GetModules());
            CreateTypes(_currentAssembly.GetTypes());

            var entryPoint = GetMethodDefinitionHandle(_currentAssembly.EntryPoint);

            var metadataRootBuilder = new MetadataRootBuilder(_metadataBuilder);

            // Without Characteristics.ExecutableImage flag, .NET runtime refuses
            // to load an assembly even it's a DLL. PEHeaderBuilder.CreateLibraryHeader
            // does not set this flag. So, we set it explicitly.
            var header = new PEHeaderBuilder(imageCharacteristics: Characteristics.ExecutableImage |
                                             (entryPoint.IsNil ? Characteristics.Dll : 0));

            var peBuilder = new ManagedPEBuilder(
                header,
                metadataRootBuilder,
                _ilBuilder,
                debugDirectoryBuilder: _debugDirectoryBuilder,
                entryPoint: entryPoint);

            var peImageBuilder = new BlobBuilder();

            peBuilder.Serialize(peImageBuilder);

            return(peImageBuilder.ToArray());
        }