| File: ClearAssemblyReferenceVersions.cs | Web Access |
| Project: src\arcade\src\Microsoft.DotNet.GenFacades\Microsoft.DotNet.GenFacades.csproj (Microsoft.DotNet.GenFacades) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.Build.Framework; using Microsoft.Build.Utilities; using Microsoft.DotNet.Build.Tasks; using System; using System.IO; using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; using System.Reflection.PortableExecutable; namespace Microsoft.DotNet.GenFacades { /// <summary> /// Rewrites an Assembly's references to be version 0.0.0.0. /// </summary> public class ClearAssemblyReferenceVersions : BuildTask { /// <summary> /// Assembly to rewrite. /// </summary> [Required] public string Assembly { get; set; } public override bool Execute() { try { using (FileStream stream = File.Open(Assembly, FileMode.Open, FileAccess.ReadWrite, FileShare.Read)) using (PEReader peReader = new PEReader(stream)) { using (BinaryWriter writer = new BinaryWriter(stream)) { MetadataReader mdReader = peReader.GetMetadataReader(); int assemblyRefOffset = mdReader.GetTableMetadataOffset(TableIndex.AssemblyRef); int numAssemblyRef = mdReader.GetTableRowCount(TableIndex.AssemblyRef); int sizeAssemblyRefRow = mdReader.GetTableRowSize(TableIndex.AssemblyRef); for (int assemblyRefRow = 0; assemblyRefRow < numAssemblyRef; assemblyRefRow++) { stream.Position = peReader.PEHeaders.MetadataStartOffset + assemblyRefOffset + assemblyRefRow * sizeAssemblyRefRow; // see ECMA-335 II.22.5 // row starts with // - MajorVersion, MinorVersion, BuildNumber, RevisionNumber (each being 2-byte constants) // 8 bytes total -> long writer.Write((long)0); } // remove signature, if present, since we changed the binary which would break any signature. // adapted from https://github.com/dotnet/arcade/blob/866b2acd5ffc3c2031c102f6415fd7c6a1a370d5/src/Microsoft.DotNet.Arcade.Sdk/src/Unsign.cs#L58-L65 if (peReader.PEHeaders.PEHeader.CertificateTableDirectory.Size != 0) { // see https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#optional-header-data-directories-image-only int certificateTableDirectoryOffset = (peReader.PEHeaders.PEHeader.Magic == PEMagic.PE32Plus) ? 144 : 128; stream.Position = peReader.PEHeaders.PEHeaderStartOffset + certificateTableDirectoryOffset; writer.Write((long)0); } } } } catch (Exception e) { Log.LogErrorFromException(e, showStackTrace: false); } return !Log.HasLoggedErrors; } } }