Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of System Reflection Metadata v5.0.0
BepInEx/core/System.Reflection.Metadata/netstandard2.1/System.Reflection.Metadata.dll
Decompiled a year ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Collections.Immutable; using System.ComponentModel; using System.Configuration.Assemblies; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.IO.Compression; using System.IO.MemoryMappedFiles; using System.Reflection; using System.Reflection.Internal; using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; using System.Reflection.PortableExecutable; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.ConstrainedExecution; using System.Runtime.ExceptionServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using FxResources.System.Reflection.Metadata; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: InternalsVisibleTo("System.Reflection.Metadata.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001004b86c4cb78549b34bab61a3b1800e23bfeb5b3ec390074041536a7e3cbd97f5f04cf0f857155a8928eaa29ebfd11cfbbad3ba70efea7bda3226c6a8d370a4cd303f714486b6ebc225985a638471e6ef571cc92a4613c00b8fa65d61ccee0cbe5f36330c9a01f4183559f1bef24cc2917c6d913e3a541333a1d05d9bed22b38cb")] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = "")] [assembly: AssemblyDefaultAlias("System.Reflection.Metadata")] [assembly: NeutralResourcesLanguage("en-US")] [assembly: AssemblyMetadata(".NETFrameworkAssembly", "")] [assembly: AssemblyMetadata("Serviceable", "True")] [assembly: AssemblyMetadata("PreferInbox", "True")] [assembly: AssemblyCompany("Microsoft Corporation")] [assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] [assembly: AssemblyDescription("System.Reflection.Metadata")] [assembly: AssemblyFileVersion("5.0.20.51904")] [assembly: AssemblyInformationalVersion("5.0.0+cf258a14b70ad9069470a108f13765e0e5988f51")] [assembly: AssemblyProduct("Microsoft® .NET")] [assembly: AssemblyTitle("System.Reflection.Metadata")] [assembly: AssemblyMetadata("RepositoryUrl", "git://github.com/dotnet/runtime")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("5.0.0.0")] [module: UnverifiableCode] [module: System.Runtime.CompilerServices.NullablePublicOnly(true)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class NullablePublicOnlyAttribute : Attribute { public readonly bool IncludesInternals; public NullablePublicOnlyAttribute(bool P_0) { IncludesInternals = P_0; } } } internal static class Interop { internal static class Libraries { internal const string Advapi32 = "advapi32.dll"; internal const string BCrypt = "BCrypt.dll"; internal const string Crypt32 = "crypt32.dll"; internal const string CryptUI = "cryptui.dll"; internal const string Gdi32 = "gdi32.dll"; internal const string HttpApi = "httpapi.dll"; internal const string IpHlpApi = "iphlpapi.dll"; internal const string Kernel32 = "kernel32.dll"; internal const string Mswsock = "mswsock.dll"; internal const string NCrypt = "ncrypt.dll"; internal const string NtDll = "ntdll.dll"; internal const string Odbc32 = "odbc32.dll"; internal const string Ole32 = "ole32.dll"; internal const string OleAut32 = "oleaut32.dll"; internal const string PerfCounter = "perfcounter.dll"; internal const string Secur32 = "secur32.dll"; internal const string Shell32 = "shell32.dll"; internal const string SspiCli = "sspicli.dll"; internal const string User32 = "user32.dll"; internal const string Version = "version.dll"; internal const string WebSocket = "websocket.dll"; internal const string WinHttp = "winhttp.dll"; internal const string WinMM = "winmm.dll"; internal const string Wldap32 = "wldap32.dll"; internal const string Ws2_32 = "ws2_32.dll"; internal const string Wtsapi32 = "wtsapi32.dll"; internal const string CompressionNative = "clrcompression.dll"; internal const string MsQuic = "msquic.dll"; internal const string HostPolicy = "hostpolicy.dll"; } internal static class Kernel32 { [DllImport("kernel32.dll", SetLastError = true)] internal unsafe static extern int ReadFile(SafeHandle handle, byte* bytes, int numBytesToRead, out int numBytesRead, IntPtr mustBeZero); } } namespace FxResources.System.Reflection.Metadata { internal static class SR { } } namespace System { internal static class SR { private static readonly bool s_usingResourceKeys = AppContext.TryGetSwitch("System.Resources.UseSystemResourceKeys", out var isEnabled) && isEnabled; private static ResourceManager s_resourceManager; internal static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(typeof(SR))); internal static string ImageTooSmall => GetResourceString("ImageTooSmall"); internal static string InvalidCorHeaderSize => GetResourceString("InvalidCorHeaderSize"); internal static string InvalidHandle => GetResourceString("InvalidHandle"); internal static string UnexpectedHandleKind => GetResourceString("UnexpectedHandleKind"); internal static string UnexpectedOpCode => GetResourceString("UnexpectedOpCode"); internal static string InvalidLocalSignatureToken => GetResourceString("InvalidLocalSignatureToken"); internal static string InvalidMetadataSectionSpan => GetResourceString("InvalidMetadataSectionSpan"); internal static string InvalidMethodHeader1 => GetResourceString("InvalidMethodHeader1"); internal static string InvalidMethodHeader2 => GetResourceString("InvalidMethodHeader2"); internal static string InvalidPESignature => GetResourceString("InvalidPESignature"); internal static string InvalidSehHeader => GetResourceString("InvalidSehHeader"); internal static string InvalidToken => GetResourceString("InvalidToken"); internal static string MetadataImageDoesNotRepresentAnAssembly => GetResourceString("MetadataImageDoesNotRepresentAnAssembly"); internal static string StandaloneDebugMetadataImageDoesNotContainModuleTable => GetResourceString("StandaloneDebugMetadataImageDoesNotContainModuleTable"); internal static string PEImageNotAvailable => GetResourceString("PEImageNotAvailable"); internal static string MissingDataDirectory => GetResourceString("MissingDataDirectory"); internal static string NotMetadataHeapHandle => GetResourceString("NotMetadataHeapHandle"); internal static string NotMetadataTableOrUserStringHandle => GetResourceString("NotMetadataTableOrUserStringHandle"); internal static string SectionTooSmall => GetResourceString("SectionTooSmall"); internal static string StreamMustSupportReadAndSeek => GetResourceString("StreamMustSupportReadAndSeek"); internal static string UnknownFileFormat => GetResourceString("UnknownFileFormat"); internal static string UnknownPEMagicValue => GetResourceString("UnknownPEMagicValue"); internal static string MetadataTableNotSorted => GetResourceString("MetadataTableNotSorted"); internal static string ModuleTableInvalidNumberOfRows => GetResourceString("ModuleTableInvalidNumberOfRows"); internal static string UnknownTables => GetResourceString("UnknownTables"); internal static string IllegalTablesInCompressedMetadataStream => GetResourceString("IllegalTablesInCompressedMetadataStream"); internal static string TableRowCountSpaceTooSmall => GetResourceString("TableRowCountSpaceTooSmall"); internal static string OutOfBoundsRead => GetResourceString("OutOfBoundsRead"); internal static string OutOfBoundsWrite => GetResourceString("OutOfBoundsWrite"); internal static string MetadataHeaderTooSmall => GetResourceString("MetadataHeaderTooSmall"); internal static string MetadataSignature => GetResourceString("MetadataSignature"); internal static string NotEnoughSpaceForVersionString => GetResourceString("NotEnoughSpaceForVersionString"); internal static string StreamHeaderTooSmall => GetResourceString("StreamHeaderTooSmall"); internal static string NotEnoughSpaceForStreamHeaderName => GetResourceString("NotEnoughSpaceForStreamHeaderName"); internal static string NotEnoughSpaceForStringStream => GetResourceString("NotEnoughSpaceForStringStream"); internal static string NotEnoughSpaceForBlobStream => GetResourceString("NotEnoughSpaceForBlobStream"); internal static string NotEnoughSpaceForGUIDStream => GetResourceString("NotEnoughSpaceForGUIDStream"); internal static string NotEnoughSpaceForMetadataStream => GetResourceString("NotEnoughSpaceForMetadataStream"); internal static string InvalidMetadataStreamFormat => GetResourceString("InvalidMetadataStreamFormat"); internal static string MetadataTablesTooSmall => GetResourceString("MetadataTablesTooSmall"); internal static string MetadataTableHeaderTooSmall => GetResourceString("MetadataTableHeaderTooSmall"); internal static string WinMDMissingMscorlibRef => GetResourceString("WinMDMissingMscorlibRef"); internal static string UnexpectedStreamEnd => GetResourceString("UnexpectedStreamEnd"); internal static string InvalidMethodRva => GetResourceString("InvalidMethodRva"); internal static string CantGetOffsetForVirtualHeapHandle => GetResourceString("CantGetOffsetForVirtualHeapHandle"); internal static string InvalidNumberOfSections => GetResourceString("InvalidNumberOfSections"); internal static string InvalidSignature => GetResourceString("InvalidSignature"); internal static string PEImageDoesNotHaveMetadata => GetResourceString("PEImageDoesNotHaveMetadata"); internal static string InvalidCodedIndex => GetResourceString("InvalidCodedIndex"); internal static string InvalidCompressedInteger => GetResourceString("InvalidCompressedInteger"); internal static string InvalidDocumentName => GetResourceString("InvalidDocumentName"); internal static string RowIdOrHeapOffsetTooLarge => GetResourceString("RowIdOrHeapOffsetTooLarge"); internal static string EnCMapNotSorted => GetResourceString("EnCMapNotSorted"); internal static string InvalidSerializedString => GetResourceString("InvalidSerializedString"); internal static string StreamTooLarge => GetResourceString("StreamTooLarge"); internal static string ImageTooSmallOrContainsInvalidOffsetOrCount => GetResourceString("ImageTooSmallOrContainsInvalidOffsetOrCount"); internal static string MetadataStringDecoderEncodingMustBeUtf8 => GetResourceString("MetadataStringDecoderEncodingMustBeUtf8"); internal static string InvalidConstantValue => GetResourceString("InvalidConstantValue"); internal static string InvalidConstantValueOfType => GetResourceString("InvalidConstantValueOfType"); internal static string InvalidImportDefinitionKind => GetResourceString("InvalidImportDefinitionKind"); internal static string ValueTooLarge => GetResourceString("ValueTooLarge"); internal static string BlobTooLarge => GetResourceString("BlobTooLarge"); internal static string InvalidTypeSize => GetResourceString("InvalidTypeSize"); internal static string HandleBelongsToFutureGeneration => GetResourceString("HandleBelongsToFutureGeneration"); internal static string InvalidRowCount => GetResourceString("InvalidRowCount"); internal static string InvalidEntryPointToken => GetResourceString("InvalidEntryPointToken"); internal static string TooManySubnamespaces => GetResourceString("TooManySubnamespaces"); internal static string TooManyExceptionRegions => GetResourceString("TooManyExceptionRegions"); internal static string SequencePointValueOutOfRange => GetResourceString("SequencePointValueOutOfRange"); internal static string InvalidDirectoryRVA => GetResourceString("InvalidDirectoryRVA"); internal static string InvalidDirectorySize => GetResourceString("InvalidDirectorySize"); internal static string InvalidDebugDirectoryEntryCharacteristics => GetResourceString("InvalidDebugDirectoryEntryCharacteristics"); internal static string UnexpectedCodeViewDataSignature => GetResourceString("UnexpectedCodeViewDataSignature"); internal static string UnexpectedEmbeddedPortablePdbDataSignature => GetResourceString("UnexpectedEmbeddedPortablePdbDataSignature"); internal static string InvalidPdbChecksumDataFormat => GetResourceString("InvalidPdbChecksumDataFormat"); internal static string UnexpectedSignatureHeader => GetResourceString("UnexpectedSignatureHeader"); internal static string UnexpectedSignatureHeader2 => GetResourceString("UnexpectedSignatureHeader2"); internal static string NotTypeDefOrRefHandle => GetResourceString("NotTypeDefOrRefHandle"); internal static string UnexpectedSignatureTypeCode => GetResourceString("UnexpectedSignatureTypeCode"); internal static string SignatureTypeSequenceMustHaveAtLeastOneElement => GetResourceString("SignatureTypeSequenceMustHaveAtLeastOneElement"); internal static string NotTypeDefOrRefOrSpecHandle => GetResourceString("NotTypeDefOrRefOrSpecHandle"); internal static string UnexpectedDebugDirectoryType => GetResourceString("UnexpectedDebugDirectoryType"); internal static string HeapSizeLimitExceeded => GetResourceString("HeapSizeLimitExceeded"); internal static string BuilderMustAligned => GetResourceString("BuilderMustAligned"); internal static string BuilderAlreadyLinked => GetResourceString("BuilderAlreadyLinked"); internal static string ReturnedBuilderSizeTooSmall => GetResourceString("ReturnedBuilderSizeTooSmall"); internal static string SignatureNotVarArg => GetResourceString("SignatureNotVarArg"); internal static string LabelDoesntBelongToBuilder => GetResourceString("LabelDoesntBelongToBuilder"); internal static string ControlFlowBuilderNotAvailable => GetResourceString("ControlFlowBuilderNotAvailable"); internal static string BaseReaderMustBeFullMetadataReader => GetResourceString("BaseReaderMustBeFullMetadataReader"); internal static string ModuleAlreadyAdded => GetResourceString("ModuleAlreadyAdded"); internal static string AssemblyAlreadyAdded => GetResourceString("AssemblyAlreadyAdded"); internal static string ExpectedListOfSize => GetResourceString("ExpectedListOfSize"); internal static string ExpectedArrayOfSize => GetResourceString("ExpectedArrayOfSize"); internal static string ExpectedNonEmptyList => GetResourceString("ExpectedNonEmptyList"); internal static string ExpectedNonEmptyArray => GetResourceString("ExpectedNonEmptyArray"); internal static string ExpectedNonEmptyString => GetResourceString("ExpectedNonEmptyString"); internal static string ReadersMustBeDeltaReaders => GetResourceString("ReadersMustBeDeltaReaders"); internal static string SignatureProviderReturnedInvalidSignature => GetResourceString("SignatureProviderReturnedInvalidSignature"); internal static string UnknownSectionName => GetResourceString("UnknownSectionName"); internal static string HashTooShort => GetResourceString("HashTooShort"); internal static string UnexpectedArrayLength => GetResourceString("UnexpectedArrayLength"); internal static string ValueMustBeMultiple => GetResourceString("ValueMustBeMultiple"); internal static string MustNotReturnNull => GetResourceString("MustNotReturnNull"); internal static string MetadataVersionTooLong => GetResourceString("MetadataVersionTooLong"); internal static string RowCountMustBeZero => GetResourceString("RowCountMustBeZero"); internal static string RowCountOutOfRange => GetResourceString("RowCountOutOfRange"); internal static string SizeMismatch => GetResourceString("SizeMismatch"); internal static string DataTooBig => GetResourceString("DataTooBig"); internal static string UnsupportedFormatVersion => GetResourceString("UnsupportedFormatVersion"); internal static string DistanceBetweenInstructionAndLabelTooBig => GetResourceString("DistanceBetweenInstructionAndLabelTooBig"); internal static string LabelNotMarked => GetResourceString("LabelNotMarked"); internal static string MethodHasNoExceptionRegions => GetResourceString("MethodHasNoExceptionRegions"); internal static string InvalidExceptionRegionBounds => GetResourceString("InvalidExceptionRegionBounds"); internal static string UnexpectedValue => GetResourceString("UnexpectedValue"); internal static string UnexpectedValueUnknownType => GetResourceString("UnexpectedValueUnknownType"); internal static string UnreachableLocation => GetResourceString("UnreachableLocation"); private static bool UsingResourceKeys() { return s_usingResourceKeys; } internal static string GetResourceString(string resourceKey, string? defaultString = null) { if (UsingResourceKeys()) { return defaultString ?? resourceKey; } string text = null; try { text = ResourceManager.GetString(resourceKey); } catch (MissingManifestResourceException) { } if (defaultString != null && resourceKey.Equals(text)) { return defaultString; } return text; } internal static string Format(string resourceFormat, object? p1) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1); } return string.Format(resourceFormat, p1); } internal static string Format(string resourceFormat, object? p1, object? p2) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1, p2); } return string.Format(resourceFormat, p1, p2); } internal static string Format(string resourceFormat, object? p1, object? p2, object? p3) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1, p2, p3); } return string.Format(resourceFormat, p1, p2, p3); } internal static string Format(string resourceFormat, params object?[]? args) { if (args != null) { if (UsingResourceKeys()) { return resourceFormat + ", " + string.Join(", ", args); } return string.Format(resourceFormat, args); } return resourceFormat; } internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1); } return string.Format(provider, resourceFormat, p1); } internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1, object? p2) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1, p2); } return string.Format(provider, resourceFormat, p1, p2); } internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1, object? p2, object? p3) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1, p2, p3); } return string.Format(provider, resourceFormat, p1, p2, p3); } internal static string Format(IFormatProvider? provider, string resourceFormat, params object?[]? args) { if (args != null) { if (UsingResourceKeys()) { return resourceFormat + ", " + string.Join(", ", args); } return string.Format(provider, resourceFormat, args); } return resourceFormat; } } } namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)] internal sealed class AllowNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)] internal sealed class DisallowNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)] internal sealed class MaybeNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)] internal sealed class NotNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] internal sealed class MaybeNullWhenAttribute : Attribute { public bool ReturnValue { get; } public MaybeNullWhenAttribute(bool returnValue) { ReturnValue = returnValue; } } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] internal sealed class NotNullWhenAttribute : Attribute { public bool ReturnValue { get; } public NotNullWhenAttribute(bool returnValue) { ReturnValue = returnValue; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)] internal sealed class NotNullIfNotNullAttribute : Attribute { public string ParameterName { get; } public NotNullIfNotNullAttribute(string parameterName) { ParameterName = parameterName; } } [AttributeUsage(AttributeTargets.Method, Inherited = false)] internal sealed class DoesNotReturnAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] internal sealed class DoesNotReturnIfAttribute : Attribute { public bool ParameterValue { get; } public DoesNotReturnIfAttribute(bool parameterValue) { ParameterValue = parameterValue; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] internal sealed class MemberNotNullAttribute : Attribute { public string[] Members { get; } public MemberNotNullAttribute(string member) { Members = new string[1] { member }; } public MemberNotNullAttribute(params string[] members) { Members = members; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] internal sealed class MemberNotNullWhenAttribute : Attribute { public bool ReturnValue { get; } public string[] Members { get; } public MemberNotNullWhenAttribute(bool returnValue, string member) { ReturnValue = returnValue; Members = new string[1] { member }; } public MemberNotNullWhenAttribute(bool returnValue, params string[] members) { ReturnValue = returnValue; Members = members; } } } namespace System.Reflection { internal static class BlobUtilities { public const int SizeOfSerializedDecimal = 13; public const int SizeOfGuid = 16; public unsafe static byte[] ReadBytes(byte* buffer, int byteCount) { if (byteCount == 0) { return EmptyArray<byte>.Instance; } byte[] array = new byte[byteCount]; Marshal.Copy((IntPtr)buffer, array, 0, byteCount); return array; } public unsafe static ImmutableArray<byte> ReadImmutableBytes(byte* buffer, int byteCount) { byte[] array = ReadBytes(buffer, byteCount); return ImmutableByteArrayInterop.DangerousCreateFromUnderlyingArray(ref array); } public unsafe static void WriteBytes(this byte[] buffer, int start, byte value, int byteCount) { fixed (byte* ptr = &buffer[0]) { byte* ptr2 = ptr + start; for (int i = 0; i < byteCount; i++) { ptr2[i] = value; } } } public unsafe static void WriteDouble(this byte[] buffer, int start, double value) { buffer.WriteUInt64(start, *(ulong*)(&value)); } public unsafe static void WriteSingle(this byte[] buffer, int start, float value) { buffer.WriteUInt32(start, *(uint*)(&value)); } public static void WriteByte(this byte[] buffer, int start, byte value) { buffer[start] = value; } public unsafe static void WriteUInt16(this byte[] buffer, int start, ushort value) { fixed (byte* ptr = &buffer[start]) { *ptr = (byte)value; ptr[1] = (byte)(value >> 8); } } public unsafe static void WriteUInt16BE(this byte[] buffer, int start, ushort value) { fixed (byte* ptr = &buffer[start]) { *ptr = (byte)(value >> 8); ptr[1] = (byte)value; } } public unsafe static void WriteUInt32BE(this byte[] buffer, int start, uint value) { fixed (byte* ptr = &buffer[start]) { *ptr = (byte)(value >> 24); ptr[1] = (byte)(value >> 16); ptr[2] = (byte)(value >> 8); ptr[3] = (byte)value; } } public unsafe static void WriteUInt32(this byte[] buffer, int start, uint value) { fixed (byte* ptr = &buffer[start]) { *ptr = (byte)value; ptr[1] = (byte)(value >> 8); ptr[2] = (byte)(value >> 16); ptr[3] = (byte)(value >> 24); } } public static void WriteUInt64(this byte[] buffer, int start, ulong value) { buffer.WriteUInt32(start, (uint)value); buffer.WriteUInt32(start + 4, (uint)(value >> 32)); } public static void WriteDecimal(this byte[] buffer, int start, decimal value) { value.GetBits(out var isNegative, out var scale, out var low, out var mid, out var high); buffer.WriteByte(start, (byte)(scale | (isNegative ? 128u : 0u))); buffer.WriteUInt32(start + 1, low); buffer.WriteUInt32(start + 5, mid); buffer.WriteUInt32(start + 9, high); } public unsafe static void WriteGuid(this byte[] buffer, int start, Guid value) { fixed (byte* ptr2 = &buffer[start]) { byte* ptr = (byte*)(&value); uint num = *(uint*)ptr; *ptr2 = (byte)num; ptr2[1] = (byte)(num >> 8); ptr2[2] = (byte)(num >> 16); ptr2[3] = (byte)(num >> 24); ushort num2 = *(ushort*)(ptr + 4); ptr2[4] = (byte)num2; ptr2[5] = (byte)(num2 >> 8); ushort num3 = *(ushort*)(ptr + 6); ptr2[6] = (byte)num3; ptr2[7] = (byte)(num3 >> 8); ptr2[8] = ptr[8]; ptr2[9] = ptr[9]; ptr2[10] = ptr[10]; ptr2[11] = ptr[11]; ptr2[12] = ptr[12]; ptr2[13] = ptr[13]; ptr2[14] = ptr[14]; ptr2[15] = ptr[15]; } } public unsafe static void WriteUTF8(this byte[] buffer, int start, char* charPtr, int charCount, int byteCount, bool allowUnpairedSurrogates) { char* ptr = charPtr + charCount; fixed (byte* ptr2 = &buffer[0]) { byte* ptr3 = ptr2 + start; if (byteCount == charCount) { while (charPtr < ptr) { *(ptr3++) = (byte)(*(charPtr++)); } return; } while (charPtr < ptr) { char c = *(charPtr++); if (c < '\u0080') { *(ptr3++) = (byte)c; continue; } if (c < 'ࠀ') { *ptr3 = (byte)(((uint)((int)c >> 6) & 0x1Fu) | 0xC0u); ptr3[1] = (byte)((c & 0x3Fu) | 0x80u); ptr3 += 2; continue; } if (IsSurrogateChar(c)) { if (IsHighSurrogateChar(c) && charPtr < ptr && IsLowSurrogateChar(*charPtr)) { int num = c; int num2 = *(charPtr++); int num3 = (num - 55296 << 10) + num2 - 56320 + 65536; *ptr3 = (byte)(((uint)(num3 >> 18) & 7u) | 0xF0u); ptr3[1] = (byte)(((uint)(num3 >> 12) & 0x3Fu) | 0x80u); ptr3[2] = (byte)(((uint)(num3 >> 6) & 0x3Fu) | 0x80u); ptr3[3] = (byte)(((uint)num3 & 0x3Fu) | 0x80u); ptr3 += 4; continue; } if (!allowUnpairedSurrogates) { c = '\ufffd'; } } *ptr3 = (byte)(((uint)((int)c >> 12) & 0xFu) | 0xE0u); ptr3[1] = (byte)(((uint)((int)c >> 6) & 0x3Fu) | 0x80u); ptr3[2] = (byte)((c & 0x3Fu) | 0x80u); ptr3 += 3; } } } internal unsafe static int GetUTF8ByteCount(string str) { fixed (char* str2 = str) { return GetUTF8ByteCount(str2, str.Length); } } internal unsafe static int GetUTF8ByteCount(char* str, int charCount) { char* remainder; return GetUTF8ByteCount(str, charCount, int.MaxValue, out remainder); } internal unsafe static int GetUTF8ByteCount(char* str, int charCount, int byteLimit, out char* remainder) { char* ptr = str + charCount; char* ptr2 = str; int num = 0; while (ptr2 < ptr) { char c = *(ptr2++); int num2; if (c < '\u0080') { num2 = 1; } else if (c < 'ࠀ') { num2 = 2; } else if (IsHighSurrogateChar(c) && ptr2 < ptr && IsLowSurrogateChar(*ptr2)) { num2 = 4; ptr2++; } else { num2 = 3; } if (num + num2 > byteLimit) { ptr2 -= ((num2 < 4) ? 1 : 2); break; } num += num2; } remainder = ptr2; return num; } internal static bool IsSurrogateChar(int c) { return (uint)(c - 55296) <= 2047u; } internal static bool IsHighSurrogateChar(int c) { return (uint)(c - 55296) <= 1023u; } internal static bool IsLowSurrogateChar(int c) { return (uint)(c - 56320) <= 1023u; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void ValidateRange(int bufferLength, int start, int byteCount, string byteCountParameterName) { if (start < 0 || start > bufferLength) { Throw.ArgumentOutOfRange("start"); } if (byteCount < 0 || byteCount > bufferLength - start) { Throw.ArgumentOutOfRange(byteCountParameterName); } } internal static int GetUserStringByteLength(int characterCount) { return characterCount * 2 + 1; } internal static byte GetUserStringTrailingByte(string str) { foreach (char c in str) { if (c >= '\u007f') { return 1; } switch (c) { case '\u0001': case '\u0002': case '\u0003': case '\u0004': case '\u0005': case '\u0006': case '\a': case '\b': case '\u000e': case '\u000f': case '\u0010': case '\u0011': case '\u0012': case '\u0013': case '\u0014': case '\u0015': case '\u0016': case '\u0017': case '\u0018': case '\u0019': case '\u001a': case '\u001b': case '\u001c': case '\u001d': case '\u001e': case '\u001f': case '\'': case '-': return 1; } } return 0; } } internal static class Throw { [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void InvalidCast() { throw new InvalidCastException(); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void InvalidArgument(string message, string parameterName) { throw new ArgumentException(message, parameterName); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void InvalidArgument_OffsetForVirtualHeapHandle() { throw new ArgumentException(System.SR.CantGetOffsetForVirtualHeapHandle, "handle"); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static Exception InvalidArgument_UnexpectedHandleKind(HandleKind kind) { throw new ArgumentException(System.SR.Format(System.SR.UnexpectedHandleKind, kind)); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static Exception InvalidArgument_Handle(string parameterName) { throw new ArgumentException(System.SR.InvalidHandle, parameterName); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void SignatureNotVarArg() { throw new InvalidOperationException(System.SR.SignatureNotVarArg); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void ControlFlowBuilderNotAvailable() { throw new InvalidOperationException(System.SR.ControlFlowBuilderNotAvailable); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void InvalidOperationBuilderAlreadyLinked() { throw new InvalidOperationException(System.SR.BuilderAlreadyLinked); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void InvalidOperation(string message) { throw new InvalidOperationException(message); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void InvalidOperation_LabelNotMarked(int id) { throw new InvalidOperationException(System.SR.Format(System.SR.LabelNotMarked, id)); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void LabelDoesntBelongToBuilder(string parameterName) { throw new ArgumentException(System.SR.LabelDoesntBelongToBuilder, parameterName); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void HeapHandleRequired() { throw new ArgumentException(System.SR.NotMetadataHeapHandle, "handle"); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void EntityOrUserStringHandleRequired() { throw new ArgumentException(System.SR.NotMetadataTableOrUserStringHandle, "handle"); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void InvalidToken() { throw new ArgumentException(System.SR.InvalidToken, "token"); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void ArgumentNull(string parameterName) { throw new ArgumentNullException(parameterName); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void ArgumentEmptyString(string parameterName) { throw new ArgumentException(System.SR.ExpectedNonEmptyString, parameterName); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void ArgumentEmptyArray(string parameterName) { throw new ArgumentException(System.SR.ExpectedNonEmptyArray, parameterName); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void ValueArgumentNull() { throw new ArgumentNullException("value"); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void BuilderArgumentNull() { throw new ArgumentNullException("builder"); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void ArgumentOutOfRange(string parameterName) { throw new ArgumentOutOfRangeException(parameterName); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void ArgumentOutOfRange(string parameterName, string message) { throw new ArgumentOutOfRangeException(parameterName, message); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void BlobTooLarge(string parameterName) { throw new ArgumentOutOfRangeException(parameterName, System.SR.BlobTooLarge); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void IndexOutOfRange() { throw new ArgumentOutOfRangeException("index"); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void TableIndexOutOfRange() { throw new ArgumentOutOfRangeException("tableIndex"); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void ValueArgumentOutOfRange() { throw new ArgumentOutOfRangeException("value"); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void OutOfBounds() { throw new BadImageFormatException(System.SR.OutOfBoundsRead); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void WriteOutOfBounds() { throw new InvalidOperationException(System.SR.OutOfBoundsWrite); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void InvalidCodedIndex() { throw new BadImageFormatException(System.SR.InvalidCodedIndex); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void InvalidHandle() { throw new BadImageFormatException(System.SR.InvalidHandle); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void InvalidCompressedInteger() { throw new BadImageFormatException(System.SR.InvalidCompressedInteger); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void InvalidSerializedString() { throw new BadImageFormatException(System.SR.InvalidSerializedString); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void ImageTooSmall() { throw new BadImageFormatException(System.SR.ImageTooSmall); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void ImageTooSmallOrContainsInvalidOffsetOrCount() { throw new BadImageFormatException(System.SR.ImageTooSmallOrContainsInvalidOffsetOrCount); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void ReferenceOverflow() { throw new BadImageFormatException(System.SR.RowIdOrHeapOffsetTooLarge); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void TableNotSorted(TableIndex tableIndex) { throw new BadImageFormatException(System.SR.Format(System.SR.MetadataTableNotSorted, tableIndex)); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void InvalidOperation_TableNotSorted(TableIndex tableIndex) { throw new InvalidOperationException(System.SR.Format(System.SR.MetadataTableNotSorted, tableIndex)); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void InvalidOperation_PEImageNotAvailable() { throw new InvalidOperationException(System.SR.PEImageNotAvailable); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void TooManySubnamespaces() { throw new BadImageFormatException(System.SR.TooManySubnamespaces); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void ValueOverflow() { throw new BadImageFormatException(System.SR.ValueTooLarge); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void SequencePointValueOutOfRange() { throw new BadImageFormatException(System.SR.SequencePointValueOutOfRange); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void HeapSizeLimitExceeded(HeapIndex heap) { throw new ImageFormatLimitationException(System.SR.Format(System.SR.HeapSizeLimitExceeded, heap)); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] internal static void PEReaderDisposed() { throw new ObjectDisposedException("PEReader"); } } [Flags] public enum MethodSemanticsAttributes { Setter = 1, Getter = 2, Other = 4, Adder = 8, Remover = 0x10, Raiser = 0x20 } public enum DeclarativeSecurityAction : short { None = 0, Demand = 2, Assert = 3, Deny = 4, PermitOnly = 5, LinkDemand = 6, InheritanceDemand = 7, RequestMinimum = 8, RequestOptional = 9, RequestRefuse = 10 } [Flags] public enum MethodImportAttributes : short { None = 0, ExactSpelling = 1, BestFitMappingDisable = 0x20, BestFitMappingEnable = 0x10, BestFitMappingMask = 0x30, CharSetAnsi = 2, CharSetUnicode = 4, CharSetAuto = 6, CharSetMask = 6, ThrowOnUnmappableCharEnable = 0x1000, ThrowOnUnmappableCharDisable = 0x2000, ThrowOnUnmappableCharMask = 0x3000, SetLastError = 0x40, CallingConventionWinApi = 0x100, CallingConventionCDecl = 0x200, CallingConventionStdCall = 0x300, CallingConventionThisCall = 0x400, CallingConventionFastCall = 0x500, CallingConventionMask = 0x700 } [Flags] public enum ManifestResourceAttributes { Public = 1, Private = 2, VisibilityMask = 7 } public enum AssemblyHashAlgorithm { None = 0, MD5 = 32771, Sha1 = 32772, Sha256 = 32780, Sha384 = 32781, Sha512 = 32782 } [Flags] public enum AssemblyFlags { PublicKey = 1, Retargetable = 0x100, WindowsRuntime = 0x200, ContentTypeMask = 0xE00, DisableJitCompileOptimizer = 0x4000, EnableJitCompileTracking = 0x8000 } internal static class TypeAttributesExtensions { private const TypeAttributes Forwarder = (TypeAttributes)2097152; private const TypeAttributes NestedMask = TypeAttributes.NestedFamANDAssem; public static bool IsForwarder(this TypeAttributes flags) { return (flags & (TypeAttributes)2097152) != 0; } public static bool IsNested(this TypeAttributes flags) { return (flags & TypeAttributes.NestedFamANDAssem) != 0; } } } namespace System.Reflection.PortableExecutable { public class ManagedPEBuilder : PEBuilder { public const int ManagedResourcesDataAlignment = 8; public const int MappedFieldDataAlignment = 8; private const int DefaultStrongNameSignatureSize = 128; private const string TextSectionName = ".text"; private const string ResourceSectionName = ".rsrc"; private const string RelocationSectionName = ".reloc"; private readonly PEDirectoriesBuilder _peDirectoriesBuilder; private readonly MetadataRootBuilder _metadataRootBuilder; private readonly BlobBuilder _ilStream; private readonly BlobBuilder _mappedFieldDataOpt; private readonly BlobBuilder _managedResourcesOpt; private readonly ResourceSectionBuilder _nativeResourcesOpt; private readonly int _strongNameSignatureSize; private readonly MethodDefinitionHandle _entryPointOpt; private readonly DebugDirectoryBuilder _debugDirectoryBuilderOpt; private readonly CorFlags _corFlags; private int _lazyEntryPointAddress; private Blob _lazyStrongNameSignature; public ManagedPEBuilder(PEHeaderBuilder header, MetadataRootBuilder metadataRootBuilder, BlobBuilder ilStream, BlobBuilder? mappedFieldData = null, BlobBuilder? managedResources = null, ResourceSectionBuilder? nativeResources = null, DebugDirectoryBuilder? debugDirectoryBuilder = null, int strongNameSignatureSize = 128, MethodDefinitionHandle entryPoint = default(MethodDefinitionHandle), CorFlags flags = CorFlags.ILOnly, Func<IEnumerable<Blob>, BlobContentId>? deterministicIdProvider = null) : base(header, deterministicIdProvider) { if (header == null) { Throw.ArgumentNull("header"); } if (metadataRootBuilder == null) { Throw.ArgumentNull("metadataRootBuilder"); } if (ilStream == null) { Throw.ArgumentNull("ilStream"); } if (strongNameSignatureSize < 0) { Throw.ArgumentOutOfRange("strongNameSignatureSize"); } _metadataRootBuilder = metadataRootBuilder; _ilStream = ilStream; _mappedFieldDataOpt = mappedFieldData; _managedResourcesOpt = managedResources; _nativeResourcesOpt = nativeResources; _strongNameSignatureSize = strongNameSignatureSize; _entryPointOpt = entryPoint; _debugDirectoryBuilderOpt = debugDirectoryBuilder ?? CreateDefaultDebugDirectoryBuilder(); _corFlags = flags; _peDirectoriesBuilder = new PEDirectoriesBuilder(); } private DebugDirectoryBuilder CreateDefaultDebugDirectoryBuilder() { if (base.IsDeterministic) { DebugDirectoryBuilder debugDirectoryBuilder = new DebugDirectoryBuilder(); debugDirectoryBuilder.AddReproducibleEntry(); return debugDirectoryBuilder; } return null; } protected override ImmutableArray<Section> CreateSections() { ImmutableArray<Section>.Builder builder = ImmutableArray.CreateBuilder<Section>(3); builder.Add(new Section(".text", SectionCharacteristics.ContainsCode | SectionCharacteristics.MemExecute | SectionCharacteristics.MemRead)); if (_nativeResourcesOpt != null) { builder.Add(new Section(".rsrc", SectionCharacteristics.ContainsInitializedData | SectionCharacteristics.MemRead)); } if (base.Header.Machine == Machine.I386 || base.Header.Machine == Machine.Unknown) { builder.Add(new Section(".reloc", SectionCharacteristics.ContainsInitializedData | SectionCharacteristics.MemDiscardable | SectionCharacteristics.MemRead)); } return builder.ToImmutable(); } protected override BlobBuilder SerializeSection(string name, SectionLocation location) { return name switch { ".text" => SerializeTextSection(location), ".rsrc" => SerializeResourceSection(location), ".reloc" => SerializeRelocationSection(location), _ => throw new ArgumentException(System.SR.Format(System.SR.UnknownSectionName, name), "name"), }; } private BlobBuilder SerializeTextSection(SectionLocation location) { BlobBuilder blobBuilder = new BlobBuilder(); BlobBuilder blobBuilder2 = new BlobBuilder(); MetadataSizes sizes = _metadataRootBuilder.Sizes; ManagedTextSection managedTextSection = new ManagedTextSection(base.Header.ImageCharacteristics, base.Header.Machine, _ilStream.Count, sizes.MetadataSize, _managedResourcesOpt?.Count ?? 0, _strongNameSignatureSize, _debugDirectoryBuilderOpt?.Size ?? 0, _mappedFieldDataOpt?.Count ?? 0); int methodBodyStreamRva = location.RelativeVirtualAddress + managedTextSection.OffsetToILStream; int mappedFieldDataStreamRva = location.RelativeVirtualAddress + managedTextSection.CalculateOffsetToMappedFieldDataStream(); _metadataRootBuilder.Serialize(blobBuilder2, methodBodyStreamRva, mappedFieldDataStreamRva); BlobBuilder blobBuilder3; DirectoryEntry debugTable; if (_debugDirectoryBuilderOpt != null) { int num = managedTextSection.ComputeOffsetToDebugDirectory(); blobBuilder3 = new BlobBuilder(_debugDirectoryBuilderOpt.TableSize); _debugDirectoryBuilderOpt.Serialize(blobBuilder3, location, num); debugTable = new DirectoryEntry(location.RelativeVirtualAddress + num, _debugDirectoryBuilderOpt.TableSize); } else { blobBuilder3 = null; debugTable = default(DirectoryEntry); } _lazyEntryPointAddress = managedTextSection.GetEntryPointAddress(location.RelativeVirtualAddress); managedTextSection.Serialize(blobBuilder, location.RelativeVirtualAddress, (!_entryPointOpt.IsNil) ? MetadataTokens.GetToken(_entryPointOpt) : 0, _corFlags, base.Header.ImageBase, blobBuilder2, _ilStream, _mappedFieldDataOpt, _managedResourcesOpt, blobBuilder3, out _lazyStrongNameSignature); _peDirectoriesBuilder.AddressOfEntryPoint = _lazyEntryPointAddress; _peDirectoriesBuilder.DebugTable = debugTable; _peDirectoriesBuilder.ImportAddressTable = managedTextSection.GetImportAddressTableDirectoryEntry(location.RelativeVirtualAddress); _peDirectoriesBuilder.ImportTable = managedTextSection.GetImportTableDirectoryEntry(location.RelativeVirtualAddress); _peDirectoriesBuilder.CorHeaderTable = managedTextSection.GetCorHeaderDirectoryEntry(location.RelativeVirtualAddress); return blobBuilder; } private BlobBuilder SerializeResourceSection(SectionLocation location) { BlobBuilder blobBuilder = new BlobBuilder(); _nativeResourcesOpt.Serialize(blobBuilder, location); _peDirectoriesBuilder.ResourceTable = new DirectoryEntry(location.RelativeVirtualAddress, blobBuilder.Count); return blobBuilder; } private BlobBuilder SerializeRelocationSection(SectionLocation location) { BlobBuilder blobBuilder = new BlobBuilder(); WriteRelocationSection(blobBuilder, base.Header.Machine, _lazyEntryPointAddress); _peDirectoriesBuilder.BaseRelocationTable = new DirectoryEntry(location.RelativeVirtualAddress, blobBuilder.Count); return blobBuilder; } private static void WriteRelocationSection(BlobBuilder builder, Machine machine, int entryPointAddress) { builder.WriteUInt32((uint)(entryPointAddress + 2) / 4096u * 4096); builder.WriteUInt32((machine == Machine.IA64) ? 14u : 12u); uint num = (uint)(entryPointAddress + 2) % 4096u; uint num2 = ((machine == Machine.Amd64 || machine == Machine.IA64 || machine == Machine.Arm64) ? 10u : 3u); ushort value = (ushort)((num2 << 12) | num); builder.WriteUInt16(value); if (machine == Machine.IA64) { builder.WriteUInt32(num2 << 12); } builder.WriteUInt16(0); } protected internal override PEDirectoriesBuilder GetDirectories() { return _peDirectoriesBuilder; } public void Sign(BlobBuilder peImage, Func<IEnumerable<Blob>, byte[]> signatureProvider) { if (peImage == null) { Throw.ArgumentNull("peImage"); } if (signatureProvider == null) { Throw.ArgumentNull("signatureProvider"); } Sign(peImage, _lazyStrongNameSignature, signatureProvider); } } internal sealed class ManagedTextSection { public const int ManagedResourcesDataAlignment = 8; private const string CorEntryPointDll = "mscoree.dll"; public const int MappedFieldDataAlignment = 8; private const int CorHeaderSize = 72; public Characteristics ImageCharacteristics { get; } public Machine Machine { get; } public int ILStreamSize { get; } public int MetadataSize { get; } public int ResourceDataSize { get; } public int StrongNameSignatureSize { get; } public int DebugDataSize { get; } public int MappedFieldDataSize { get; } internal bool RequiresStartupStub { get { if (Machine != Machine.I386) { return Machine == Machine.Unknown; } return true; } } internal bool Requires64bits { get { if (Machine != Machine.Amd64 && Machine != Machine.IA64) { return Machine == Machine.Arm64; } return true; } } public bool Is32Bit => !Requires64bits; private string CorEntryPointName { get { if ((ImageCharacteristics & Characteristics.Dll) == 0) { return "_CorExeMain"; } return "_CorDllMain"; } } private int SizeOfImportAddressTable { get { if (!RequiresStartupStub) { return 0; } if (!Is32Bit) { return 16; } return 8; } } private int SizeOfImportTable => 40 + (Is32Bit ? 12 : 16) + 2 + CorEntryPointName.Length + 1; private static int SizeOfNameTable => "mscoree.dll".Length + 1 + 2; private int SizeOfRuntimeStartupStub { get { if (!Is32Bit) { return 16; } return 8; } } public int OffsetToILStream => SizeOfImportAddressTable + 72; public ManagedTextSection(Characteristics imageCharacteristics, Machine machine, int ilStreamSize, int metadataSize, int resourceDataSize, int strongNameSignatureSize, int debugDataSize, int mappedFieldDataSize) { MetadataSize = metadataSize; ResourceDataSize = resourceDataSize; ILStreamSize = ilStreamSize; MappedFieldDataSize = mappedFieldDataSize; StrongNameSignatureSize = strongNameSignatureSize; ImageCharacteristics = imageCharacteristics; Machine = machine; DebugDataSize = debugDataSize; } public int CalculateOffsetToMappedFieldDataStream() { int num = ComputeOffsetToImportTable(); if (RequiresStartupStub) { num += SizeOfImportTable + SizeOfNameTable; num = BitArithmetic.Align(num, Is32Bit ? 4 : 8); num += SizeOfRuntimeStartupStub; } return num; } internal int ComputeOffsetToDebugDirectory() { return ComputeOffsetToMetadata() + MetadataSize + ResourceDataSize + StrongNameSignatureSize; } private int ComputeOffsetToImportTable() { return ComputeOffsetToDebugDirectory() + DebugDataSize; } private int ComputeOffsetToMetadata() { return OffsetToILStream + BitArithmetic.Align(ILStreamSize, 4); } public int ComputeSizeOfTextSection() { return CalculateOffsetToMappedFieldDataStream() + MappedFieldDataSize; } public int GetEntryPointAddress(int rva) { if (!RequiresStartupStub) { return 0; } return rva + CalculateOffsetToMappedFieldDataStream() - (Is32Bit ? 6 : 10); } public DirectoryEntry GetImportAddressTableDirectoryEntry(int rva) { if (!RequiresStartupStub) { return default(DirectoryEntry); } return new DirectoryEntry(rva, SizeOfImportAddressTable); } public DirectoryEntry GetImportTableDirectoryEntry(int rva) { if (!RequiresStartupStub) { return default(DirectoryEntry); } return new DirectoryEntry(rva + ComputeOffsetToImportTable(), (Is32Bit ? 66 : 70) + 13); } public DirectoryEntry GetCorHeaderDirectoryEntry(int rva) { return new DirectoryEntry(rva + SizeOfImportAddressTable, 72); } public void Serialize(BlobBuilder builder, int relativeVirtualAddess, int entryPointTokenOrRelativeVirtualAddress, CorFlags corFlags, ulong baseAddress, BlobBuilder metadataBuilder, BlobBuilder ilBuilder, BlobBuilder? mappedFieldDataBuilderOpt, BlobBuilder? resourceBuilderOpt, BlobBuilder? debugDataBuilderOpt, out Blob strongNameSignature) { int relativeVirtualAddress = GetImportTableDirectoryEntry(relativeVirtualAddess).RelativeVirtualAddress; int relativeVirtualAddress2 = GetImportAddressTableDirectoryEntry(relativeVirtualAddess).RelativeVirtualAddress; if (RequiresStartupStub) { WriteImportAddressTable(builder, relativeVirtualAddress); } WriteCorHeader(builder, relativeVirtualAddess, entryPointTokenOrRelativeVirtualAddress, corFlags); ilBuilder.Align(4); builder.LinkSuffix(ilBuilder); builder.LinkSuffix(metadataBuilder); if (resourceBuilderOpt != null) { builder.LinkSuffix(resourceBuilderOpt); } strongNameSignature = builder.ReserveBytes(StrongNameSignatureSize); new BlobWriter(strongNameSignature).WriteBytes(0, StrongNameSignatureSize); if (debugDataBuilderOpt != null) { builder.LinkSuffix(debugDataBuilderOpt); } if (RequiresStartupStub) { WriteImportTable(builder, relativeVirtualAddress, relativeVirtualAddress2); WriteNameTable(builder); WriteRuntimeStartupStub(builder, relativeVirtualAddress2, baseAddress); } if (mappedFieldDataBuilderOpt != null) { builder.LinkSuffix(mappedFieldDataBuilderOpt); } } private void WriteImportAddressTable(BlobBuilder builder, int importTableRva) { int count = builder.Count; int num = importTableRva + 40; int num2 = num + (Is32Bit ? 12 : 16); if (Is32Bit) { builder.WriteUInt32((uint)num2); builder.WriteUInt32(0u); } else { builder.WriteUInt64((uint)num2); builder.WriteUInt64(0uL); } } private void WriteImportTable(BlobBuilder builder, int importTableRva, int importAddressTableRva) { int count = builder.Count; int num = importTableRva + 40; int num2 = num + (Is32Bit ? 12 : 16); int value = num2 + 12 + 2; builder.WriteUInt32((uint)num); builder.WriteUInt32(0u); builder.WriteUInt32(0u); builder.WriteUInt32((uint)value); builder.WriteUInt32((uint)importAddressTableRva); builder.WriteBytes(0, 20); if (Is32Bit) { builder.WriteUInt32((uint)num2); builder.WriteUInt32(0u); builder.WriteUInt32(0u); } else { builder.WriteUInt64((uint)num2); builder.WriteUInt64(0uL); } builder.WriteUInt16(0); string corEntryPointName = CorEntryPointName; foreach (char c in corEntryPointName) { builder.WriteByte((byte)c); } builder.WriteByte(0); } private static void WriteNameTable(BlobBuilder builder) { int count = builder.Count; string text = "mscoree.dll"; foreach (char c in text) { builder.WriteByte((byte)c); } builder.WriteByte(0); builder.WriteUInt16(0); } private void WriteCorHeader(BlobBuilder builder, int textSectionRva, int entryPointTokenOrRva, CorFlags corFlags) { int num = textSectionRva + ComputeOffsetToMetadata(); int num2 = num + MetadataSize; int num3 = num2 + ResourceDataSize; int count = builder.Count; builder.WriteUInt32(72u); builder.WriteUInt16(2); builder.WriteUInt16(5); builder.WriteUInt32((uint)num); builder.WriteUInt32((uint)MetadataSize); builder.WriteUInt32((uint)corFlags); builder.WriteUInt32((uint)entryPointTokenOrRva); builder.WriteUInt32((ResourceDataSize != 0) ? ((uint)num2) : 0u); builder.WriteUInt32((uint)ResourceDataSize); builder.WriteUInt32((StrongNameSignatureSize != 0) ? ((uint)num3) : 0u); builder.WriteUInt32((uint)StrongNameSignatureSize); builder.WriteUInt32(0u); builder.WriteUInt32(0u); builder.WriteUInt32(0u); builder.WriteUInt32(0u); builder.WriteUInt32(0u); builder.WriteUInt32(0u); builder.WriteUInt32(0u); builder.WriteUInt32(0u); } private void WriteRuntimeStartupStub(BlobBuilder sectionBuilder, int importAddressTableRva, ulong baseAddress) { if (Is32Bit) { sectionBuilder.Align(4); sectionBuilder.WriteUInt16(0); sectionBuilder.WriteByte(byte.MaxValue); sectionBuilder.WriteByte(37); sectionBuilder.WriteUInt32((uint)(importAddressTableRva + (int)baseAddress)); } else { sectionBuilder.Align(8); sectionBuilder.WriteUInt32(0u); sectionBuilder.WriteUInt16(0); sectionBuilder.WriteByte(byte.MaxValue); sectionBuilder.WriteByte(37); sectionBuilder.WriteUInt64((ulong)importAddressTableRva + baseAddress); } } } public abstract class PEBuilder { protected readonly struct Section { public readonly string Name; public readonly SectionCharacteristics Characteristics; public Section(string name, SectionCharacteristics characteristics) { if (name == null) { Throw.ArgumentNull("name"); } Name = name; Characteristics = characteristics; } } private readonly struct SerializedSection { public readonly BlobBuilder Builder; public readonly string Name; public readonly SectionCharacteristics Characteristics; public readonly int RelativeVirtualAddress; public readonly int SizeOfRawData; public readonly int PointerToRawData; public int VirtualSize => Builder.Count; 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; } } private readonly Lazy<ImmutableArray<Section>> _lazySections; private Blob _lazyChecksum; private static readonly byte[] s_dosHeader = new byte[128] { 77, 90, 144, 0, 3, 0, 0, 0, 4, 0, 0, 0, 255, 255, 0, 0, 184, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 14, 31, 186, 14, 0, 180, 9, 205, 33, 184, 1, 76, 205, 33, 84, 104, 105, 115, 32, 112, 114, 111, 103, 114, 97, 109, 32, 99, 97, 110, 110, 111, 116, 32, 98, 101, 32, 114, 117, 110, 32, 105, 110, 32, 68, 79, 83, 32, 109, 111, 100, 101, 46, 13, 13, 10, 36, 0, 0, 0, 0, 0, 0, 0 }; internal static int DosHeaderSize = s_dosHeader.Length; public PEHeaderBuilder Header { get; } public Func<IEnumerable<Blob>, BlobContentId> IdProvider { get; } public bool IsDeterministic { get; } protected PEBuilder(PEHeaderBuilder header, Func<IEnumerable<Blob>, BlobContentId>? deterministicIdProvider) { if (header == null) { Throw.ArgumentNull("header"); } IdProvider = deterministicIdProvider ?? BlobContentId.GetTimeBasedProvider(); IsDeterministic = deterministicIdProvider != null; Header = header; _lazySections = new Lazy<ImmutableArray<Section>>(CreateSections); } protected ImmutableArray<Section> GetSections() { ImmutableArray<Section> value = _lazySections.Value; if (value.IsDefault) { throw new InvalidOperationException(System.SR.Format(System.SR.MustNotReturnNull, "CreateSections")); } return value; } protected abstract ImmutableArray<Section> CreateSections(); protected abstract BlobBuilder SerializeSection(string name, SectionLocation location); protected internal abstract PEDirectoriesBuilder GetDirectories(); public BlobContentId Serialize(BlobBuilder builder) { ImmutableArray<SerializedSection> immutableArray = SerializeSections(); PEDirectoriesBuilder directories = GetDirectories(); WritePESignature(builder); WriteCoffHeader(builder, immutableArray, out var stampFixup); WritePEHeader(builder, directories, immutableArray); WriteSectionHeaders(builder, immutableArray); builder.Align(Header.FileAlignment); ImmutableArray<SerializedSection>.Enumerator enumerator = immutableArray.GetEnumerator(); while (enumerator.MoveNext()) { builder.LinkSuffix(enumerator.Current.Builder); builder.Align(Header.FileAlignment); } BlobContentId result = IdProvider(builder.GetBlobs()); new BlobWriter(stampFixup).WriteUInt32(result.Stamp); return result; } private ImmutableArray<SerializedSection> SerializeSections() { ImmutableArray<Section> sections = GetSections(); ImmutableArray<SerializedSection>.Builder builder = ImmutableArray.CreateBuilder<SerializedSection>(sections.Length); int position = Header.ComputeSizeOfPEHeaders(sections.Length); int relativeVirtualAddress = BitArithmetic.Align(position, Header.SectionAlignment); int pointerToRawData = BitArithmetic.Align(position, Header.FileAlignment); ImmutableArray<Section>.Enumerator enumerator = sections.GetEnumerator(); while (enumerator.MoveNext()) { Section current = enumerator.Current; BlobBuilder blobBuilder = SerializeSection(current.Name, new SectionLocation(relativeVirtualAddress, pointerToRawData)); SerializedSection item = new SerializedSection(blobBuilder, current.Name, current.Characteristics, relativeVirtualAddress, BitArithmetic.Align(blobBuilder.Count, Header.FileAlignment), pointerToRawData); builder.Add(item); relativeVirtualAddress = BitArithmetic.Align(item.RelativeVirtualAddress + item.VirtualSize, Header.SectionAlignment); pointerToRawData = item.PointerToRawData + item.SizeOfRawData; } return builder.MoveToImmutable(); } private void WritePESignature(BlobBuilder builder) { builder.WriteBytes(s_dosHeader); builder.WriteUInt32(17744u); } private void WriteCoffHeader(BlobBuilder builder, ImmutableArray<SerializedSection> sections, out Blob stampFixup) { builder.WriteUInt16((ushort)((Header.Machine == Machine.Unknown) ? Machine.I386 : Header.Machine)); builder.WriteUInt16((ushort)sections.Length); stampFixup = builder.ReserveBytes(4); builder.WriteUInt32(0u); builder.WriteUInt32(0u); builder.WriteUInt16((ushort)PEHeader.Size(Header.Is32Bit)); builder.WriteUInt16((ushort)Header.ImageCharacteristics); } private void WritePEHeader(BlobBuilder builder, PEDirectoriesBuilder directories, ImmutableArray<SerializedSection> sections) { builder.WriteUInt16((ushort)(Header.Is32Bit ? 267 : 523)); builder.WriteByte(Header.MajorLinkerVersion); builder.WriteByte(Header.MinorLinkerVersion); builder.WriteUInt32((uint)SumRawDataSizes(sections, SectionCharacteristics.ContainsCode)); builder.WriteUInt32((uint)SumRawDataSizes(sections, SectionCharacteristics.ContainsInitializedData)); builder.WriteUInt32((uint)SumRawDataSizes(sections, SectionCharacteristics.ContainsUninitializedData)); builder.WriteUInt32((uint)directories.AddressOfEntryPoint); int num = IndexOfSection(sections, SectionCharacteristics.ContainsCode); builder.WriteUInt32((num != -1) ? ((uint)sections[num].RelativeVirtualAddress) : 0u); if (Header.Is32Bit) { int num2 = IndexOfSection(sections, SectionCharacteristics.ContainsInitializedData); builder.WriteUInt32((num2 != -1) ? ((uint)sections[num2].RelativeVirtualAddress) : 0u); builder.WriteUInt32((uint)Header.ImageBase); } else { builder.WriteUInt64(Header.ImageBase); } builder.WriteUInt32((uint)Header.SectionAlignment); builder.WriteUInt32((uint)Header.FileAlignment); builder.WriteUInt16(Header.MajorOperatingSystemVersion); builder.WriteUInt16(Header.MinorOperatingSystemVersion); builder.WriteUInt16(Header.MajorImageVersion); builder.WriteUInt16(Header.MinorImageVersion); builder.WriteUInt16(Header.MajorSubsystemVersion); builder.WriteUInt16(Header.MinorSubsystemVersion); builder.WriteUInt32(0u); SerializedSection serializedSection = sections[sections.Length - 1]; builder.WriteUInt32((uint)BitArithmetic.Align(serializedSection.RelativeVirtualAddress + serializedSection.VirtualSize, Header.SectionAlignment)); builder.WriteUInt32((uint)BitArithmetic.Align(Header.ComputeSizeOfPEHeaders(sections.Length), Header.FileAlignment)); _lazyChecksum = builder.ReserveBytes(4); new BlobWriter(_lazyChecksum).WriteUInt32(0u); builder.WriteUInt16((ushort)Header.Subsystem); builder.WriteUInt16((ushort)Header.DllCharacteristics); if (Header.Is32Bit) { builder.WriteUInt32((uint)Header.SizeOfStackReserve); builder.WriteUInt32((uint)Header.SizeOfStackCommit); builder.WriteUInt32((uint)Header.SizeOfHeapReserve); builder.WriteUInt32((uint)Header.SizeOfHeapCommit); } else { builder.WriteUInt64(Header.SizeOfStackReserve); builder.WriteUInt64(Header.SizeOfStackCommit); builder.WriteUInt64(Header.SizeOfHeapReserve); builder.WriteUInt64(Header.SizeOfHeapCommit); } builder.WriteUInt32(0u); builder.WriteUInt32(16u); builder.WriteUInt32((uint)directories.ExportTable.RelativeVirtualAddress); builder.WriteUInt32((uint)directories.ExportTable.Size); builder.WriteUInt32((uint)directories.ImportTable.RelativeVirtualAddress); builder.WriteUInt32((uint)directories.ImportTable.Size); builder.WriteUInt32((uint)directories.ResourceTable.RelativeVirtualAddress); builder.WriteUInt32((uint)directories.ResourceTable.Size); builder.WriteUInt32((uint)directories.ExceptionTable.RelativeVirtualAddress); builder.WriteUInt32((uint)directories.ExceptionTable.Size); builder.WriteUInt32(0u); builder.WriteUInt32(0u); builder.WriteUInt32((uint)directories.BaseRelocationTable.RelativeVirtualAddress); builder.WriteUInt32((uint)directories.BaseRelocationTable.Size); builder.WriteUInt32((uint)directories.DebugTable.RelativeVirtualAddress); builder.WriteUInt32((uint)directories.DebugTable.Size); builder.WriteUInt32((uint)directories.CopyrightTable.RelativeVirtualAddress); builder.WriteUInt32((uint)directories.CopyrightTable.Size); builder.WriteUInt32((uint)directories.GlobalPointerTable.RelativeVirtualAddress); builder.WriteUInt32((uint)directories.GlobalPointerTable.Size); builder.WriteUInt32((uint)directories.ThreadLocalStorageTable.RelativeVirtualAddress); builder.WriteUInt32((uint)directories.ThreadLocalStorageTable.Size); builder.WriteUInt32((uint)directories.LoadConfigTable.RelativeVirtualAddress); builder.WriteUInt32((uint)directories.LoadConfigTable.Size); builder.WriteUInt32((uint)directories.BoundImportTable.RelativeVirtualAddress); builder.WriteUInt32((uint)directories.BoundImportTable.Size); builder.WriteUInt32((uint)directories.ImportAddressTable.RelativeVirtualAddress); builder.WriteUInt32((uint)directories.ImportAddressTable.Size); builder.WriteUInt32((uint)directories.DelayImportTable.RelativeVirtualAddress); builder.WriteUInt32((uint)directories.DelayImportTable.Size); builder.WriteUInt32((uint)directories.CorHeaderTable.RelativeVirtualAddress); builder.WriteUInt32((uint)directories.CorHeaderTable.Size); builder.WriteUInt64(0uL); } private void WriteSectionHeaders(BlobBuilder builder, ImmutableArray<SerializedSection> serializedSections) { ImmutableArray<SerializedSection>.Enumerator enumerator = serializedSections.GetEnumerator(); while (enumerator.MoveNext()) { SerializedSection current = enumerator.Current; WriteSectionHeader(builder, current); } } private static void WriteSectionHeader(BlobBuilder builder, SerializedSection serializedSection) { if (serializedSection.VirtualSize == 0) { return; } int i = 0; int length = serializedSection.Name.Length; for (; i < 8; i++) { if (i < length) { builder.WriteByte((byte)serializedSection.Name[i]); } else { builder.WriteByte(0); } } builder.WriteUInt32((uint)serializedSection.VirtualSize); builder.WriteUInt32((uint)serializedSection.RelativeVirtualAddress); builder.WriteUInt32((uint)serializedSection.SizeOfRawData); builder.WriteUInt32((uint)serializedSection.PointerToRawData); builder.WriteUInt32(0u); builder.WriteUInt32(0u); builder.WriteUInt16(0); builder.WriteUInt16(0); builder.WriteUInt32((uint)serializedSection.Characteristics); } private static int IndexOfSection(ImmutableArray<SerializedSection> sections, SectionCharacteristics characteristics) { for (int i = 0; i < sections.Length; i++) { if ((sections[i].Characteristics & characteristics) == characteristics) { return i; } } return -1; } private static int SumRawDataSizes(ImmutableArray<SerializedSection> sections, SectionCharacteristics characteristics) { int num = 0; for (int i = 0; i < sections.Length; i++) { if ((sections[i].Characteristics & characteristics) == characteristics) { num += sections[i].SizeOfRawData; } } return num; } internal static IEnumerable<Blob> GetContentToSign(BlobBuilder peImage, int peHeadersSize, int peHeaderAlignment, Blob strongNameSignatureFixup) { int remainingHeaderToSign = peHeadersSize; int remainingHeader = BitArithmetic.Align(peHeadersSize, peHeaderAlignment); foreach (Blob blob in peImage.GetBlobs()) { int blobStart = blob.Start; int blobLength = blob.Length; while (blobLength > 0) { if (remainingHeader > 0) { int length; if (remainingHeaderToSign > 0) { length = Math.Min(remainingHeaderToSign, blobLength); yield return new Blob(blob.Buffer, blobStart, length); remainingHeaderToSign -= length; } else { length = Math.Min(remainingHeader, blobLength); } remainingHeader -= length; blobStart += length; blobLength -= length; continue; } if (blob.Buffer == strongNameSignatureFixup.Buffer) { yield return GetPrefixBlob(new Blob(blob.Buffer, blobStart, blobLength), strongNameSignatureFixup); yield return GetSuffixBlob(new Blob(blob.Buffer, blobStart, blobLength), strongNameSignatureFixup); } else { yield return new Blob(blob.Buffer, blobStart, blobLength); } break; } } } internal static Blob GetPrefixBlob(Blob container, Blob blob) { return new Blob(container.Buffer, container.Start, blob.Start - container.Start); } internal static Blob GetSuffixBlob(Blob container, Blob blob) { return new Blob(container.Buffer, blob.Start + blob.Length, container.Start + container.Length - blob.Start - blob.Length); } internal static IEnumerable<Blob> GetContentToChecksum(BlobBuilder peImage, Blob checksumFixup) { foreach (Blob blob in peImage.GetBlobs()) { if (blob.Buffer == checksumFixup.Buffer) { yield return GetPrefixBlob(blob, checksumFixup); yield return GetSuffixBlob(blob, checksumFixup); } else { yield return blob; } } } internal void Sign(BlobBuilder peImage, Blob strongNameSignatureFixup, Func<IEnumerable<Blob>, byte[]> signatureProvider) { int peHeadersSize = Header.ComputeSizeOfPEHeaders(GetSections().Length); byte[] array = signatureProvider(GetContentToSign(peImage, peHeadersSize, Header.FileAlignment, strongNameSignatureFixup)); if (array == null || array.Length > strongNameSignatureFixup.Length) { throw new InvalidOperationException(System.SR.SignatureProviderReturnedInvalidSignature); } new BlobWriter(strongNameSignatureFixup).WriteBytes(array); uint value = CalculateChecksum(peImage, _lazyChecksum); new BlobWriter(_lazyChecksum).WriteUInt32(value); } internal static uint CalculateChecksum(BlobBuilder peImage, Blob checksumFixup) { return CalculateChecksum(GetContentToChecksum(peImage, checksumFixup)) + (uint)peImage.Count; } private unsafe static uint CalculateChecksum(IEnumerable<Blob> blobs) { uint num = 0u; int num2 = -1; foreach (Blob blob in blobs) { ArraySegment<byte> bytes = blob.GetBytes(); fixed (byte* ptr = bytes.Array) { byte* ptr2 = ptr + bytes.Offset; byte* ptr3 = ptr2 + bytes.Count; if (num2 >= 0) { num = AggregateChecksum(num, (ushort)((*ptr2 << 8) | num2)); ptr2++; } if ((ptr3 - ptr2) % 2 != 0L) { ptr3--; num2 = *ptr3; } else { num2 = -1; } for (; ptr2 < ptr3; ptr2 += 2) { num = AggregateChecksum(num, *(ushort*)ptr2); } } } if (num2 >= 0) { num = AggregateChecksum(num, (ushort)num2); } return num; } private static uint AggregateChecksum(uint checksum, ushort value) { uint num = checksum + value; return (num >> 16) + (ushort)num; } } public sealed class DebugDirectoryBuilder { private struct Entry { public uint Stamp; public uint Version; public DebugDirectoryEntryType Type; public int DataSize; } private readonly List<Entry> _entries; private readonly BlobBuilder _dataBuilder; internal int TableSize => 28 * _entries.Count; internal int Size => (TableSize + _dataBuilder?.Count).GetValueOrDefault(); public DebugDirectoryBuilder() { _entries = new List<Entry>(3); _dataBuilder = new BlobBuilder(); } internal void AddEntry(DebugDirectoryEntryType type, uint version, uint stamp, int dataSize) { _entries.Add(new Entry { Stamp = stamp, Version = version, Type = type, DataSize = dataSize }); } public void AddEntry(DebugDirectoryEntryType type, uint version, uint stamp) { AddEntry(type, version, stamp, 0); } public void AddEntry<TData>(DebugDirectoryEntryType type, uint version, uint stamp, TData data, Action<BlobBuilder, TData> dataSerializer) { if (dataSerializer == null) { Throw.ArgumentNull("dataSerializer"); } int count = _dataBuilder.Count; dataSerializer(_dataBuilder, data); int dataSize = _dataBuilder.Count - count; AddEntry(type, version, stamp, dataSize); } public void AddCodeViewEntry(string pdbPath, BlobContentId pdbContentId, ushort portablePdbVersion) { AddCodeViewEntry(pdbPath, pdbContentId, portablePdbVersion, 1); } internal void AddCodeViewEntry(string pdbPath, BlobContentId pdbContentId, ushort portablePdbVersion, int age) { if (pdbPath == null) { Throw.ArgumentNull("pdbPath"); } if (age < 1) { Throw.ArgumentOutOfRange("age"); } if (pdbPath.Length == 0 || pdbPath.IndexOf('\0') == 0) { Throw.InvalidArgument(System.SR.ExpectedNonEmptyString, "pdbPath"); } if (portablePdbVersion > 0 && portablePdbVersion < 256) { Throw.ArgumentOutOfRange("portablePdbVersion"); } int dataSize = WriteCodeViewData(_dataBuilder, pdbPath, pdbContentId.Guid, age); AddEntry(DebugDirectoryEntryType.CodeView, (portablePdbVersion != 0) ? PortablePdbVersions.DebugDirectoryEntryVersion(portablePdbVersion) : 0u, pdbContentId.Stamp, dataSize); } public void AddReproducibleEntry() { AddEntry(DebugDirectoryEntryType.Reproducible, 0u, 0u); } private static int WriteCodeViewData(BlobBuilder builder, string pdbPath, Guid pdbGuid, int age) { int count = builder.Count; builder.WriteByte(82); builder.WriteByte(83); builder.WriteByte(68); builder.WriteByte(83); builder.WriteGuid(pdbGuid); builder.WriteInt32(age); builder.WriteUTF8(pdbPath); builder.WriteByte(0); return builder.Count - count; } public void AddPdbChecksumEntry(string algorithmName, ImmutableArray<byte> checksum) { if (algorithmName == null) { Throw.ArgumentNull("algorithmName"); } if (algorithmName.Length == 0) { Throw.ArgumentEmptyString("algorithmName"); } if (checksum.IsDefault) { Throw.ArgumentNull("checksum"); } if (checksum.Length == 0) { Throw.ArgumentEmptyArray("checksum"); } int dataSize = WritePdbChecksumData(_dataBuilder, algorithmName, checksum); AddEntry(DebugDirectoryEntryType.PdbChecksum, 1u, 0u, dataSize); } private static int WritePdbChecksumData(BlobBuilder builder, string algorithmName, ImmutableArray<byte> checksum) { int count = builder.Count; builder.WriteUTF8(algorithmName); builder.WriteByte(0); builder.WriteBytes(checksum); return builder.Count - count; } internal void Serialize(BlobBuilder builder, SectionLocation sectionLocation, int sectionOffset) { int num = sectionOffset + TableSize; foreach (Entry entry in _entries) { int value; int value2; if (entry.DataSize > 0) { value = sectionLocation.RelativeVirtualAddress + num; value2 = sectionLocation.PointerToRawData + num; } else { value = 0; value2 = 0; } builder.WriteUInt32(0u); builder.WriteUInt32(entry.Stamp); builder.WriteUInt32(entry.Version); builder.WriteInt32((int)entry.Type); builder.WriteInt32(entry.DataSize); builder.WriteInt32(value); builder.WriteInt32(value2); num += entry.DataSize; } builder.LinkSuffix(_dataBuilder); } public void AddEmbeddedPortablePdbEntry(BlobBuilder debugMetadata, ushort portablePdbVersion) { if (debugMetadata == null) { Throw.ArgumentNull("debugMetadata"); } if (portablePdbVersion < 256) { Throw.ArgumentOutOfRange("portablePdbVersion"); } int dataSize = WriteEmbeddedPortablePdbData(_dataBuilder, debugMetadata); AddEntry(DebugDirectoryEntryType.EmbeddedPortablePdb, PortablePdbVersions.DebugDirectoryEmbeddedVersion(portablePdbVersion), 0u, dataSize); } private static int WriteEmbeddedPortablePdbData(BlobBuilder builder, BlobBuilder debugMetadata) { int count = builder.Count; builder.WriteUInt32(1111773261u); builder.WriteInt32(debugMetadata.Count); MemoryStream memoryStream = new MemoryStream(); using (DeflateStream deflateStream = new DeflateStream(memoryStream, CompressionLevel.Optimal, leaveOpen: true)) { foreach (Blob blob in debugMetadata.GetBlobs()) { ArraySegment<byte> bytes = blob.GetBytes(); deflateStream.Write(bytes.Array, bytes.Offset, bytes.Count); } } builder.WriteBytes(memoryStream.ToArray()); return builder.Count - count; } } public readonly struct PdbChecksumDebugDirectoryData { public string AlgorithmName { get; } public ImmutableArray<byte> Checksum { get; } internal PdbChecksumDebugDirectoryData(string algorithmName, ImmutableArray<byte> checksum) { AlgorithmName = algorithmName; Checksum = checksum; } } public sealed class PEDirectoriesBuilder { public int AddressOfEntryPoint { get; set; } public DirectoryEntry ExportTable { get; set; } public DirectoryEntry ImportTable { get; set; } public DirectoryEntry ResourceTable { get; set; } public DirectoryEntry ExceptionTable { get; set; } public DirectoryEntry BaseRelocationTable { get; set; } public DirectoryEntry DebugTable { get; set; } public DirectoryEntry CopyrightTable { get; set; } public DirectoryEntry GlobalPointerTable { get; set; } public DirectoryEntry ThreadLocalStorageTable { get; set; } public DirectoryEntry LoadConfigTable { get; set; } public DirectoryEntry BoundImportTable { get; set; } public DirectoryEntry ImportAddressTable { get; set; } public DirectoryEntry DelayImportTable { get; set; } public DirectoryEntry CorHeaderTable { get; set; } } public sealed class PEHeaderBuilder { public Machine Machine { get; } public Characteristics ImageCharacteristics { get; } public byte MajorLinkerVersion { get; } public byte MinorLinkerVersion { get; } public ulong ImageBase { get; } public int SectionAlignment { get; } public int FileAlignment { get; } public ushort MajorOperatingSystemVersion { get; } public ushort MinorOperatingSystemVersion { get; } public ushort MajorImageVersion { get; } public ushort MinorImageVersion { get; } public ushort MajorSubsystemVersion { get; } public ushort MinorSubsystemVersion { get; } public Subsystem Subsystem { get; } public DllCharacteristics DllCharacteristics { get; } public ulong SizeOfStackReserve { get; } public ulong SizeOfStackCommit { get; } public ulong SizeOfHeapReserve { get; } public ulong SizeOfHeapCommit { get; } internal bool Is32Bit { get { if (Machine != Machine.Amd64 && Machine != Machine.IA64) { return Machine != Machine.Arm64; } return false; } } public PEHeaderBuilder(Machine machine = Machine.Unknown, int sectionAlignment = 8192, int fileAlignment = 512, ulong imageBase = 4194304uL, byte majorLinkerVersion = 48, byte minorLinkerVersion = 0, ushort majorOperatingSystemVersion = 4, ushort minorOperatingSystemVersion = 0, ushort majorImageVersion = 0, ushort minorImageVersion = 0, ushort majorSubsystemVersion = 4, ushort minorSubsystemVersion = 0, Subsystem subsystem = Subsystem.WindowsCui, DllCharacteristics dllCharacteristics = DllCharacteristics.DynamicBase | DllCharacteristics.NxCompatible | DllCharacteristics.NoSeh | DllCharacteristics.TerminalServerAware, Characteristics imageCharacteristics = Characteristics.Dll, ulong sizeOfStackReserve = 1048576uL, ulong sizeOfStackCommit = 4096uL, ulong sizeOfHeapReserve = 1048576uL, ulong sizeOfHeapCommit = 4096uL) { if (fileAlignment < 512 || fileAlignment > 65536 || BitArithmetic.CountBits(fileAlignment) != 1) { Throw.ArgumentOutOfRange("fileAlignment"); } if (sectionAlignment < fileAlignment || BitArithmetic.CountBits(sectionAlignment) != 1) { Throw.ArgumentOutOfRange("sectionAlignment"); } Machine = machine; SectionAlignment = sectionAlignment; FileAlignment = fileAlignment; ImageBase = imageBase; MajorLinkerVersion = majorLinkerVersion; MinorLinkerVersion = minorLinkerVersion; MajorOperatingSystemVersion = majorOperatingSystemVersion; MinorOperatingSystemVersion = minorOperatingSystemVersion; MajorImageVersion = majorImageVersion; MinorImageVersion = minorImageVersion; MajorSubsystemVersion = majorSubsystemVersion; MinorSubsystemVersion = minorSubsystemVersion; Subsystem = subsystem; DllCharacteristics = dllCharacteristics; ImageCharacteristics = imageCharacteristics; SizeOfStackReserve = sizeOfStackReserve; SizeOfStackCommit = sizeOfStackCommit; SizeOfHeapReserve = sizeOfHeapReserve; SizeOfHeapCommit = sizeOfHeapCommit; } public static PEHeaderBuilder CreateExecutableHeader() { return new PEHeaderBuilder(Machine.Unknown, 8192, 512, 4194304uL, 48, 0, 4, 0, 0, 0, 4, 0, Subsystem.WindowsCui, DllCharacteristics.DynamicBase | DllCharacteristics.NxCompatible | DllCharacteristics.NoSeh | DllCharacteristics.TerminalServerAware, Characteristics.ExecutableImage, 1048576uL, 4096uL, 1048576uL, 4096uL); } public static PEHeaderBuilder CreateLibraryHeader() { return new PEHeaderBuilder(Machine.Unknown, 8192, 512, 4194304uL, 48, 0, 4, 0, 0, 0, 4, 0, Subsystem.WindowsCui, DllCharacteristics.DynamicBase | DllCharacteristics.NxCompatible | DllCharacteristics.NoSeh | DllCharacteristics.TerminalServerAware, Characteristics.ExecutableImage | Characteristics.Dll, 1048576uL, 4096uL, 1048576uL, 4096uL); } internal int ComputeSizeOfPEHeaders(int sectionCount) { return PEBuilder.DosHeaderSize + 4 + 20 + PEHeader.Size(Is32Bit) + 40 * sectionCount; } } public abstract class ResourceSectionBuilder { protected internal abstract void Serialize(BlobBuilder builder, SectionLocation location); } public readonly struct SectionLocation { public int RelativeVirtualAddress { get; } public int PointerToRawData { get; } public SectionLocation(int relativeVirtualAddress, int pointerToRawData) { RelativeVirtualAddress = relativeVirtualAddress; PointerToRawData = pointerToRawData; } } public sealed class CoffHeader { internal const int Size = 20; public Machine Machine { get; } public short NumberOfSections { get; } public int TimeDateStamp { get; } public int PointerToSymbolTable { get; } public int NumberOfSymbols { get; } public short SizeOfOptionalHeader { get; } public Characteristics Characteristics { get; } internal CoffHeader(ref PEBinaryReader reader) { Machine = (Machine)reader.ReadUInt16(); NumberOfSections = reader.ReadInt16(); TimeDateStamp = reader.ReadInt32(); PointerToSymbolTable = reader.ReadInt32(); NumberOfSymbols = reader.ReadInt32(); SizeOfOptionalHeader = reader.ReadInt16(); Characteristics = (Characteristics)reader.ReadUInt16(); } } [Flags] public enum CorFlags { ILOnly = 1, Requires32Bit = 2, ILLibrary = 4, StrongNameSigned = 8, NativeEntryPoint = 0x10, TrackDebugData = 0x10000, Prefers32Bit = 0x20000 } public sealed class CorHeader { public ushort MajorRuntimeVersion { get; } public ushort MinorRuntimeVersion { get; } public DirectoryEntry MetadataDirectory { get; } public CorFlags Flags { get; } public int EntryPointTokenOrRelativeVirtualAddress { get; } public DirectoryEntry ResourcesDirectory { get; } public DirectoryEntry StrongNameSignatureDirectory { get; } public DirectoryEntry CodeManagerTableDirectory { get; } public DirectoryEntry VtableFixupsDirectory { get; } public DirectoryEntry ExportAddressTableJumpsDirectory { get; } public DirectoryEntry ManagedNativeHeaderDirectory { get; } internal CorHeader(ref PEBinaryReader reader) { reader.ReadInt32(); MajorRuntimeVersion = reader.ReadUInt16(); MinorRuntimeVersion = reader.ReadUInt16(); MetadataDirectory = new DirectoryEntry(ref reader); Flags = (CorFlags)reader.ReadUInt32(); EntryPointTokenOrRelativeVirtualAddress = reader.ReadInt32(); ResourcesDirectory = new DirectoryEntry(ref reader); StrongNameSignatureDirectory = new DirectoryEntry(ref reader); CodeManagerTableDirectory = new DirectoryEntry(ref reader); VtableFixupsDirectory = new DirectoryEntry(ref reader); ExportAddressTableJumpsDirectory = new DirectoryEntry(ref reader); ManagedNativeHeaderDirectory = new DirectoryEntry(ref reader); } } public readonly struct CodeViewDebugDirectoryData { public Guid Guid { get; } public int Age { get; } public string Path { get; } internal CodeViewDebugDirectoryData(Guid guid, int age, string path) { Path = path; Guid = guid; Age = age; } } public readonly struct DebugDirectoryEntry { internal const int Size = 28; public uint Stamp { get; } public ushort MajorVersion { get; } public ushort MinorVersion { get; } public DebugDirectoryEntryType Type { get; } public int DataSize { get; } public int DataRelativeVirtualAddress { get; } public int DataPointer { get; } public bool IsPortableCodeView => MinorVersion == 20557; public DebugDirectoryEntry(uint stamp, ushort majorVersion, ushort minorVersion, DebugDirectoryEntryType type, int dataSize, int dataRelativeVirtualAddress, int dataPointer) { Stamp = stamp; MajorVersion = majorVersion; MinorVersion = minorVersion; Type = type; DataSize = dataSize; DataRelativeVirtualAddress = dataRelativeVirtualAddress; DataPointer = dataPointer; } } public enum DebugDirectoryEntryType { Unknown = 0, Coff = 1, CodeView = 2, Reproducible = 16, EmbeddedPortablePdb = 17, PdbChecksum = 19 } public readonly struct DirectoryEntry { public readonly int RelativeVirtualAddress; public readonly int Size; public DirectoryEntry(int relativeVirtualAddress, int size) { RelativeVirtualAddress = relativeVirtualAddress; Size = size; } internal DirectoryEntry(ref PEBinaryReader reader) { RelativeVirtualAddress = reader.ReadInt32(); Size = reader.ReadInt32(); } } public enum Machine : ushort { Unknown = 0, I386 = 332, WceMipsV2 = 361, Alpha = 388, SH3 = 418, SH3Dsp = 419, SH3E = 420, SH4 = 422, SH5 = 424, Arm = 448, Thumb = 450, ArmThumb2 = 452, AM33 = 467, PowerPC = 496, PowerPCFP = 497, IA64 = 512, MIPS16 = 614, Alpha64 = 644, MipsFpu = 870, MipsFpu16 = 1126, Tricore = 1312, Ebc = 3772, Amd64 = 34404, M32R = 36929, Arm64 = 43620 } internal readonly struct PEBinaryReader { private readonly long _startOffset; private readonly long _maxOffset; private readonly BinaryReader _reader; public int CurrentOffset => (int)(_reader.BaseStream.Position - _startOffset); public PEBinaryReader(Stream stream, int size) { _startOffset = stream.Position; _maxOffset = _startOffset + size; _reader = new BinaryReader(stream, Encoding.UTF8, leaveOpen: true); } public void Seek(int offset) { CheckBounds(_startOffset, offset); _reader.BaseStream.Seek(offset, SeekOrigin.Begin); } public byte[] ReadBytes(int count) { CheckBounds(_reader.BaseStream.Position, count); return _reader.ReadBytes(count); } public byte ReadByte() { CheckBounds(1u); return _reader.ReadByte(); } public short ReadInt16() { CheckBounds(2u); return _reader.ReadInt16(); } public ushort ReadUInt16() { CheckBounds(2u); return _reader.ReadUInt16(); } public int ReadInt32() { CheckBounds(4u); return _reader.ReadInt32(); } public uint ReadUInt32() { CheckBounds(4u); return _reader.ReadUInt32(); } public ulong ReadUInt64() { CheckBounds(8u); return _reader.ReadUInt64(); } public string ReadNullPaddedUTF8(int byteCount) { byte[] array = ReadBytes(byteCount); int count = 0; for (int num = array.Length; num > 0; num--) { if (array[num - 1] != 0) { count = num; break; } } return Encoding.UTF8.GetString(array, 0, count); } private void CheckBounds(uint count) { if ((ulong)(_reader.BaseStream.Position + count) > (ulong)_maxOffset) { Throw.ImageTooSmall(); } } private void CheckBounds(long startPosition, int count) { if ((ulong)(startPosition + (uint)count) > (ulong)_maxOffset) { Throw.ImageTooSmallOrContainsInvalidOffsetOrCount(); } } } [Flags] public enum Characteristics : ushort { RelocsStripped = 1, ExecutableImage = 2, LineNumsStripped = 4, LocalSymsStripped = 8, AggressiveWSTrim = 0x10, LargeAddressAware = 0x20, BytesReversedLo = 0x80, Bit32Machine = 0x100, DebugStripped = 0x200, RemovableRunFromSwap = 0x400, NetRunFromSwap = 0x800, System = 0x1000, Dll = 0x2000, UpSystemOnly = 0x4000, BytesReversedHi = 0x8000 } public enum PEMagic : ushort { PE32 = 267, PE32Plus = 523 } public enum Subsystem : ushort { Unknown = 0, Native = 1, WindowsGui = 2, WindowsCui = 3, OS2Cui = 5, PosixCui = 7, NativeWindows = 8, WindowsCEGui = 9, EfiApplication = 10, EfiBootServiceDriver = 11, EfiRuntimeDriver = 12, EfiRom = 13, Xbox = 14, WindowsBootApplication = 16 } [Flags] public enum DllCharacteristics : ushort { ProcessInit = 1, ProcessTerm = 2, ThreadInit = 4, ThreadTerm = 8, HighEntropyVirtualAddressSpace = 0x20, DynamicBase = 0x40, NxCompatible = 0x100, NoIsolation = 0x200, NoSeh = 0x400, NoBind = 0x800, AppContainer = 0x1000, WdmDriver = 0x2000, TerminalServerAware = 0x8000 } [Flags] public enum SectionCharacteristics : uint { TypeReg = 0u, TypeDSect = 1u, TypeNoLoad = 2u, TypeGroup = 4u, TypeNoPad = 8u, TypeCopy = 0x10u, ContainsCode = 0x20u, ContainsInitializedData = 0x40u, ContainsUninitializedData = 0x80u, LinkerOther = 0x100u, LinkerInfo = 0x200u, TypeOver = 0x400u, LinkerRemove = 0x800u, LinkerComdat = 0x1000u, MemProtected = 0x4000u, NoDeferSpecExc = 0x4000u, GPRel = 0x8000u, MemFardata = 0x8000u, MemSysheap = 0x10000u, MemPurgeable = 0x20000u, Mem16Bit = 0x20000u, MemLocked = 0x40000u, MemPreload = 0x80000u, Align1Bytes = 0x100000u, Align2Bytes = 0x200000u, Align4Bytes = 0x300000u, Align8Bytes = 0x400000u, Align16Bytes = 0x500000u, Align32Bytes = 0x600000u, Align64Bytes = 0x700000u, Align128Bytes = 0x800000u, Align256Bytes = 0x900000u, Align512Bytes = 0xA00000u, Align1024Bytes = 0xB00000u, Align2048Bytes = 0xC00000u, Align4096Bytes = 0xD00000u, Align8192Bytes = 0xE00000u, AlignMask = 0xF00000u, LinkerNRelocOvfl = 0x1000000u, MemDiscardable = 0x2000000u, MemNotCached = 0x4000000u, MemNotPaged = 0x8000000u, MemShared = 0x10000000u, MemExecute = 0x20000000u, MemRead = 0x40000000u, MemWrite = 0x80000000u } public sealed class PEHeader { internal const int OffsetOfChecksum = 64; public PEMagic Magic { get; } public byte MajorLinkerVersion { get; } public byte MinorLinkerVersion { get; } public int SizeOfCode { get; } public int SizeOfInitializedData { get; } public int SizeOfUninitializedData { get; } public int AddressOfEntryPoint { get; } public int BaseOfCode { get; } public int BaseOfData { get; } public ulong ImageBase { get; } public int SectionAlignment { get; } public int FileAlignment { get; } public ushort MajorOperatingSystemVersion { get; } public ushort MinorOperatingSystemVersion { get; } public ushort MajorImageVersion { get; } public ushort MinorImageVersion { get; } public ushort MajorSubsystemVersion { get; } public ushort MinorSubsystemVersion { get; } public int SizeOfImage { get; } public int SizeOfHeaders { get; } public uint CheckSum { get; } public Subsystem Subsystem { get; } public DllCharacteristics DllCharacteristics { get; } public ulong SizeOfStackReserve { get; } public ulong SizeOfStackCommit { get; } public ulong SizeOfHeapReserve { get; } public ulong SizeOfHeapCommit { get; } public int NumberOfRvaAndSizes { get; } public DirectoryEntry ExportTableDirectory { get; } public DirectoryEntry ImportTableDirectory { get; } public DirectoryEntry ResourceTableDirectory { get; } public DirectoryEntry ExceptionTableDirectory { get; } public DirectoryEntry CertificateTableDirectory { get; } public DirectoryEntry BaseRelocationTableDirectory { get; } public DirectoryEntry DebugTableDirectory { get; } public DirectoryEntry CopyrightTableDirectory { get; } public DirectoryEntry GlobalPointerTableDirectory { get; } public DirectoryEntry ThreadLocalStorageTableDirectory { get; } public DirectoryEntry LoadConfigTableDirectory { get; } public DirectoryEntry BoundImportTableDirectory { get; } public DirectoryEntry ImportAddressTableDirectory { get; } public DirectoryEntry DelayImportTableDirectory { get; } public DirectoryEntry CorHeaderTableDirectory { get; } internal static int Size(bool is32Bit) { return 72 + 4 * (is32Bit ? 4 : 8) + 4 + 4 + 128; } internal PEHeader(ref PEBinaryReader reader) { PEMagic pEMagic = (PEMagic)reader.ReadUInt16(); if (pEMagic != PEMagic.PE32 && pEMagic != PEMagic.PE32Plus) { throw new BadImageFormatException(System.SR.UnknownPEMagicValue); } Magic = pEMagic; MajorLinkerVersion = reader.ReadByte(); MinorLinkerVersion = reader.ReadByte(); SizeOfCode = reader.ReadInt32(); SizeOfInitializedData = reader.ReadInt32(); SizeOfUninitializedData = reader.ReadInt32(); AddressOfEntryPoint = reader.ReadInt32(); BaseOfCode = reader.ReadInt32(); if (pEMagic == PEMagic.PE32Plus) { BaseOfData = 0; } else { BaseOfData = reader.ReadInt32(); } if (pEMagic == PEMagic.PE32Plus) { ImageBase = reader.ReadUInt64(); } else { ImageBase = reader.ReadUInt32(); } SectionAlignment = reader.ReadInt32(); FileAlignment = reader.ReadInt32(); MajorOperatingSystemVersion = reader.ReadUInt16(); MinorOperatingSystemVersion = reader.ReadUInt16(); MajorImageVersion = reader.ReadUInt16(); MinorImageVersion = reader.ReadUInt16(); MajorSubsystemVersion = reader.ReadUInt16(); MinorSubsystemVersion = reader.ReadUInt16(); reader.ReadUInt32(); SizeOfImage = reader.ReadInt32(); SizeOfHeaders = reader.ReadInt32(); CheckSum = reader.ReadUInt32(); Subsystem = (Subsystem)reader.ReadUInt16(); DllCharacteristics = (DllCharacteristics)reader.ReadUInt16(); if (pEMagic == PEMagic.PE32Plus) { SizeOfStackReserve = reader.ReadUInt64(); SizeOfStackCommit = reader.ReadUInt64(); SizeOfHeapReserve = reader.ReadUInt64(); SizeOfHeapCommit = reader.ReadUInt64(); } else { SizeOfStackReserve = reader.ReadUInt32(); SizeOfStackCommit = reader.ReadUInt32(); SizeOfHeapReserve = reader.ReadUInt32(); SizeOfHeapCommit = reader.ReadUInt32(); } reader.ReadUInt32(); NumberOfRvaAndSizes = reader.ReadInt32(); ExportTableDirectory = new DirectoryEntry(ref reader); ImportTableDirectory = new DirectoryEntry(ref reader); ResourceTableDirectory = new DirectoryEntry(ref reader); ExceptionTableDirectory = new DirectoryEntry(ref reader); CertificateTableDirectory = new DirectoryEntry(ref reader); BaseRelocationTableDirectory = new DirectoryEntry(ref reader); DebugTableDirectory = new DirectoryEntry(ref reader); CopyrightTableDirectory = new DirectoryEntry(ref reader); GlobalPointerTableDirectory = new DirectoryEntry(ref reader); ThreadLocalStorageTableDirectory = new DirectoryEntry(ref reader); LoadConfigTableDirectory = new DirectoryEntry(ref reader); BoundImportTableDirectory = new DirectoryEntry(ref reader); ImportAddressTableDirectory = new DirectoryEntry(ref reader); DelayImportTableDirectory = new DirectoryEntry(ref reader); CorHeaderTableDirectory = new DirectoryEntry(ref reader); new DirectoryEntry(ref reader); } } public sealed class PEHeaders { private readonly CoffHeader _coffHeader; private readonly PEHeader _peHeader; private readonly ImmutableArray<SectionHeader> _sectionHeaders; private readonly CorHeader _corHeader; private readonly bool _isLoadedImage; private readonly int _metadataStartOffset = -1; private readonly int _metadataSize; private readonly int _coffHeaderStartOffset = -1; private readonly int _corHeaderStartOffset = -1; private readonly int _peHeaderStartOffset = -1; internal const ushort DosSignature = 23117; internal const int PESignatureOffsetLocation = 60; internal const uint PESignature = 17744u; internal const int PESignatureSize = 4; public int MetadataStartOffset => _metadataStartOffset; public int MetadataSize => _metadataSize; public CoffHeader CoffHeader => _coffHeader; public int CoffHeaderStartOffset => _coffHeaderStartOffset; public bool IsCoffOnly => _peHeader == null; public PEHeader? PEHeader => _peHeader; public int PEHeaderStartOffset => _peHeaderStartOffset; public ImmutableArray<SectionHeader> SectionHeaders => _sectionHeaders; public CorHeader? CorHeader => _corHeader; public int CorHeaderStartOffset => _corHeaderStartOffset; public bool IsConsoleApplication { get { if (_peHeader != null) { return _peHeader.Subsystem == Subsystem.WindowsCui; } return false; } } public bool IsDll => (_coffHeader.Characteristics & Characteristics.Dll) != 0; public bool IsExe => (_coffHeader.Characteristics & Characteristics.Dll) == 0; public PEHeaders(Stream peStream) : this(peStream, 0) { } public PEHeaders(Stream peStream, int size) : this(peStream, size, isLoadedImage: false) { } public PEHeaders(Stream peStream, int size, bool isLoadedImage) { if (peStream == null) { throw new ArgumentNullException("peStream"); } if (!peStream.CanRead || !peStream.CanSeek) { throw new ArgumentException(System.SR.StreamMustSupportReadAndSeek, "peStream"); } _isLoadedImage = isLoadedImage; int andValidateSize = StreamExtensions.GetAndValidateSize(peStream, size, "peStream"); PEBinaryReader reader = new PEBinaryReader(peStream, andValidateSize); SkipDosHeader(ref reader, out var isCOFFOnly); _coffHeaderStartOffset = reader.CurrentOffset; _coffHeader = new CoffHeader(ref reader); if (!isCOFFOnly) { _peHeaderStartOffset = reader.CurrentOffset; _peHeader = new PEHeader(ref reader); } _sectionHeaders = ReadSectionHeaders(ref reader); if (!isCOFFOnly && TryCalculateCorHeaderOffset(andValidateSize, out var startOffset)) { _corHeaderStartOffset = startOffset; reader.Seek(startOffset); _corHeader = new CorHeader(ref reader); } CalculateMetadataLocation(andValidateSize, out _metadataStartOffset, out _metadataSize); } private bool TryCalculateCorHeaderOffset(long peStreamSize, out int startOffset) { if (!TryGetDirectoryOffset(_peHeader.CorHeaderTableDirectory, out startOffset, canCrossSectionBoundary: false)) { startOffset = -1; return false; } int size = _peHeader.CorHeaderTableDirectory.Size; if (size < 72) { throw new BadImageFormatException(System.SR.InvalidCorHeaderSize); } return true; } private void SkipDosHeader(ref PEBinaryReader reader, out bool isCOFFOnly) { ushort num = reader.ReadUInt16(); if (num != 23117) { if (num == 0 && reader.ReadUInt16() == ushort.MaxValue) { throw new BadImageFormatException(System.SR.UnknownFileFormat); } isCOFFOnly = true; reader.Seek(0); } else { isCOFFOnly = false; } if (!isCOFFOn