diff --git a/src/Tasks.UnitTests/StrongNameUtils_Tests.cs b/src/Tasks.UnitTests/StrongNameUtils_Tests.cs
new file mode 100644
index 00000000000..b72d43e1029
--- /dev/null
+++ b/src/Tasks.UnitTests/StrongNameUtils_Tests.cs
@@ -0,0 +1,150 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#if NETFRAMEWORK
+
+using System;
+using System.IO;
+using System.Reflection;
+using System.Reflection.Emit;
+using Microsoft.Build.Tasks;
+using Shouldly;
+using Xunit;
+
+#nullable disable
+
+namespace Microsoft.Build.UnitTests
+{
+ public sealed class StrongNameUtils_Tests
+ {
+ ///
+ /// The BCL (mscorlib) is always a fully signed managed assembly.
+ ///
+ [Fact]
+ public void GetAssemblyStrongNameLevel_FullySignedAssembly_ReturnsFullySigned()
+ {
+ string bclPath = typeof(string).Assembly.Location;
+ bclPath.ShouldNotBeNullOrEmpty();
+ File.Exists(bclPath).ShouldBeTrue();
+
+ StrongNameUtils.GetAssemblyStrongNameLevel(bclPath).ShouldBe(StrongNameLevel.FullySigned);
+ }
+
+ ///
+ /// A managed assembly with a strong-name signature directory present but with the
+ /// COMIMAGE_FLAGS_STRONGNAMESIGNED bit cleared must be reported as DelaySigned.
+ /// We emit one on the fly by attaching a public key and tagging the assembly
+ /// [assembly: AssemblyDelaySign(true)].
+ ///
+ [Fact]
+ public void GetAssemblyStrongNameLevel_DelaySignedAssembly_ReturnsDelaySigned()
+ {
+ using TestEnvironment env = TestEnvironment.Create();
+ TransientTestFolder folder = env.CreateFolder();
+
+ AssemblyName name = new AssemblyName("DelaySignedTestAssembly_" + Guid.NewGuid().ToString("N"));
+ name.SetPublicKey(typeof(string).Assembly.GetName().GetPublicKey());
+
+ // Mark as delay-signed via AssemblyDelaySignAttribute.
+ CustomAttributeBuilder delaySign = new CustomAttributeBuilder(
+ typeof(AssemblyDelaySignAttribute).GetConstructor([typeof(bool)]),
+ [true]);
+
+ AssemblyBuilder asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(
+ name,
+ AssemblyBuilderAccess.Save,
+ folder.Path);
+ asmBuilder.SetCustomAttribute(delaySign);
+
+ string fileName = name.Name + ".dll";
+ ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule(name.Name, fileName);
+ modBuilder.DefineType("Stub", TypeAttributes.Public).CreateType();
+ asmBuilder.Save(fileName);
+
+ string asmPath = Path.Combine(folder.Path, fileName);
+ File.Exists(asmPath).ShouldBeTrue();
+
+ StrongNameUtils.GetAssemblyStrongNameLevel(asmPath).ShouldBe(StrongNameLevel.DelaySigned);
+ }
+
+ ///
+ /// An unsigned managed assembly (COR20 header present, no strong name signature directory)
+ /// must be reported as None.
+ ///
+ [Fact]
+ public void GetAssemblyStrongNameLevel_UnsignedManagedAssembly_ReturnsNone()
+ {
+ using TestEnvironment env = TestEnvironment.Create();
+ TransientTestFolder folder = env.CreateFolder();
+
+ // Emit a trivial dynamic assembly to disk with no key file / key pair attached.
+ AssemblyName name = new AssemblyName("UnsignedTestAssembly_" + Guid.NewGuid().ToString("N"));
+ AssemblyBuilder asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(
+ name,
+ AssemblyBuilderAccess.Save,
+ folder.Path);
+ string fileName = name.Name + ".dll";
+ ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule(name.Name, fileName);
+ modBuilder.DefineType("Stub", TypeAttributes.Public).CreateType();
+ asmBuilder.Save(fileName);
+
+ string asmPath = Path.Combine(folder.Path, fileName);
+ File.Exists(asmPath).ShouldBeTrue();
+
+ StrongNameUtils.GetAssemblyStrongNameLevel(asmPath).ShouldBe(StrongNameLevel.None);
+ }
+
+ ///
+ /// A native PE without a COR20 header must be reported as Unknown (not None) so that
+ /// callers like AxTlbBaseReference.SigningRequirementsMatchExistingWrapper can distinguish
+ /// "no managed signature present" from "not a managed image at all".
+ ///
+ [WindowsOnlyFact]
+ public void GetAssemblyStrongNameLevel_NativePE_ReturnsUnknown()
+ {
+ string systemRoot = Environment.GetEnvironmentVariable("SystemRoot") ?? Environment.GetFolderPath(Environment.SpecialFolder.Windows);
+ string kernel32 = Path.Combine(systemRoot, "System32", "kernel32.dll");
+ File.Exists(kernel32).ShouldBeTrue();
+
+ StrongNameUtils.GetAssemblyStrongNameLevel(kernel32).ShouldBe(StrongNameLevel.Unknown);
+ }
+
+ [Fact]
+ public void GetAssemblyStrongNameLevel_NonExistentFile_ReturnsUnknown()
+ {
+ using TestEnvironment env = TestEnvironment.Create();
+ TransientTestFile missing = env.GetTempFile(".dll");
+ File.Exists(missing.Path).ShouldBeFalse();
+
+ StrongNameUtils.GetAssemblyStrongNameLevel(missing.Path).ShouldBe(StrongNameLevel.Unknown);
+ }
+
+ [Fact]
+ public void GetAssemblyStrongNameLevel_GarbageFile_ReturnsUnknown()
+ {
+ using TestEnvironment env = TestEnvironment.Create();
+ TransientTestFile garbage = env.CreateFile();
+ File.WriteAllBytes(garbage.Path, [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09]);
+
+ StrongNameUtils.GetAssemblyStrongNameLevel(garbage.Path).ShouldBe(StrongNameLevel.Unknown);
+ }
+
+ [Fact]
+ public void GetAssemblyStrongNameLevel_EmptyFile_ReturnsUnknown()
+ {
+ using TestEnvironment env = TestEnvironment.Create();
+ TransientTestFile empty = env.CreateFile();
+
+ StrongNameUtils.GetAssemblyStrongNameLevel(empty.Path).ShouldBe(StrongNameLevel.Unknown);
+ }
+
+ [Fact]
+ public void GetAssemblyStrongNameLevel_NullPath_Throws()
+ {
+ Should.Throw(() => StrongNameUtils.GetAssemblyStrongNameLevel(null));
+ }
+ }
+}
+
+#endif
+
diff --git a/src/Tasks/NativeMethods.cs b/src/Tasks/NativeMethods.cs
index b97f5cb9817..c53c535254b 100644
--- a/src/Tasks/NativeMethods.cs
+++ b/src/Tasks/NativeMethods.cs
@@ -462,7 +462,6 @@ internal static partial class NativeMethods
#region Constants
internal static readonly IntPtr NullPtr = IntPtr.Zero;
- internal static readonly IntPtr InvalidIntPtr = new IntPtr(-1);
internal const int ERROR_SUCCESS = 0;
@@ -507,14 +506,6 @@ internal enum REGKIND
internal const UInt16 IMAGE_FILE_MACHINE_ARM64 = 0xAA64; // ARM64 Little-Endian
internal const UInt16 IMAGE_FILE_MACHINE_R4000 = 0x166; // Used to test a architecture we do not expect to reference
- internal const uint GENERIC_READ = 0x80000000;
-
- internal const uint PAGE_READONLY = 0x02;
-
- internal const uint FILE_MAP_READ = 0x04;
-
- internal const uint FILE_TYPE_DISK = 0x01;
-
internal const int SE_ERR_ACCESSDENIED = 5;
[Flags]
@@ -528,152 +519,6 @@ internal enum MoveFileFlags
MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x00000020
}
- #endregion
-
- #region NT header stuff
-
- internal const uint IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x10b;
- internal const uint IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x20b;
-
- internal const uint IMAGE_DIRECTORY_ENTRY_COMHEADER = 14;
-
- internal const uint COMIMAGE_FLAGS_STRONGNAMESIGNED = 0x08;
-
- [StructLayout(LayoutKind.Sequential)]
- internal struct IMAGE_FILE_HEADER
- {
- internal ushort Machine;
- internal ushort NumberOfSections;
- internal uint TimeDateStamp;
- internal uint PointerToSymbolTable;
- internal uint NumberOfSymbols;
- internal ushort SizeOfOptionalHeader;
- internal ushort Characteristics;
- }
-
- [StructLayout(LayoutKind.Sequential)]
- internal struct IMAGE_DATA_DIRECTORY
- {
- internal uint VirtualAddress;
- internal uint Size;
- }
-
- [StructLayout(LayoutKind.Sequential)]
- internal struct IMAGE_OPTIONAL_HEADER32
- {
- internal ushort Magic;
- internal byte MajorLinkerVersion;
- internal byte MinorLinkerVersion;
- internal uint SizeOfCode;
- internal uint SizeOfInitializedData;
- internal uint SizeOfUninitializedData;
- internal uint AddressOfEntryPoint;
- internal uint BaseOfCode;
- internal uint BaseOfData;
- internal uint ImageBase;
- internal uint SectionAlignment;
- internal uint FileAlignment;
- internal ushort MajorOperatingSystemVersion;
- internal ushort MinorOperatingSystemVersion;
- internal ushort MajorImageVersion;
- internal ushort MinorImageVersion;
- internal ushort MajorSubsystemVersion;
- internal ushort MinorSubsystemVersion;
- internal uint Win32VersionValue;
- internal uint SizeOfImage;
- internal uint SizeOfHeaders;
- internal uint CheckSum;
- internal ushort Subsystem;
- internal ushort DllCharacteristics;
- internal uint SizeOfStackReserve;
- internal uint SizeOfStackCommit;
- internal uint SizeOfHeapReserve;
- internal uint SizeOfHeapCommit;
- internal uint LoaderFlags;
- internal uint NumberOfRvaAndSizes;
-
- // should be:
- // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] internal IMAGE_DATA_DIRECTORY[] DataDirectory;
- // but fixed size arrays only work with simple types, so I have to use ulongs and convert them to IMAGE_DATA_DIRECTORY structs
- // Fortunately, IMAGE_DATA_DIRECTORY is only 8 bytes long... (whew)
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
- internal ulong[] DataDirectory;
- }
-
- [StructLayout(LayoutKind.Sequential)]
- internal struct IMAGE_OPTIONAL_HEADER64
- {
- internal ushort Magic;
- internal byte MajorLinkerVersion;
- internal byte MinorLinkerVersion;
- internal uint SizeOfCode;
- internal uint SizeOfInitializedData;
- internal uint SizeOfUninitializedData;
- internal uint AddressOfEntryPoint;
- internal uint BaseOfCode;
- internal ulong ImageBase;
- internal uint SectionAlignment;
- internal uint FileAlignment;
- internal ushort MajorOperatingSystemVersion;
- internal ushort MinorOperatingSystemVersion;
- internal ushort MajorImageVersion;
- internal ushort MinorImageVersion;
- internal ushort MajorSubsystemVersion;
- internal ushort MinorSubsystemVersion;
- internal uint Win32VersionValue;
- internal uint SizeOfImage;
- internal uint SizeOfHeaders;
- internal uint CheckSum;
- internal ushort Subsystem;
- internal ushort DllCharacteristics;
- internal ulong SizeOfStackReserve;
- internal ulong SizeOfStackCommit;
- internal ulong SizeOfHeapReserve;
- internal ulong SizeOfHeapCommit;
- internal uint LoaderFlags;
- internal uint NumberOfRvaAndSizes;
-
- // should be:
- // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] internal IMAGE_DATA_DIRECTORY[] DataDirectory;
- // but fixed size arrays only work with simple types, so I have to use ulongs and convert them to IMAGE_DATA_DIRECTORY structs
- // Fortunately, IMAGE_DATA_DIRECTORY is only 8 bytes long... (whew)
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
- internal ulong[] DataDirectory;
- }
-
- [StructLayout(LayoutKind.Sequential)]
- internal struct IMAGE_NT_HEADERS32
- {
- internal uint signature;
- internal IMAGE_FILE_HEADER fileHeader;
- internal IMAGE_OPTIONAL_HEADER32 optionalHeader;
- }
-
- [StructLayout(LayoutKind.Sequential)]
- internal struct IMAGE_NT_HEADERS64
- {
- internal uint signature;
- internal IMAGE_FILE_HEADER fileHeader;
- internal IMAGE_OPTIONAL_HEADER64 optionalHeader;
- }
-
- [StructLayout(LayoutKind.Sequential)]
- internal struct IMAGE_COR20_HEADER
- {
- internal uint cb;
- internal ushort MajorRuntimeVersion;
- internal ushort MinorRuntimeVersion;
- internal IMAGE_DATA_DIRECTORY MetaData;
- internal uint Flags;
- internal uint EntryPointTokenOrEntryPointRVA;
- internal IMAGE_DATA_DIRECTORY Resources;
- internal IMAGE_DATA_DIRECTORY StrongNameSignature;
- internal IMAGE_DATA_DIRECTORY CodeManagerTable;
- internal IMAGE_DATA_DIRECTORY VTableFixups;
- internal IMAGE_DATA_DIRECTORY ExportAddressTableJumps;
- internal IMAGE_DATA_DIRECTORY ManagedNativeHeader;
- }
-
[StructLayout(LayoutKind.Sequential)]
internal struct CRYPTOAPI_BLOB
{
@@ -809,58 +654,6 @@ internal static extern void UnregisterTypeLib(
[return: MarshalAs(UnmanagedType.BStr)]
internal static extern string QueryPathOfRegTypeLib([In] ref Guid clsid, [In] short majorVersion, [In] short minorVersion, [In] int lcid);
- //------------------------------------------------------------------------------
- // CreateFile
- //------------------------------------------------------------------------------
- [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
- internal static extern IntPtr CreateFile(string lpFileName, uint dwDesiredAccess, FileShare dwShareMode,
- IntPtr lpSecurityAttributes, FileMode dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);
-
- //------------------------------------------------------------------------------
- // GetFileType
- //------------------------------------------------------------------------------
- [DllImport("kernel32.dll", SetLastError = true)]
- internal static extern uint GetFileType(IntPtr hFile);
-
- //------------------------------------------------------------------------------
- // CloseHandle
- //------------------------------------------------------------------------------
- [DllImport("kernel32.dll", SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- internal static extern bool CloseHandle(IntPtr hObject);
-
- //------------------------------------------------------------------------------
- // CreateFileMapping
- //------------------------------------------------------------------------------
- [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
- internal static extern IntPtr CreateFileMapping(IntPtr hFile, IntPtr lpFileMappingAttributes, uint flProtect,
- uint dwMaximumSizeHigh, uint dwMaximumSizeLow, string lpName);
-
- //------------------------------------------------------------------------------
- // MapViewOfFile
- //------------------------------------------------------------------------------
- [DllImport("kernel32.dll", SetLastError = true)]
- internal static extern IntPtr MapViewOfFile(IntPtr hFileMapping, uint dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, IntPtr dwNumberOfBytesToMap);
-
- //------------------------------------------------------------------------------
- // UnmapViewOfFile
- //------------------------------------------------------------------------------
- [DllImport("kernel32.dll", SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- internal static extern bool UnmapViewOfFile(IntPtr lpBaseAddress);
-
- //------------------------------------------------------------------------------
- // ImageNtHeader
- //------------------------------------------------------------------------------
- [DllImport("dbghelp.dll", SetLastError = true)]
- internal static extern IntPtr ImageNtHeader(IntPtr imageBase);
-
- //------------------------------------------------------------------------------
- // ImageRvaToVa
- //------------------------------------------------------------------------------
- [DllImport("dbghelp.dll", SetLastError = true)]
- internal static extern IntPtr ImageRvaToVa(IntPtr ntHeaders, IntPtr imageBase, uint Rva, out IntPtr LastRvaSection);
-
internal static bool AllDrivesMapped()
{
#if FEATURE_WINDOWSINTEROP
diff --git a/src/Tasks/StrongNameUtils.cs b/src/Tasks/StrongNameUtils.cs
index f1aef67e8c0..ea3e0ab1a87 100644
--- a/src/Tasks/StrongNameUtils.cs
+++ b/src/Tasks/StrongNameUtils.cs
@@ -2,10 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
-using System.Diagnostics;
using System.IO;
using System.Reflection;
-using System.Runtime.InteropServices;
+using System.Reflection.PortableExecutable;
using System.Security;
using Microsoft.Build.Shared;
using Microsoft.Build.Utilities;
@@ -128,167 +127,47 @@ internal static void GetStrongNameKey(TaskLoggingHelper log, string keyFile, str
}
///
- /// Given an assembly path, determine if the assembly is [delay] signed or not. This code is based on similar unmanaged
- /// routines in vsproject and sn.exe (ndp tools) codebases.
+ /// Given an assembly path, determine if the assembly is [delay] signed or not.
///
- ///
- ///
internal static StrongNameLevel GetAssemblyStrongNameLevel(string assemblyPath)
{
ErrorUtilities.VerifyThrowArgumentNull(assemblyPath);
- StrongNameLevel snLevel = StrongNameLevel.Unknown;
- IntPtr fileHandle = NativeMethods.InvalidIntPtr;
-
try
{
- // open the assembly
- fileHandle = NativeMethods.CreateFile(assemblyPath, NativeMethods.GENERIC_READ, FileShare.Read, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero);
- if (fileHandle == NativeMethods.InvalidIntPtr)
- {
- return snLevel;
- }
+ using FileStream stream = File.OpenRead(assemblyPath);
+ using PEReader peReader = new PEReader(stream);
+ CorHeader corHeader = peReader.PEHeaders.CorHeader;
- // if it's not a disk file, exit
- if (NativeMethods.GetFileType(fileHandle) != NativeMethods.FILE_TYPE_DISK)
+ // No COR20 header means this isn't a managed PE; preserve the historical
+ // "we don't know" answer rather than claiming the image is unsigned.
+ if (corHeader is null)
{
- return snLevel;
+ return StrongNameLevel.Unknown;
}
- IntPtr fileMappingHandle = IntPtr.Zero;
-
- try
+ DirectoryEntry signature = corHeader.StrongNameSignatureDirectory;
+ if (signature.RelativeVirtualAddress == 0 || signature.Size == 0)
{
- fileMappingHandle = NativeMethods.CreateFileMapping(fileHandle, IntPtr.Zero, NativeMethods.PAGE_READONLY, 0, 0, null);
- if (fileMappingHandle == IntPtr.Zero)
- {
- return snLevel;
- }
-
- IntPtr fileMappingBase = IntPtr.Zero;
-
- try
- {
- fileMappingBase = NativeMethods.MapViewOfFile(fileMappingHandle, NativeMethods.FILE_MAP_READ, 0, 0, IntPtr.Zero);
- if (fileMappingBase == IntPtr.Zero)
- {
- return snLevel;
- }
-
- // retrieve NT headers pointer from the file
- IntPtr ntHeader = NativeMethods.ImageNtHeader(fileMappingBase);
- if (ntHeader == IntPtr.Zero)
- {
- return snLevel;
- }
-
- // get relative virtual address of the COR20 header
- uint cor20HeaderRva = GetCor20HeaderRva(ntHeader);
- if (cor20HeaderRva == 0)
- {
- return snLevel;
- }
-
- // get the pointer to the COR20 header structure
- IntPtr cor20HeaderPtr = NativeMethods.ImageRvaToVa(ntHeader, fileMappingBase, cor20HeaderRva, out _);
- if (cor20HeaderPtr == IntPtr.Zero)
- {
- return snLevel;
- }
-
- // get the COR20 structure itself
- NativeMethods.IMAGE_COR20_HEADER cor20Header = (NativeMethods.IMAGE_COR20_HEADER)Marshal.PtrToStructure(cor20HeaderPtr, typeof(NativeMethods.IMAGE_COR20_HEADER));
-
- // and finally, examine it. If no space is allocated for strong name signature, assembly is not signed.
- if ((cor20Header.StrongNameSignature.VirtualAddress == 0) || (cor20Header.StrongNameSignature.Size == 0))
- {
- snLevel = StrongNameLevel.None;
- }
- else
- {
- // if there's allocated space and strong name flag is set, assembly is fully signed, or delay signed otherwise
- if ((cor20Header.Flags & NativeMethods.COMIMAGE_FLAGS_STRONGNAMESIGNED) != 0)
- {
- snLevel = StrongNameLevel.FullySigned;
- }
- else
- {
- snLevel = StrongNameLevel.DelaySigned;
- }
- }
- }
- finally
- {
- if (fileMappingBase != IntPtr.Zero)
- {
- NativeMethods.UnmapViewOfFile(fileMappingBase);
- fileMappingBase = IntPtr.Zero;
- }
- }
+ return StrongNameLevel.None;
}
- finally
- {
- if (fileMappingHandle != IntPtr.Zero)
- {
- NativeMethods.CloseHandle(fileMappingHandle);
- fileMappingHandle = IntPtr.Zero;
- }
- }
- }
- finally
- {
- if (fileHandle != NativeMethods.InvalidIntPtr)
- {
- NativeMethods.CloseHandle(fileHandle);
- }
- }
-
- return snLevel;
- }
-
- ///
- /// Retrieves the relative virtual address of the COR20 header, given the address of the NT headers structure. The catch
- /// here is that the NT headers struct can be either 32 or 64 bit version, and some fields have different sizes there. We
- /// need to see if we're dealing with a 32bit header or a 64bit one first.
- ///
- ///
- ///
- private static uint GetCor20HeaderRva(IntPtr ntHeadersPtr)
- {
- // read the first ushort in the optional header - we have an uint and IMAGE_FILE_HEADER preceding it
- ushort optionalHeaderMagic = (ushort)Marshal.ReadInt16(ntHeadersPtr, Marshal.SizeOf() + Marshal.SizeOf());
-
- // this should really be a structure, but NDP can't marshal fixed size struct arrays in a struct... ugh.
- // this ulong corresponds to a IMAGE_DATA_DIRECTORY structure
- ulong cor20DataDirectoryLong;
- // see if we have a 32bit header or a 64bit header
- if (optionalHeaderMagic == NativeMethods.IMAGE_NT_OPTIONAL_HDR32_MAGIC)
+ return (corHeader.Flags & CorFlags.StrongNameSigned) != 0
+ ? StrongNameLevel.FullySigned
+ : StrongNameLevel.DelaySigned;
+ }
+ catch (IOException)
{
- // marshal data into the appropriate structure
- NativeMethods.IMAGE_NT_HEADERS32 ntHeader32 = (NativeMethods.IMAGE_NT_HEADERS32)Marshal.PtrToStructure(ntHeadersPtr, typeof(NativeMethods.IMAGE_NT_HEADERS32));
- cor20DataDirectoryLong = ntHeader32.optionalHeader.DataDirectory[NativeMethods.IMAGE_DIRECTORY_ENTRY_COMHEADER];
+ return StrongNameLevel.Unknown;
}
- else if (optionalHeaderMagic == NativeMethods.IMAGE_NT_OPTIONAL_HDR64_MAGIC)
+ catch (BadImageFormatException)
{
- // marshal data into the appropriate structure
- NativeMethods.IMAGE_NT_HEADERS64 ntHeader64 = (NativeMethods.IMAGE_NT_HEADERS64)Marshal.PtrToStructure(ntHeadersPtr, typeof(NativeMethods.IMAGE_NT_HEADERS64));
- cor20DataDirectoryLong = ntHeader64.optionalHeader.DataDirectory[NativeMethods.IMAGE_DIRECTORY_ENTRY_COMHEADER];
+ return StrongNameLevel.Unknown;
}
- else
+ catch (UnauthorizedAccessException)
{
- Debug.Assert(false, "invalid file type!");
- return 0;
+ return StrongNameLevel.Unknown;
}
-
- // cor20DataDirectoryLong is really a IMAGE_DATA_DIRECTORY structure which I had to pack into an ulong
- // (see comments for IMAGE_OPTIONAL_HEADER32/64 in NativeMethods.cs)
- // this code extracts the virtualAddress (uint) and size (uint) fields from the ulong by doing simple
- // bit masking/shifting ops
- uint virtualAddress = (uint)(cor20DataDirectoryLong & 0x00000000ffffffff);
- // uint size = (uint)(cor20DataDirectoryLong >> 32);
-
- return virtualAddress;
}
}
}