Decompiled source of System Reflection Metadata v5.0.0
BepInEx/core/System.Reflection.Metadata/netstandard2.1/System.Reflection.Metadata.dll
Decompiled a month 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