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); }
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); }
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; }
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()); }
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); } }
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)); }
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)); }
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); }
/// <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]; }
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); }
/// <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; }
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()); }
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); }
/// <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()); }
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)); }
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()); }
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); }
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)); }
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); }
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()); }
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()); }
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); }
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)); }
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); }
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()); }