Esempio n. 1
0
        public void CodeView()
        {
            var peStream = new MemoryStream(Misc.Debug);
            using (var reader = new PEReader(peStream))
            {
                // dumpbin:
                //
                // Debug Directories
                // 
                //     Time Type        Size RVA  Pointer
                // -------------- - ------------------------
                // 5670C4E6 cv           11C 0000230C      50C Format: RSDS, { 0C426227-31E6-4EC2-BD5F-712C4D96C0AB}, 1, C:\Temp\Debug.pdb

                var cvEntry = reader.ReadDebugDirectory().Single();
                Assert.Equal(DebugDirectoryEntryType.CodeView, cvEntry.Type);
                Assert.Equal(0x050c, cvEntry.DataPointer);
                Assert.Equal(0x230c, cvEntry.DataRelativeVirtualAddress);
                Assert.Equal(0x011c, cvEntry.DataSize); // includes NUL padding
                Assert.Equal(0, cvEntry.MajorVersion);
                Assert.Equal(0, cvEntry.MinorVersion);
                Assert.Equal(0x5670c4e6u, cvEntry.Stamp);

                var cv = reader.ReadCodeViewDebugDirectoryData(cvEntry);
                Assert.Equal(1, cv.Age);
                Assert.Equal(new Guid("0C426227-31E6-4EC2-BD5F-712C4D96C0AB"), cv.Guid);
                Assert.Equal(@"C:\Temp\Debug.pdb", cv.Path);
            }
        }
Esempio n. 2
0
        private void VerifyPE(Stream peStream)
        {
            var peReader = new PEReader(peStream);
            var headers = peReader.PEHeaders;
            var mdReader = peReader.GetMetadataReader();

            // TODO: more validation (can we use MetadataVisualizer until managed PEVerifier is available)?
        }
 public void Deterministic()
 {
     var peStream = new MemoryStream(Misc.Deterministic);
     using (var reader = new PEReader(peStream))
     {
         ValidateDeterministic(reader);
     }
 }
 public void CodeView()
 {
     var peStream = new MemoryStream(Misc.Debug);
     using (var reader = new PEReader(peStream))
     {
         ValidateCodeView(reader);
     }
 }
Esempio n. 5
0
 public void NoDebugDirectory()
 {
     var peStream = new MemoryStream(Misc.Members);
     using (var reader = new PEReader(peStream))
     {
         var entries = reader.ReadDebugDirectory();
         Assert.Empty(entries);
     }
 }
Esempio n. 6
0
 public void Sections()
 {
     var peHeaders = new PEReader(SynthesizedPeImages.Image1).PEHeaders;
     AssertEx.Equal(new[]
     {
         ".s1 offset=0x200 rva=0x200 size=512",
         ".s2 offset=0x400 rva=0x400 size=512",
         ".s3 offset=0x600 rva=0x600 size=512"
     }, peHeaders.SectionHeaders.Select(h => $"{h.Name} offset=0x{h.PointerToRawData:x3} rva=0x{h.VirtualAddress:x3} size={h.SizeOfRawData}"));
 }
Esempio n. 7
0
        public void GetContainingSectionIndex()
        {
            var peHeaders = new PEReader(SynthesizedPeImages.Image1).PEHeaders;

            Assert.Equal(-1, peHeaders.GetContainingSectionIndex(0));
            Assert.Equal(-1, peHeaders.GetContainingSectionIndex(0x200 - 1));
            Assert.Equal(0, peHeaders.GetContainingSectionIndex(0x200));
            Assert.Equal(1, peHeaders.GetContainingSectionIndex(0x400));
            Assert.Equal(2, peHeaders.GetContainingSectionIndex(0x600));
            Assert.Equal(2, peHeaders.GetContainingSectionIndex(0x600 + 9));
            Assert.Equal(-1, peHeaders.GetContainingSectionIndex(0x600 + 10));
        }
Esempio n. 8
0
        public void IL_LazyLoad()
        {
            var peStream = new MemoryStream(Misc.Members);
            using (var reader = new PEReader(peStream, PEStreamOptions.LeaveOpen))
            {
                var md = reader.GetMetadataReader();
                var il = reader.GetMethodBody(md.GetMethodDefinition(MetadataTokens.MethodDefinitionHandle(1)).RelativeVirtualAddress);

                Assert.Equal(new byte[] { 0, 42 }, il.GetILBytes());
                Assert.Equal(8, il.MaxStack);
            }
        }
Esempio n. 9
0
        private unsafe static void VerifyStrongNameSignatureDirectory(PEReader peReader, byte[] expectedSignature)
        {
            var headers = peReader.PEHeaders;
            int rva = headers.CorHeader.StrongNameSignatureDirectory.RelativeVirtualAddress;
            int size = headers.CorHeader.StrongNameSignatureDirectory.Size;

            // Even if the image is not signed we reserve space for a signature.
            // Validate that the signature is in .text section.
            Assert.Equal(".text", headers.SectionHeaders[headers.GetContainingSectionIndex(rva)].Name);

            var signature = peReader.GetSectionData(rva).GetContent(0, size);
            AssertEx.Equal(expectedSignature ?? new byte[size], signature);
        }
Esempio n. 10
0
        private void VerifyPE(Stream peStream, byte[] expectedSignature = null)
        {
            peStream.Position = 0;

            using (var peReader = new PEReader(peStream))
            {
                var headers = peReader.PEHeaders;
                var mdReader = peReader.GetMetadataReader();

                // TODO: more validation (can we use MetadataVisualizer until managed PEVerifier is available)?

                VerifyStrongNameSignatureDirectory(peReader, expectedSignature);

                Assert.Equal(s_contentId.Stamp, unchecked((uint)peReader.PEHeaders.CoffHeader.TimeDateStamp));
                Assert.Equal(s_guid, mdReader.GetGuid(mdReader.GetModuleDefinition().Mvid));
            }
        }
Esempio n. 11
0
        public void Deterministic()
        {
            var peStream = new MemoryStream(Misc.Deterministic);
            using (var reader = new PEReader(peStream))
            {
                // dumpbin:
                //
                // Debug Directories
                // 
                //       Time Type        Size      RVA  Pointer
                //   -------- ------- -------- -------- --------
                //   D2FC74D3 cv            32 00002338      538    Format: RSDS, {814C578F-7676-0263-4F8A-2D3E8528EAF1}, 1, C:\Temp\Deterministic.pdb
                //   00000000 repro          0 00000000        0

                var entries = reader.ReadDebugDirectory();

                var cvEntry = entries[0];
                Assert.Equal(DebugDirectoryEntryType.CodeView, cvEntry.Type);
                Assert.Equal(0x0538, cvEntry.DataPointer);
                Assert.Equal(0x2338, cvEntry.DataRelativeVirtualAddress);
                Assert.Equal(0x0032, cvEntry.DataSize); // no NUL padding
                Assert.Equal(0, cvEntry.MajorVersion);
                Assert.Equal(0, cvEntry.MinorVersion);
                Assert.Equal(0xD2FC74D3u, cvEntry.Stamp);

                var cv = reader.ReadCodeViewDebugDirectoryData(cvEntry);
                Assert.Equal(1, cv.Age);
                Assert.Equal(new Guid("814C578F-7676-0263-4F8A-2D3E8528EAF1"), cv.Guid);
                Assert.Equal(@"C:\Temp\Deterministic.pdb", cv.Path);

                var detEntry = entries[1];
                Assert.Equal(DebugDirectoryEntryType.Deterministic, detEntry.Type);
                Assert.Equal(0, detEntry.DataPointer);
                Assert.Equal(0, detEntry.DataRelativeVirtualAddress);
                Assert.Equal(0, detEntry.DataSize);
                Assert.Equal(0, detEntry.MajorVersion);
                Assert.Equal(0, detEntry.MinorVersion);
                Assert.Equal(0u, detEntry.Stamp);

                Assert.Equal(2, entries.Length);

                Assert.Throws<ArgumentException>(() => reader.ReadCodeViewDebugDirectoryData(detEntry));
            }
        }
Esempio n. 12
0
        public void TryGetDirectoryOffset()
        {
            var peHeaders = new PEReader(SynthesizedPeImages.Image1).PEHeaders;
            var dir = peHeaders.PEHeader.CopyrightTableDirectory;
            
            Assert.Equal(0x400 + 5, dir.RelativeVirtualAddress);
            Assert.Equal(10, dir.Size);

            int dirOffset;
            Assert.True(peHeaders.TryGetDirectoryOffset(dir, out dirOffset));
            Assert.Equal(0x400 + 5, dirOffset);

            Assert.False(peHeaders.TryGetDirectoryOffset(new DirectoryEntry(0, 10), out dirOffset));
            Assert.Equal(-1, dirOffset);

            Assert.True(peHeaders.TryGetDirectoryOffset(new DirectoryEntry(0x600, 0x300), out dirOffset));
            Assert.Equal(0x600, dirOffset);

            Assert.False(peHeaders.TryGetDirectoryOffset(new DirectoryEntry(0x1000, 10), out dirOffset));
            Assert.Equal(-1, dirOffset);
        }
Esempio n. 13
0
        public void Ctor()
        {
            Assert.Throws<ArgumentNullException>(() => new PEReader(null, PEStreamOptions.Default));

            var invalid = new MemoryStream(new byte[] { 1, 2, 3, 4 });

            // the stream should not be disposed if the arguments are bad
            Assert.Throws<ArgumentOutOfRangeException>(() => new PEReader(invalid, (PEStreamOptions)int.MaxValue));
            Assert.True(invalid.CanRead);

            // no BadImageFormatException if we're prefetching the entire image:
            var peReader0 = new PEReader(invalid, PEStreamOptions.PrefetchEntireImage | PEStreamOptions.LeaveOpen);
            Assert.True(invalid.CanRead);
            Assert.Throws<BadImageFormatException>(() => peReader0.PEHeaders);
            invalid.Position = 0;

            // BadImageFormatException if we're prefetching the entire image and metadata:
            Assert.Throws<BadImageFormatException>(() => new PEReader(invalid, PEStreamOptions.PrefetchEntireImage | PEStreamOptions.PrefetchMetadata | PEStreamOptions.LeaveOpen));
            Assert.True(invalid.CanRead);
            invalid.Position = 0;

            // the stream should be disposed if the content is bad:
            Assert.Throws<BadImageFormatException>(() => new PEReader(invalid, PEStreamOptions.PrefetchMetadata));
            Assert.False(invalid.CanRead);

            // the stream should not be disposed if we specified LeaveOpen flag:
            invalid = new MemoryStream(new byte[] { 1, 2, 3, 4 });
            Assert.Throws<BadImageFormatException>(() => new PEReader(invalid, PEStreamOptions.PrefetchMetadata | PEStreamOptions.LeaveOpen));
            Assert.True(invalid.CanRead);

            // valid metadata:
            var valid = new MemoryStream(Misc.Members);
            var peReader = new PEReader(valid, PEStreamOptions.Default);
            Assert.True(valid.CanRead);
            peReader.Dispose();
            Assert.False(valid.CanRead);
        }
        public void CorLibWithAssemblyReferences_Pdb()
        {
            string sourceLib =
                @"namespace Namespace
{
    public class Private { }
}";
            var compLib = CreateCompilationWithMscorlib(sourceLib, assemblyName: "System.Private.Library");

            compLib.VerifyDiagnostics();
            var refLib = compLib.EmitToImageReference(aliases: ImmutableArray.Create("A"));

            string sourceCorLib =
                @"extern alias A;
#pragma warning disable 8019
using N = A::Namespace;
namespace System
{
    public class Object
    {
        public void F()
        {
        }
    }
#pragma warning disable 0436
    public class Void : Object { }
#pragma warning restore 0436
}";
            // Create a custom corlib with a reference to compilation
            // above and a reference to the actual mscorlib.
            var compCorLib = CreateCompilation(sourceCorLib, assemblyName: CorLibAssemblyName, references: new[] { MscorlibRef, refLib });

            compCorLib.VerifyDiagnostics();
            var objectType = compCorLib.SourceAssembly.GlobalNamespace.GetMember <NamedTypeSymbol>("System.Object");

            Assert.NotNull(objectType.BaseType);

            var pdbPath = Temp.CreateDirectory().Path;
            ImmutableArray <byte> peBytes;
            ImmutableArray <byte> pdbBytes;

            ExpressionCompilerTestHelpers.EmitCorLibWithAssemblyReferences(
                compCorLib,
                pdbPath,
                moduleBuilder => new PEAssemblyBuilderWithAdditionalReferences(moduleBuilder, objectType),
                out peBytes,
                out pdbBytes);
            var symReader = SymReaderFactory.CreateReader(pdbBytes);

            using (var reader = new PEReader(peBytes))
            {
                var metadata       = reader.GetMetadata();
                var module         = metadata.ToModuleMetadata(ignoreAssemblyRefs: true);
                var metadataReader = metadata.ToMetadataReader();
                var moduleInstance = ModuleInstance.Create(metadata, metadataReader.GetModuleVersionIdOrThrow(), symReader);

                // Verify the module declares System.Object.
                Assert.True(metadataReader.DeclaresTheObjectClass());
                // Verify the PEModule has no assembly references.
                Assert.Equal(0, module.Module.ReferencedAssemblies.Length);
                // Verify the underlying metadata has the expected assembly references.
                var actualReferences = metadataReader.AssemblyReferences.Select(r => metadataReader.GetString(metadataReader.GetAssemblyReference(r).Name)).ToImmutableArray();
                AssertEx.Equal(new[] { "mscorlib", "System.Private.Library" }, actualReferences);

                using (var runtime = RuntimeInstance.Create(new[] { moduleInstance }))
                {
                    string error;
                    var    context  = CreateMethodContext(runtime, "System.Object.F");
                    var    testData = new CompilationTestData();
                    // Invalid import: "using N = A::Namespace;".
                    context.CompileExpression(
                        "new N.Private()",
                        out error,
                        testData);
                    Assert.Equal("error CS0246: The type or namespace name 'N' could not be found (are you missing a using directive or an assembly reference?)", error);
                }
            }
        }
Esempio n. 15
0
 /// <summary>
 /// Initializes a new instance.
 /// </summary>
 /// <param name="pe"></param>
 /// <param name="start"></param>
 /// <param name="count"></param>
 internal ExportList(PEReader pe, int start, int count)
 {
     this.pe    = pe;
     this.start = start;
     this.count = count;
 }
Esempio n. 16
0
        public void TestImplicitConstructorSpans()
        {
            string source = @"
using System;

public class C
{
    public static void Main()                                   // Method 0
    {
        TestMain();
    }

    static void TestMain()                                      // Method 1
    {
        C local = new C();
    }

    static int Init() => 33;                                    // Method 2

    int _x = Init();
    int _y = Init() + 12;
    static int s_x = Init();
    static int s_y = Init() + 153;
    static int s_z = 144;

    int Prop1 { get; } = 15;
    static int Prop2 { get; } = 255;
}
";

            var c       = CreateCompilation(Parse(source + InstrumentationHelperSource, @"C:\myproject\doc1.cs"));
            var peImage = c.EmitToArray(EmitOptions.Default.WithInstrumentationKinds(ImmutableArray.Create(InstrumentationKind.TestCoverage)));

            var peReader = new PEReader(peImage);
            var reader   = DynamicAnalysisDataReader.TryCreateFromPE(peReader, "<DynamicAnalysisData>");

            string[] sourceLines = source.Split('\n');

            VerifySpans(reader, reader.Methods[0], sourceLines,
                        new SpanResult(5, 4, 8, 5, "public static void Main()"),
                        new SpanResult(7, 8, 7, 19, "TestMain()"));

            VerifySpans(reader, reader.Methods[1], sourceLines,
                        new SpanResult(10, 4, 13, 5, "static void TestMain()"),
                        new SpanResult(12, 8, 12, 26, "C local = new C()"));

            VerifySpans(reader, reader.Methods[2], sourceLines,
                        new SpanResult(15, 4, 15, 28, "static int Init() => 33"),
                        new SpanResult(15, 25, 15, 27, "33"));

            VerifySpans(reader, reader.Methods[5], sourceLines,                     // Synthesized instance constructor
                        new SpanResult(17, 13, 17, 19, "Init()"),
                        new SpanResult(18, 13, 18, 24, "Init() + 12"),
                        new SpanResult(23, 25, 23, 27, "15"));

            VerifySpans(reader, reader.Methods[6], sourceLines,                     // Synthesized static constructor
                        new SpanResult(19, 21, 19, 27, "Init()"),
                        new SpanResult(20, 21, 20, 33, "Init() + 153"),
                        new SpanResult(21, 21, 21, 24, "144"),
                        new SpanResult(24, 32, 24, 35, "255"));
        }
Esempio n. 17
0
        public void TestLocalFunctionWithLambdaSpans()
        {
            string source = @"
using System;

public class C
{
    public static void Main()                                   // Method 0
    {
        TestMain();
    }

    static void TestMain()                                      // Method 1
    {
        new D().M1();
    }
}

public class D
{
    public void M1()                                            // Method 3
    {
        L1();
        void L1()
        {
            var f = new Func<int>(
                () => 1
            );

            f();

            var f1 = new Func<int>(
                () => { return 2; }
            );

            var f2 = new Func<int, int>(
                (x) => x + 3
            );

            var f3 = new Func<int, int>(
                x => x + 4
            );
        }
    }
}
";

            var c       = CreateCompilation(Parse(source + InstrumentationHelperSource, @"C:\myproject\doc1.cs"));
            var peImage = c.EmitToArray(EmitOptions.Default.WithInstrumentationKinds(ImmutableArray.Create(InstrumentationKind.TestCoverage)));

            var peReader = new PEReader(peImage);
            var reader   = DynamicAnalysisDataReader.TryCreateFromPE(peReader, "<DynamicAnalysisData>");

            string[] sourceLines = source.Split('\n');

            VerifySpans(reader, reader.Methods[0], sourceLines,
                        new SpanResult(5, 4, 8, 5, "public static void Main()"),
                        new SpanResult(7, 8, 7, 19, "TestMain()"));

            VerifySpans(reader, reader.Methods[1], sourceLines,
                        new SpanResult(10, 4, 13, 5, "static void TestMain()"),
                        new SpanResult(12, 8, 12, 21, "new D().M1()"));

            VerifySpans(reader, reader.Methods[3], sourceLines,
                        new SpanResult(18, 4, 41, 5, "public void M1()"),
                        new SpanResult(20, 8, 20, 13, "L1()"),
                        new SpanResult(24, 22, 24, 23, "1"),
                        new SpanResult(23, 12, 25, 14, "var f = new Func<int>"),
                        new SpanResult(27, 12, 27, 16, "f()"),
                        new SpanResult(30, 24, 30, 33, "return 2"),
                        new SpanResult(29, 12, 31, 14, "var f1 = new Func<int>"),
                        new SpanResult(34, 23, 34, 28, "x + 3"),
                        new SpanResult(33, 12, 35, 14, "var f2 = new Func<int, int>"),
                        new SpanResult(38, 21, 38, 26, "x + 4"),
                        new SpanResult(37, 12, 39, 14, "var f3 = new Func<int, int>"));
        }
Esempio n. 18
0
 public void EntireImage_EagerLoad()
 {
     var peStream = new MemoryStream(Misc.Members);
     using (var reader = new PEReader(peStream, PEStreamOptions.LeaveOpen | PEStreamOptions.PrefetchMetadata | PEStreamOptions.PrefetchEntireImage))
     {
         Assert.Equal(4608, reader.GetEntireImage().Length);
     }
 }
Esempio n. 19
0
        public void TestPatternSpans()
        {
            string source = @"
using System;

public class C
{
    public static void Main()                                   // Method 0
    {
        Student s = new Student();
        s.Name = ""Bozo"";
        s.GPA = 2.3;
        Operate(s);
    }
     
    static string Operate(Person p)                             // Method 1
    {
        switch (p)
        {
            case Student s when s.GPA > 3.5:
                return $""Student {s.Name} ({s.GPA:N1})"";
            case Student s when (s.GPA < 2.0):
                return $""Failing Student {s.Name} ({s.GPA:N1})"";
            case Student s:
                return $""Student {s.Name} ({s.GPA:N1})"";
            case Teacher t:
                return $""Teacher {t.Name} of {t.Subject}"";
            default:
                return $""Person {p.Name}"";
        }
    }
}

class Person { public string Name; }
class Teacher : Person { public string Subject; }
class Student : Person { public double GPA; }
";

            var c       = CreateCompilation(Parse(source + InstrumentationHelperSource, @"C:\myproject\doc1.cs"));
            var peImage = c.EmitToArray(EmitOptions.Default.WithInstrumentationKinds(ImmutableArray.Create(InstrumentationKind.TestCoverage)));

            var peReader = new PEReader(peImage);
            var reader   = DynamicAnalysisDataReader.TryCreateFromPE(peReader, "<DynamicAnalysisData>");

            string[] sourceLines = source.Split('\n');

            VerifySpans(reader, reader.Methods[0], sourceLines,
                        new SpanResult(5, 4, 11, 5, "public static void Main()"),
                        new SpanResult(7, 8, 7, 34, "Student s = new Student()"),
                        new SpanResult(8, 8, 8, 24, "s.Name = \"Bozo\""),
                        new SpanResult(9, 8, 9, 20, "s.GPA = 2.3"),
                        new SpanResult(10, 8, 10, 19, "Operate(s)"));

            VerifySpans(reader, reader.Methods[1], sourceLines,
                        new SpanResult(13, 4, 28, 5, "static string Operate(Person p)"),
                        new SpanResult(17, 27, 17, 43, "when s.GPA > 3.5"),
                        new SpanResult(19, 27, 19, 45, "when (s.GPA < 2.0)"),
                        new SpanResult(18, 16, 18, 56, "return $\"Student {s.Name} ({s.GPA:N1})\""),
                        new SpanResult(20, 16, 20, 64, "return $\"Failing Student {s.Name} ({s.GPA:N1})\""),
                        new SpanResult(22, 16, 22, 56, "return $\"Student {s.Name} ({s.GPA:N1})\""),
                        new SpanResult(24, 16, 24, 58, "return $\"Teacher {t.Name} of {t.Subject}\""),
                        new SpanResult(26, 16, 26, 42, "return $\"Person {p.Name}\""),
                        new SpanResult(15, 16, 15, 17, "p"));
        }
Esempio n. 20
0
 public SymMetadataImport(Stream peStream)
 {
     _peReader      = new PEReader(peStream);
     MetadataReader = _peReader.GetMetadataReader();
 }
Esempio n. 21
0
 public void GetSectionData_Errors()
 {
     var peStream = new MemoryStream(Misc.Members);
     using (var reader = new PEReader(peStream))
     {
         Assert.Throws<ArgumentNullException>(() => reader.GetSectionData(null));
         Assert.Throws<ArgumentOutOfRangeException>(() => reader.GetSectionData(-1));
         Assert.Throws<ArgumentOutOfRangeException>(() => reader.GetSectionData(int.MinValue));
     }
 }
        public override bool Execute()
        {
            var list = new List <ITaskItem>();
            var assembliesToSkipPublish           = new List <ITaskItem>();
            var nativeAotFrameworkAssembliesToUse = new HashSet <string>();

            foreach (ITaskItem taskItem in SdkAssemblies)
            {
                nativeAotFrameworkAssembliesToUse.Add(Path.GetFileName(taskItem.ItemSpec));
            }

            foreach (ITaskItem taskItem in FrameworkAssemblies)
            {
                nativeAotFrameworkAssembliesToUse.Add(Path.GetFileName(taskItem.ItemSpec));
            }

            foreach (ITaskItem taskItem in Assemblies)
            {
                // In the case of disk-based assemblies, this holds the file path
                string itemSpec = taskItem.ItemSpec;

                // Skip the native apphost (whose name ends up colliding with the native output binary) and supporting libraries
                if (itemSpec.EndsWith(DotNetAppHostExecutableName, StringComparison.OrdinalIgnoreCase) || itemSpec.Contains(DotNetHostFxrLibraryName) || itemSpec.Contains(DotNetHostPolicyLibraryName))
                {
                    assembliesToSkipPublish.Add(taskItem);
                    continue;
                }

                // Prototype aid - remove the native CoreCLR runtime pieces from the publish folder
                if (itemSpec.Contains("microsoft.netcore.app") && (itemSpec.Contains("\\native\\") || itemSpec.Contains("/native/")))
                {
                    assembliesToSkipPublish.Add(taskItem);
                    continue;
                }

                var assemblyFileName = Path.GetFileName(itemSpec);

                if (assemblyFileName == "WindowsBase.dll")
                {
                    // There are two instances of WindowsBase.dll, one small one, in the NativeAOT framework
                    // and real one in WindowsDesktop SDK. We want to make sure that if both are present,
                    // we will use the one from WindowsDesktop SDK, and not from NativeAOT framework.
                    foreach (ITaskItem taskItemToSkip in FrameworkAssemblies)
                    {
                        if (Path.GetFileName(taskItemToSkip.ItemSpec) == assemblyFileName)
                        {
                            assembliesToSkipPublish.Add(taskItemToSkip);
                            break;
                        }
                    }

                    assembliesToSkipPublish.Add(taskItem);
                    list.Add(taskItem);
                    continue;
                }

                // Remove any assemblies whose implementation we want to come from NativeAOT's package.
                // Currently that's System.Private.* SDK assemblies and a bunch of framework assemblies.
                if (nativeAotFrameworkAssembliesToUse.Contains(assemblyFileName))
                {
                    assembliesToSkipPublish.Add(taskItem);
                    continue;
                }

                try
                {
                    using (FileStream moduleStream = File.OpenRead(itemSpec))
                        using (var module = new PEReader(moduleStream))
                        {
                            if (module.HasMetadata)
                            {
                                MetadataReader moduleMetadataReader = module.GetMetadataReader();
                                if (moduleMetadataReader.IsAssembly)
                                {
                                    string culture = moduleMetadataReader.GetString(moduleMetadataReader.GetAssemblyDefinition().Culture);

                                    assembliesToSkipPublish.Add(taskItem);
                                    if (culture == "" || culture.Equals("neutral", StringComparison.OrdinalIgnoreCase))
                                    {
                                        // NativeAOT doesn't consume resource assemblies yet so skip them
                                        list.Add(taskItem);
                                    }
                                }
                            }
                        }
                }
                catch (BadImageFormatException)
                {
                }
            }

            ManagedAssemblies       = list.ToArray();
            AssembliesToSkipPublish = assembliesToSkipPublish.ToArray();

            return(true);
        }
Esempio n. 23
0
 private ModuleMetadata(PEReader peReader)
     : base(isImageOwner: true, id: MetadataId.CreateNewId())
 {
     _module = new PEModule(this, peReader: peReader, metadataOpt: IntPtr.Zero, metadataSizeOpt: 0, includeEmbeddedInteropTypes: false, ignoreAssemblyRefs: false);
 }
Esempio n. 24
0
        /// <summary>
        /// Initializes the fields of the R2RHeader and R2RMethods
        /// </summary>
        /// <param name="filename">PE image</param>
        /// <exception cref="BadImageFormatException">The Cor header flag must be ILLibrary</exception>
        public unsafe R2RReader(string filename)
        {
            Filename = filename;
            Image    = File.ReadAllBytes(filename);

            fixed(byte *p = Image)
            {
                IntPtr ptr = (IntPtr)p;

                peReader = new PEReader(p, Image.Length);

                IsR2R = (peReader.PEHeaders.CorHeader.Flags == CorFlags.ILLibrary);
                if (!IsR2R)
                {
                    throw new BadImageFormatException("The file is not a ReadyToRun image");
                }

                Machine   = peReader.PEHeaders.CoffHeader.Machine;
                ImageBase = peReader.PEHeaders.PEHeader.ImageBase;

                // initialize R2RHeader
                DirectoryEntry r2rHeaderDirectory = peReader.PEHeaders.CorHeader.ManagedNativeHeaderDirectory;
                int            r2rHeaderOffset    = GetOffset(r2rHeaderDirectory.RelativeVirtualAddress);

                R2RHeader = new R2RHeader(Image, r2rHeaderDirectory.RelativeVirtualAddress, r2rHeaderOffset);
                if (r2rHeaderDirectory.Size != R2RHeader.Size)
                {
                    throw new BadImageFormatException("The calculated size of the R2RHeader doesn't match the size saved in the ManagedNativeHeaderDirectory");
                }

                // initialize R2RMethods
                if (peReader.HasMetadata)
                {
                    MetadataReader mdReader = peReader.GetMetadataReader();

                    int runtimeFunctionSize = 2;
                    if (Machine == Machine.Amd64)
                    {
                        runtimeFunctionSize = 3;
                    }
                    runtimeFunctionSize *= sizeof(int);
                    R2RSection runtimeFunctionSection = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_RUNTIME_FUNCTIONS];
                    uint       nRuntimeFunctions      = (uint)(runtimeFunctionSection.Size / runtimeFunctionSize);
                    int        runtimeFunctionOffset  = GetOffset(runtimeFunctionSection.RelativeVirtualAddress);
                    bool[]     isEntryPoint           = new bool[nRuntimeFunctions];
                    for (int i = 0; i < nRuntimeFunctions; i++)
                    {
                        isEntryPoint[i] = false;
                    }

                    // initialize R2RMethods with method signatures from MethodDefHandle, and runtime function indices from MethodDefEntryPoints
                    int         methodDefEntryPointsRVA    = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_METHODDEF_ENTRYPOINTS].RelativeVirtualAddress;
                    int         methodDefEntryPointsOffset = GetOffset(methodDefEntryPointsRVA);
                    NativeArray methodEntryPoints          = new NativeArray(Image, (uint)methodDefEntryPointsOffset);
                    uint        nMethodEntryPoints         = methodEntryPoints.GetCount();
                    R2RMethods = new List <R2RMethod>();
                    for (uint rid = 1; rid <= nMethodEntryPoints; rid++)
                    {
                        int offset = 0;
                        if (methodEntryPoints.TryGetAt(Image, rid - 1, ref offset))
                        {
                            R2RMethod method = new R2RMethod(Image, mdReader, rid, GetEntryPointIdFromOffset(offset), null, null);

                            if (method.EntryPointRuntimeFunctionId < 0 || method.EntryPointRuntimeFunctionId >= nRuntimeFunctions)
                            {
                                throw new BadImageFormatException("EntryPointRuntimeFunctionId out of bounds");
                            }
                            isEntryPoint[method.EntryPointRuntimeFunctionId] = true;
                            R2RMethods.Add(method);
                        }
                    }

                    // instance method table
                    R2RSection      instMethodEntryPointSection = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS];
                    int             instMethodEntryPointsOffset = GetOffset(instMethodEntryPointSection.RelativeVirtualAddress);
                    NativeParser    parser = new NativeParser(Image, (uint)instMethodEntryPointsOffset);
                    NativeHashtable instMethodEntryPoints = new NativeHashtable(Image, parser);
                    NativeHashtable.AllEntriesEnumerator allEntriesEnum = instMethodEntryPoints.EnumerateAllEntries();
                    NativeParser curParser = allEntriesEnum.GetNext();
                    while (!curParser.IsNull())
                    {
                        uint methodFlags = curParser.GetCompressedData();
                        uint rid         = curParser.GetCompressedData();
                        if ((methodFlags & (byte)R2RMethod.EncodeMethodSigFlags.ENCODE_METHOD_SIG_MethodInstantiation) != 0)
                        {
                            uint nArgs = curParser.GetCompressedData();
                            R2RMethod.GenericElementTypes[] args = new R2RMethod.GenericElementTypes[nArgs];
                            uint[] tokens = new uint[nArgs];
                            for (int i = 0; i < nArgs; i++)
                            {
                                args[i] = (R2RMethod.GenericElementTypes)curParser.GetByte();
                                if (args[i] == R2RMethod.GenericElementTypes.ValueType)
                                {
                                    tokens[i] = curParser.GetCompressedData();
                                    tokens[i] = (tokens[i] >> 2);
                                }
                            }

                            uint id = curParser.GetUnsigned();
                            id = id >> 1;
                            R2RMethod method = new R2RMethod(Image, mdReader, rid, (int)id, args, tokens);
                            if (method.EntryPointRuntimeFunctionId >= 0 && method.EntryPointRuntimeFunctionId < nRuntimeFunctions)
                            {
                                isEntryPoint[method.EntryPointRuntimeFunctionId] = true;
                            }
                            R2RMethods.Add(method);
                        }
                        curParser = allEntriesEnum.GetNext();
                    }

                    // get the RVAs of the runtime functions for each method
                    int curOffset = 0;
                    foreach (R2RMethod method in R2RMethods)
                    {
                        int runtimeFunctionId = method.EntryPointRuntimeFunctionId;
                        if (runtimeFunctionId == -1)
                        {
                            continue;
                        }
                        curOffset = runtimeFunctionOffset + runtimeFunctionId * runtimeFunctionSize;
                        do
                        {
                            int startRva = NativeReader.ReadInt32(Image, ref curOffset);
                            int endRva   = -1;
                            if (Machine == Machine.Amd64)
                            {
                                endRva = NativeReader.ReadInt32(Image, ref curOffset);
                            }
                            int unwindRva = NativeReader.ReadInt32(Image, ref curOffset);

                            method.RuntimeFunctions.Add(new RuntimeFunction(runtimeFunctionId, startRva, endRva, unwindRva, method));
                            runtimeFunctionId++;
                        }while (runtimeFunctionId < nRuntimeFunctions && !isEntryPoint[runtimeFunctionId]);
                    }
                }
            }
        }
Esempio n. 25
0
 /// <summary>
 /// Read a PE file and create all the data structures to represent it
 /// </summary>
 /// <param name="filename">The file name of the PE file</param>
 /// <returns>PEFile object representing "filename"</returns>
 public static PEFile ReadPEFile(string filename)
 {
     Contract.Requires(filename != null);
     Contract.Ensures(Contract.Result <PEFile>() != null);
     return(PEReader.ReadPEFile(filename, false));
 }
Esempio n. 26
0
        static CodeViewDebugData CvDataFromPE(string fileName)
        {
            PEReader per = null;
            try
            {
                // Inspect PE to get the PDB information
                per = new PEReader(new System.IO.FileStream(fileName, FileMode.Open));
            }
            catch (Exception)
            {
            }

            return (per != null) ? per.CodeViewDebugData : null;
        }
Esempio n. 27
0
 internal EcmaModule GetModule(PEReader peReader)
 {
     return(_typeSystemContext.GetModule(peReader));
 }
Esempio n. 28
0
        public void EmitPortableExecutable()
        {
            bool succeeded = false;

            try
            {
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();

                PEHeaderBuilder headerBuilder;
                int?            timeDateStamp;
                ISymbolNode     r2rHeaderExportSymbol;
                Func <IEnumerable <Blob>, BlobContentId> peIdProvider = null;

                if (_nodeFactory.CompilationModuleGroup.IsCompositeBuildMode && _componentModule == null)
                {
                    headerBuilder         = PEHeaderProvider.Create(Subsystem.Unknown, _nodeFactory.Target);
                    peIdProvider          = new Func <IEnumerable <Blob>, BlobContentId>(content => BlobContentId.FromHash(CryptographicHashProvider.ComputeSourceHash(content)));
                    timeDateStamp         = null;
                    r2rHeaderExportSymbol = _nodeFactory.Header;
                }
                else
                {
                    PEReader inputPeReader = (_componentModule != null ? _componentModule.PEReader : _nodeFactory.CompilationModuleGroup.CompilationModuleSet.First().PEReader);
                    headerBuilder         = PEHeaderProvider.Create(inputPeReader.PEHeaders.PEHeader.Subsystem, _nodeFactory.Target);
                    timeDateStamp         = inputPeReader.PEHeaders.CoffHeader.TimeDateStamp;
                    r2rHeaderExportSymbol = null;
                }

                Func <RuntimeFunctionsTableNode> getRuntimeFunctionsTable = null;
                if (_componentModule == null)
                {
                    getRuntimeFunctionsTable = GetRuntimeFunctionsTable;
                }
                R2RPEBuilder r2rPeBuilder = new R2RPEBuilder(
                    _nodeFactory.Target,
                    headerBuilder,
                    r2rHeaderExportSymbol,
                    Path.GetFileName(_objectFilePath),
                    getRuntimeFunctionsTable,
                    _customPESectionAlignment,
                    peIdProvider);

                NativeDebugDirectoryEntryNode  nativeDebugDirectoryEntryNode  = null;
                PerfMapDebugDirectoryEntryNode perfMapDebugDirectoryEntryNode = null;
                ISymbolDefinitionNode          firstImportThunk = null;
                ISymbolDefinitionNode          lastImportThunk  = null;
                ObjectNode lastWrittenObjectNode = null;

                int nodeIndex = -1;
                foreach (var depNode in _nodes)
                {
                    ++nodeIndex;
                    ObjectNode node = depNode as ObjectNode;

                    if (node == null)
                    {
                        continue;
                    }

                    if (node.ShouldSkipEmittingObjectNode(_nodeFactory))
                    {
                        continue;
                    }

                    ObjectData nodeContents = node.GetData(_nodeFactory);

                    if (node is NativeDebugDirectoryEntryNode nddeNode)
                    {
                        // There should be only one NativeDebugDirectoryEntry.
                        Debug.Assert(nativeDebugDirectoryEntryNode == null);
                        nativeDebugDirectoryEntryNode = nddeNode;
                    }

                    if (node is PerfMapDebugDirectoryEntryNode pmdeNode)
                    {
                        // There should be only one PerfMapDebugDirectoryEntryNode.
                        Debug.Assert(perfMapDebugDirectoryEntryNode is null);
                        perfMapDebugDirectoryEntryNode = pmdeNode;
                    }

                    if (node is ImportThunk importThunkNode)
                    {
                        Debug.Assert(firstImportThunk == null || lastWrittenObjectNode is ImportThunk,
                                     "All the import thunks must be in single contiguous run");

                        if (firstImportThunk == null)
                        {
                            firstImportThunk = importThunkNode;
                        }
                        lastImportThunk = importThunkNode;
                    }

                    string name = null;

                    if (_mapFileBuilder != null)
                    {
                        name = depNode.GetType().ToString();
                        int firstGeneric = name.IndexOf('[');
                        if (firstGeneric < 0)
                        {
                            firstGeneric = name.Length;
                        }
                        int lastDot = name.LastIndexOf('.', firstGeneric - 1, firstGeneric);
                        if (lastDot > 0)
                        {
                            name = name.Substring(lastDot + 1);
                        }
                    }

                    EmitObjectData(r2rPeBuilder, nodeContents, nodeIndex, name, node.Section);
                    lastWrittenObjectNode = node;

                    if (_outputInfoBuilder != null && node is MethodWithGCInfo methodNode)
                    {
                        _outputInfoBuilder.AddMethod(methodNode, nodeContents.DefinedSymbols[0]);
                    }
                }

                r2rPeBuilder.SetCorHeader(_nodeFactory.CopiedCorHeaderNode, _nodeFactory.CopiedCorHeaderNode.Size);
                r2rPeBuilder.SetDebugDirectory(_nodeFactory.DebugDirectoryNode, _nodeFactory.DebugDirectoryNode.Size);
                if (firstImportThunk != null)
                {
                    r2rPeBuilder.AddSymbolForRange(_nodeFactory.DelayLoadMethodCallThunks, firstImportThunk, lastImportThunk);
                }


                if (_nodeFactory.Win32ResourcesNode != null)
                {
                    Debug.Assert(_nodeFactory.Win32ResourcesNode.Size != 0);
                    r2rPeBuilder.SetWin32Resources(_nodeFactory.Win32ResourcesNode, _nodeFactory.Win32ResourcesNode.Size);
                }

                if (_outputInfoBuilder != null)
                {
                    foreach (string inputFile in _inputFiles)
                    {
                        _outputInfoBuilder.AddInputModule(_nodeFactory.TypeSystemContext.GetModuleFromPath(inputFile));
                    }
                }

                using (var peStream = File.Create(_objectFilePath))
                {
                    r2rPeBuilder.Write(peStream, timeDateStamp);

                    if (_mapFileBuilder != null)
                    {
                        _mapFileBuilder.SetFileSize(peStream.Length);
                    }

                    if (nativeDebugDirectoryEntryNode is not null)
                    {
                        Debug.Assert(_generatePdbFile);
                        // Compute MD5 hash of the output image and store that in the native DebugDirectory entry
                        using (var md5Hash = MD5.Create())
                        {
                            peStream.Seek(0, SeekOrigin.Begin);
                            byte[] hash      = md5Hash.ComputeHash(peStream);
                            byte[] rsdsEntry = nativeDebugDirectoryEntryNode.GenerateRSDSEntryData(hash);

                            int offsetToUpdate = r2rPeBuilder.GetSymbolFilePosition(nativeDebugDirectoryEntryNode);
                            peStream.Seek(offsetToUpdate, SeekOrigin.Begin);
                            peStream.Write(rsdsEntry);
                        }
                    }

                    if (perfMapDebugDirectoryEntryNode is not null)
                    {
                        Debug.Assert(_generatePerfMapFile && _outputInfoBuilder is not null && _outputInfoBuilder.EnumerateInputAssemblies().Any());
                        byte[] perfmapSig   = PerfMapWriter.PerfMapV1SignatureHelper(_outputInfoBuilder.EnumerateInputAssemblies(), _nodeFactory.Target);
                        byte[] perfMapEntry = perfMapDebugDirectoryEntryNode.GeneratePerfMapEntryData(perfmapSig, _perfMapFormatVersion);

                        int offsetToUpdate = r2rPeBuilder.GetSymbolFilePosition(perfMapDebugDirectoryEntryNode);
                        peStream.Seek(offsetToUpdate, SeekOrigin.Begin);
                        peStream.Write(perfMapEntry);
                    }
                }

                if (_outputInfoBuilder != null)
                {
                    r2rPeBuilder.AddSections(_outputInfoBuilder);

                    if (_generateMapFile)
                    {
                        string mapFileName = Path.ChangeExtension(_objectFilePath, ".map");
                        _mapFileBuilder.SaveMap(mapFileName);
                    }

                    if (_generateMapCsvFile)
                    {
                        string nodeStatsCsvFileName = Path.ChangeExtension(_objectFilePath, ".nodestats.csv");
                        string mapCsvFileName       = Path.ChangeExtension(_objectFilePath, ".map.csv");
                        _mapFileBuilder.SaveCsv(nodeStatsCsvFileName, mapCsvFileName);
                    }

                    if (_generatePdbFile)
                    {
                        string path = _pdbPath;
                        if (string.IsNullOrEmpty(path))
                        {
                            path = Path.GetDirectoryName(_objectFilePath);
                        }
                        _symbolFileBuilder.SavePdb(path, _objectFilePath);
                    }

                    if (_generatePerfMapFile)
                    {
                        string path = _perfMapPath;
                        if (string.IsNullOrEmpty(path))
                        {
                            path = Path.GetDirectoryName(_objectFilePath);
                        }
                        _symbolFileBuilder.SavePerfMap(path, _perfMapFormatVersion, _objectFilePath);
                    }

                    if (_profileFileBuilder != null)
                    {
                        string path = Path.ChangeExtension(_objectFilePath, ".profile");
                        _profileFileBuilder.SaveProfile(path);
                    }
                }

                succeeded = true;
            }
            finally
            {
                if (!succeeded)
                {
                    // If there was an exception while generating the OBJ file, make sure we don't leave the unfinished
                    // object file around.
                    try
                    {
                        File.Delete(_objectFilePath);
                    }
                    catch
                    {
                    }
                }
            }
        }
Esempio n. 29
0
 public void GetSectionData()
 {
     var peStream = new MemoryStream(Misc.Members);
     using (var reader = new PEReader(peStream))
     {
         ValidateSectionData(reader);
     }
 }
Esempio n. 30
0
 /// <summary>
 /// Parse export table directory for a given PE reader.
 /// </summary>
 /// <param name="reader">PE reader representing the executable image to parse</param>
 public static PEExportTable GetExportTable(this PEReader reader)
 {
     return(PEExportTable.Parse(reader));
 }
Esempio n. 31
0
        public void Metadata_EagerLoad()
        {
            var peStream = new MemoryStream(Misc.Members);
            using (var reader = new PEReader(peStream, PEStreamOptions.LeaveOpen | PEStreamOptions.PrefetchMetadata))
            {
                var md = reader.GetMetadataReader();
                var method = md.GetMethodDefinition(MetadataTokens.MethodDefinitionHandle(1));
                Assert.Equal("MC1", md.GetString(method.Name));

                Assert.Throws<InvalidOperationException>(() => reader.GetEntireImage());
                Assert.Throws<InvalidOperationException>(() => reader.GetMethodBody(method.RelativeVirtualAddress));
            }
        }
Esempio n. 32
0
        private PEExportTable(PEReader peReader)
        {
            _namedExportRva = new Dictionary <string, int>();
            _ordinalRva     = new Dictionary <int, int>();

            DirectoryEntry exportTable       = peReader.PEHeaders.PEHeader.ExportTableDirectory;
            PEMemoryBlock  peImage           = peReader.GetEntireImage();
            BlobReader     exportTableHeader = peImage.GetReader(peReader.GetOffset(exportTable.RelativeVirtualAddress), exportTable.Size);

            if (exportTableHeader.Length == 0)
            {
                return;
            }

            // +0x00: reserved
            exportTableHeader.ReadUInt32();
            // +0x04: TODO: time/date stamp
            exportTableHeader.ReadUInt32();
            // +0x08: major version
            exportTableHeader.ReadUInt16();
            // +0x0A: minor version
            exportTableHeader.ReadUInt16();
            // +0x0C: DLL name RVA
            exportTableHeader.ReadUInt32();
            // +0x10: ordinal base
            int minOrdinal = exportTableHeader.ReadInt32();
            // +0x14: number of entries in the address table
            int addressEntryCount = exportTableHeader.ReadInt32();
            // +0x18: number of name pointers
            int namePointerCount = exportTableHeader.ReadInt32();
            // +0x1C: export address table RVA
            int addressTableRVA = exportTableHeader.ReadInt32();
            // +0x20: name pointer RVA
            int namePointerRVA = exportTableHeader.ReadInt32();
            // +0x24: ordinal table RVA
            int ordinalTableRVA = exportTableHeader.ReadInt32();

            int[]      addressTable       = new int[addressEntryCount];
            BlobReader addressTableReader = peImage.GetReader(peReader.GetOffset(addressTableRVA), sizeof(int) * addressEntryCount);

            for (int entryIndex = 0; entryIndex < addressEntryCount; entryIndex++)
            {
                addressTable[entryIndex] = addressTableReader.ReadInt32();
            }

            ushort[]   ordinalTable       = new ushort[namePointerCount];
            BlobReader ordinalTableReader = peImage.GetReader(peReader.GetOffset(ordinalTableRVA), sizeof(ushort) * namePointerCount);

            for (int entryIndex = 0; entryIndex < namePointerCount; entryIndex++)
            {
                ushort ordinalIndex = ordinalTableReader.ReadUInt16();
                ordinalTable[entryIndex] = ordinalIndex;
                _ordinalRva.Add(entryIndex + minOrdinal, addressTable[ordinalIndex]);
            }

            BlobReader namePointerReader = peImage.GetReader(peReader.GetOffset(namePointerRVA), sizeof(int) * namePointerCount);

            for (int entryIndex = 0; entryIndex < namePointerCount; entryIndex++)
            {
                int nameRVA = namePointerReader.ReadInt32();
                if (nameRVA != 0)
                {
                    int           nameOffset  = peReader.GetOffset(nameRVA);
                    BlobReader    nameReader  = peImage.GetReader(nameOffset, peImage.Length - nameOffset);
                    StringBuilder nameBuilder = new StringBuilder();
                    for (byte ascii; (ascii = nameReader.ReadByte()) != 0;)
                    {
                        nameBuilder.Append((char)ascii);
                    }
                    _namedExportRva.Add(nameBuilder.ToString(), addressTable[ordinalTable[entryIndex]]);
                }
            }
        }
        private void ValidateDeterministic(PEReader reader)
        {
            // dumpbin:
            //
            // Debug Directories
            // 
            //       Time Type        Size      RVA  Pointer
            //   -------- ------- -------- -------- --------
            //   D2FC74D3 cv            32 00002338      538    Format: RSDS, {814C578F-7676-0263-4F8A-2D3E8528EAF1}, 1, C:\Temp\Deterministic.pdb
            //   00000000 repro          0 00000000        0

            var entries = reader.ReadDebugDirectory();

            var cvEntry = entries[0];
            Assert.Equal(DebugDirectoryEntryType.CodeView, cvEntry.Type);
            Assert.False(cvEntry.IsPortableCodeView);
            Assert.Equal(0x0538, cvEntry.DataPointer);
            Assert.Equal(0x2338, cvEntry.DataRelativeVirtualAddress);
            Assert.Equal(0x0032, cvEntry.DataSize); // no NUL padding
            Assert.Equal(0, cvEntry.MajorVersion);
            Assert.Equal(0, cvEntry.MinorVersion);
            Assert.Equal(0xD2FC74D3u, cvEntry.Stamp);

            var cv = reader.ReadCodeViewDebugDirectoryData(cvEntry);
            Assert.Equal(1, cv.Age);
            Assert.Equal(new Guid("814C578F-7676-0263-4F8A-2D3E8528EAF1"), cv.Guid);
            Assert.Equal(@"C:\Temp\Deterministic.pdb", cv.Path);

            var detEntry = entries[1];
            Assert.Equal(DebugDirectoryEntryType.Reproducible, detEntry.Type);
            Assert.False(detEntry.IsPortableCodeView);
            Assert.Equal(0, detEntry.DataPointer);
            Assert.Equal(0, detEntry.DataRelativeVirtualAddress);
            Assert.Equal(0, detEntry.DataSize);
            Assert.Equal(0, detEntry.MajorVersion);
            Assert.Equal(0, detEntry.MinorVersion);
            Assert.Equal(0u, detEntry.Stamp);

            Assert.Equal(2, entries.Length);
        }
Esempio n. 34
0
 public static PEExportTable Parse(PEReader peReader)
 {
     return(new PEExportTable(peReader));
 }
Esempio n. 35
0
        public void TestFieldInitializerSpans()
        {
            string source = @"
using System;

public class C
{
    public static void Main()                                   // Method 0
    {
        TestMain();
    }

    static void TestMain()                                      // Method 1
    {
        C local = new C(); local = new C(1, 2);
    }

    static int Init() => 33;                                    // Method 2

    C()                                                         // Method 3
    {
        _z = 12;
    }

    static C()                                                  // Method 4
    {
        s_z = 123;
    }

    int _x = Init();
    int _y = Init() + 12;
    int _z;
    static int s_x = Init();
    static int s_y = Init() + 153;
    static int s_z;

    C(int x)                                                    // Method 5
    {
        _z = x;
    }

    C(int a, int b)                                             // Method 6
    {
        _z = a + b;
    }

    int Prop1 { get; } = 15;
    static int Prop2 { get; } = 255;
}
";

            var c       = CreateCompilation(Parse(source + InstrumentationHelperSource, @"C:\myproject\doc1.cs"));
            var peImage = c.EmitToArray(EmitOptions.Default.WithInstrumentationKinds(ImmutableArray.Create(InstrumentationKind.TestCoverage)));

            var peReader = new PEReader(peImage);
            var reader   = DynamicAnalysisDataReader.TryCreateFromPE(peReader, "<DynamicAnalysisData>");

            string[] sourceLines = source.Split('\n');

            VerifySpans(reader, reader.Methods[0], sourceLines,
                        new SpanResult(5, 4, 8, 5, "public static void Main()"),
                        new SpanResult(7, 8, 7, 19, "TestMain()"));

            VerifySpans(reader, reader.Methods[1], sourceLines,
                        new SpanResult(10, 4, 13, 5, "static void TestMain()"),
                        new SpanResult(12, 8, 12, 26, "C local = new C()"),
                        new SpanResult(12, 27, 12, 47, "local = new C(1, 2)"));

            VerifySpans(reader, reader.Methods[2], sourceLines,
                        new SpanResult(15, 4, 15, 28, "static int Init() => 33"),
                        new SpanResult(15, 25, 15, 27, "33"));

            VerifySpans(reader, reader.Methods[3], sourceLines,
                        new SpanResult(17, 4, 20, 5, "C()"),
                        new SpanResult(27, 13, 27, 19, "Init()"),
                        new SpanResult(28, 13, 28, 24, "Init() + 12"),
                        new SpanResult(44, 25, 44, 27, "15"),
                        new SpanResult(19, 8, 19, 16, "_z = 12"));

            VerifySpans(reader, reader.Methods[4], sourceLines,
                        new SpanResult(22, 4, 25, 5, "static C()"),
                        new SpanResult(30, 21, 30, 27, "Init()"),
                        new SpanResult(31, 21, 31, 33, "Init() + 153"),
                        new SpanResult(45, 32, 45, 35, "255"),
                        new SpanResult(24, 8, 24, 18, "s_z = 123"));

            VerifySpans(reader, reader.Methods[5], sourceLines,
                        new SpanResult(34, 4, 37, 5, "C(int x)"),
                        new SpanResult(27, 13, 27, 19, "Init()"),
                        new SpanResult(28, 13, 28, 24, "Init() + 12"),
                        new SpanResult(44, 25, 44, 27, "15"),
                        new SpanResult(36, 8, 36, 15, "_z = x"));

            VerifySpans(reader, reader.Methods[6], sourceLines,
                        new SpanResult(39, 4, 42, 5, "C(int a, int b)"),
                        new SpanResult(27, 13, 27, 19, "Init()"),
                        new SpanResult(28, 13, 28, 24, "Init() + 12"),
                        new SpanResult(44, 25, 44, 27, "15"),
                        new SpanResult(41, 8, 41, 19, "_z = a + b"));
        }
Esempio n. 36
0
        private static bool IsCompatibleWithCurrentProcess(string fileName, out string[] complaints)
        {
            complaints = null;
            Stream peImage = null;

            try
            {
                peImage = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
                using (var peReader = new PEReader(peImage, PEStreamOptions.PrefetchMetadata))
                {
                    peImage = null;
                    if (peReader.HasMetadata)
                    {
                        var processorArchitecture = ProcessorArchitecture.MSIL;

                        var isPureIL = (peReader.PEHeaders.CorHeader.Flags & CorFlags.ILOnly) != 0;

                        if (peReader.PEHeaders.PEHeader.Magic == PEMagic.PE32Plus)
                        {
                            processorArchitecture = ProcessorArchitecture.Amd64;
                        }
                        else if ((peReader.PEHeaders.CorHeader.Flags & CorFlags.Requires32Bit) != 0 || !isPureIL)
                        {
                            processorArchitecture = ProcessorArchitecture.X86;
                        }

                        var isLoadable = (isPureIL && processorArchitecture == ProcessorArchitecture.MSIL) ||
                                         (Environment.Is64BitProcess && processorArchitecture == ProcessorArchitecture.Amd64) ||
                                         (!Environment.Is64BitProcess && processorArchitecture == ProcessorArchitecture.X86);

                        if (!isLoadable)
                        {
                            complaints = new[] { $"The file {fileName} is not loadable into this process, either it is not an MSIL assembly or the complied for a different processor architecture." };
                        }

                        return(isLoadable);
                    }
                    else
                    {
                        complaints = new[] { $"The file {fileName} does not contain any CLR metadata, probably it is a native file." };
                        return(false);
                    }
                }
            }
            catch (IOException)
            {
                return(false);
            }
            catch (BadImageFormatException)
            {
                return(false);
            }
            catch (UnauthorizedAccessException)
            {
                return(false);
            }
            catch (MissingMethodException)
            {
                complaints = new[] { "MissingMethodException occurred. Please try to add a BindingRedirect for System.Collections.ImmutableCollections to the App.config file to correct this error." };
                return(false);
            }
            catch (Exception ex)
            {
                complaints = new[] { LogFormatter.PrintException(ex) };
                return(false);
            }
            finally
            {
                peImage?.Dispose();
            }
        }
Esempio n. 37
0
        public void TestImplicitConstructorsWithLambdasSpans()
        {
            string source = @"
using System;

public class C
{
    public static void Main()                                   // Method 0
    {
        TestMain();
    }

    static void TestMain()                                      // Method 1
    {
        int y = s_c._function();
        D d = new D();
        int z = d._c._function();
        int zz = D.s_c._function();
    }

    public C(Func<int> f)                                       // Method 2
    {
        _function = f;
    }

    static C s_c = new C(() => 115);
    Func<int> _function;
}

class D
{
    public C _c = new C(() => 120);
    public static C s_c = new C(() => 144);
    public C _c1 = new C(() => 130);
    public static C s_c1 = new C(() => 156);
}

partial struct E
{
}

partial struct E
{
    public static C s_c = new C(() => 1444);
    public static C s_c1 = new C(() => { return 1567; });
}
";

            var c       = CreateCompilation(Parse(source + InstrumentationHelperSource, @"C:\myproject\doc1.cs"));
            var peImage = c.EmitToArray(EmitOptions.Default.WithInstrumentationKinds(ImmutableArray.Create(InstrumentationKind.TestCoverage)));

            var peReader = new PEReader(peImage);
            var reader   = DynamicAnalysisDataReader.TryCreateFromPE(peReader, "<DynamicAnalysisData>");

            string[] sourceLines = source.Split('\n');

            VerifySpans(reader, reader.Methods[0], sourceLines,
                        new SpanResult(5, 4, 8, 5, "public static void Main()"),
                        new SpanResult(7, 8, 7, 19, "TestMain()"));

            VerifySpans(reader, reader.Methods[1], sourceLines,
                        new SpanResult(10, 4, 16, 5, "static void TestMain()"),
                        new SpanResult(12, 8, 12, 32, "int y = s_c._function()"),
                        new SpanResult(13, 8, 13, 22, "D d = new D()"),
                        new SpanResult(14, 8, 14, 33, "int z = d._c._function()"),
                        new SpanResult(15, 8, 15, 35, "int zz = D.s_c._function()"));

            VerifySpans(reader, reader.Methods[2], sourceLines,
                        new SpanResult(18, 4, 21, 5, "public C(Func<int> f)"),
                        new SpanResult(20, 8, 20, 22, "_function = f"));

            VerifySpans(reader, reader.Methods[3], sourceLines,                     // Synthesized static constructor for C
                        new SpanResult(23, 31, 23, 34, "115"),
                        new SpanResult(23, 19, 23, 35, "new C(() => 115)"));

            VerifySpans(reader, reader.Methods[4], sourceLines,                     // Synthesized instance constructor for D
                        new SpanResult(29, 30, 29, 33, "120"),
                        new SpanResult(31, 31, 31, 34, "130"),
                        new SpanResult(29, 18, 29, 34, "new C(() => 120)"),
                        new SpanResult(31, 19, 31, 35, "new C(() => 130)"));

            VerifySpans(reader, reader.Methods[5], sourceLines,                     // Synthesized static constructor for D
                        new SpanResult(30, 38, 30, 41, "144"),
                        new SpanResult(32, 39, 32, 42, "156"),
                        new SpanResult(30, 26, 30, 42, "new C(() => 144)"),
                        new SpanResult(32, 27, 32, 43, "new C(() => 156"));

            VerifySpans(reader, reader.Methods[6], sourceLines,                     // Synthesized static constructor for E
                        new SpanResult(41, 38, 41, 42, "1444"),
                        new SpanResult(42, 41, 42, 53, "return 1567"),
                        new SpanResult(41, 26, 41, 43, "new C(() => 1444)"),
                        new SpanResult(42, 27, 42, 56, "new C(() => { return 1567; })"));
        }
        partial void BindEcmaAssemblyName(RuntimeAssemblyName refName, bool cacheMissedLookups, ref AssemblyBindResult result, ref Exception exception, ref Exception preferredException, ref bool foundMatch)
        {
            lock (s_ecmaLoadedAssemblies)
            {
                for (int i = 0; i < s_ecmaLoadedAssemblies.Count; i++)
                {
                    PEInfo info = s_ecmaLoadedAssemblies[i];
                    if (AssemblyNameMatches(refName, info.Name, ref preferredException))
                    {
                        if (foundMatch)
                        {
                            exception = new AmbiguousMatchException();
                            return;
                        }

                        result.EcmaMetadataReader = info.Reader;
                        foundMatch = result.EcmaMetadataReader != null;

                        // For failed matches, we will never be able to succeed, so return now
                        if (!foundMatch)
                        {
                            return;
                        }
                    }
                }

                if (!foundMatch)
                {
                    try
                    {
                        // Not found in already loaded list, attempt to source assembly from disk
                        foreach (string filePath in FilePathsForAssembly(refName))
                        {
                            PEReader?ownedPEReader = null;
                            MemoryMappedViewAccessor?ownedMemoryMappedView = null;
                            try
                            {
                                if (!RuntimeAugments.FileExists(filePath))
                                {
                                    continue;
                                }

                                try
                                {
                                    ownedPEReader = OpenPEFile(filePath, out ownedMemoryMappedView);
                                }
                                catch (IOException)
                                {
                                    // Failure to open a file is not fundamentally an assembly load error, but it does indicate this file cannot be used
                                    continue;
                                }

                                if (!ownedPEReader.HasMetadata)
                                {
                                    continue;
                                }

                                MetadataReader reader = ownedPEReader.GetMetadataReader();
                                // Create AssemblyName from MetadataReader
                                RuntimeAssemblyName runtimeAssemblyName = reader.GetAssemblyDefinition().ToRuntimeAssemblyName(reader);

                                // If assembly name doesn't match, it isn't the one we're looking for. Continue to look for more assemblies
                                if (!AssemblyNameMatches(refName, runtimeAssemblyName, ref preferredException))
                                {
                                    continue;
                                }

                                // This is the one we are looking for, add it to the list of loaded assemblies
                                PEInfo peinfo = new PEInfo(runtimeAssemblyName, reader, ownedPEReader, ownedMemoryMappedView);

                                s_ecmaLoadedAssemblies.Add(peinfo);

                                // At this point the PE reader is no longer owned by this code, but is owned by the s_ecmaLoadedAssemblies list
                                PEReader pe = ownedPEReader;
                                ownedPEReader         = null;
                                ownedMemoryMappedView = null;

                                ModuleList moduleList    = ModuleList.Instance;
                                ModuleInfo newModuleInfo = new EcmaModuleInfo(moduleList.SystemModule.Handle, pe, reader);
                                moduleList.RegisterModule(newModuleInfo);

                                foundMatch = true;
                                result.EcmaMetadataReader = peinfo.Reader;
                                break;
                            }
                            finally
                            {
                                ownedPEReader?.Dispose();
                                ownedMemoryMappedView?.Dispose();
                            }
                        }
                    }
                    catch (IOException)
                    { }
                    catch (ArgumentException)
                    { }
                    catch (BadImageFormatException badImageFormat)
                    {
                        exception = badImageFormat;
                    }

                    // Cache missed lookups
                    if (cacheMissedLookups && !foundMatch)
                    {
                        PEInfo peinfo = new PEInfo(refName, null, null);
                        s_ecmaLoadedAssemblies.Add(peinfo);
                    }
                }
            }
        }
        public void CorLibWithAssemblyReferences()
        {
            string sourceLib =
                @"public class Private1
{
}
public class Private2
{
}";
            var compLib = CreateCompilationWithMscorlib(sourceLib, assemblyName: "System.Private.Library");

            compLib.VerifyDiagnostics();
            var refLib = compLib.EmitToImageReference();

            string sourceCorLib =
                @"using System.Runtime.CompilerServices;
[assembly: TypeForwardedTo(typeof(Private2))]
namespace System
{
    public class Object
    {
        public Private1 F() => null;
    }
#pragma warning disable 0436
    public class Void : Object { }
#pragma warning restore 0436
}";
            // Create a custom corlib with a reference to compilation
            // above and a reference to the actual mscorlib.
            var compCorLib = CreateCompilation(sourceCorLib, assemblyName: CorLibAssemblyName, references: new[] { MscorlibRef, refLib });

            compCorLib.VerifyDiagnostics();
            var objectType = compCorLib.SourceAssembly.GlobalNamespace.GetMember <NamedTypeSymbol>("System.Object");

            Assert.NotNull(objectType.BaseType);

            ImmutableArray <byte> peBytes;
            ImmutableArray <byte> pdbBytes;

            ExpressionCompilerTestHelpers.EmitCorLibWithAssemblyReferences(
                compCorLib,
                null,
                moduleBuilder => new PEAssemblyBuilderWithAdditionalReferences(moduleBuilder, objectType),
                out peBytes,
                out pdbBytes);

            using (var reader = new PEReader(peBytes))
            {
                var metadata       = reader.GetMetadata();
                var module         = metadata.ToModuleMetadata(ignoreAssemblyRefs: true);
                var metadataReader = metadata.ToMetadataReader();
                var moduleInstance = ModuleInstance.Create(metadata, metadataReader.GetModuleVersionIdOrThrow());

                // Verify the module declares System.Object.
                Assert.True(metadataReader.DeclaresTheObjectClass());
                // Verify the PEModule has no assembly references.
                Assert.Equal(0, module.Module.ReferencedAssemblies.Length);
                // Verify the underlying metadata has the expected assembly references.
                var actualReferences = metadataReader.AssemblyReferences.Select(r => metadataReader.GetString(metadataReader.GetAssemblyReference(r).Name)).ToImmutableArray();
                AssertEx.Equal(new[] { "mscorlib", "System.Private.Library" }, actualReferences);

                var source =
                    @"class C
{
    static void M()
    {
    }
}";
                var comp = CreateCompilation(source, options: TestOptions.DebugDll, references: new[] { refLib, AssemblyMetadata.Create(module).GetReference() });
                comp.VerifyDiagnostics();

                using (var runtime = RuntimeInstance.Create(new[] { comp.ToModuleInstance(), moduleInstance }))
                {
                    string error;
                    var    context = CreateMethodContext(runtime, "C.M");

                    // Valid expression.
                    var testData = new CompilationTestData();
                    context.CompileExpression(
                        "new object()",
                        out error,
                        testData);
                    Assert.Null(error);
                    testData.GetMethodData("<>x.<>m0").VerifyIL(
                        @"{
  // Code size        6 (0x6)
  .maxstack  1
  IL_0000:  newobj     ""object..ctor()""
  IL_0005:  ret
}");

                    // Invalid expression: System.Int32 is not defined in corlib above.
                    testData = new CompilationTestData();
                    context.CompileExpression(
                        "1",
                        out error,
                        testData);
                    Assert.Equal("error CS0518: Predefined type 'System.Int32' is not defined or imported", error);

                    // Invalid expression: type in method signature from missing referenced assembly.
                    testData = new CompilationTestData();
                    context.CompileExpression(
                        "(new object()).F()",
                        out error,
                        testData);
                    Assert.Equal("error CS0570: 'object.F()' is not supported by the language", error);

                    // Invalid expression: type forwarded to missing referenced assembly.
                    testData = new CompilationTestData();
                    context.CompileExpression(
                        "new Private2()",
                        out error,
                        testData);
                    Assert.Equal("error CS0246: The type or namespace name 'Private2' could not be found (are you missing a using directive or an assembly reference?)", error);
                }
            }
        }
Esempio n. 40
0
        private async Task <bool> AssemblyIsDebuggable(AnalysisContext ctx, string item, CancellationToken cancellationToken)
        {
            using var fileStream = new MemoryStream();
            using (var rawStream = ctx.PackageReader.GetStream(item))
            {
                await rawStream.CopyToAsync(fileStream, cancellationToken);

                fileStream.Position = 0;
            }

            // Check if the package has a corresponding symbol file for the assembly.
            var symbolPath = Path.ChangeExtension(item, "pdb");

            if (ctx.PackageFiles.Contains(symbolPath))
            {
                // TODO: Check that the PDB and DLL match.
                // See: https://github.com/NuGet/NuGet.Jobs/blob/master/src/Validation.Symbols/SymbolsValidatorService.cs#L190-L249
                var pdbStream = ctx.PackageReader.GetStream(symbolPath);
                if (HasSourceLink(pdbStream))
                {
                    ctx.Messages.Add("The NuGet package does not have SourceLink");
                    return(false);
                }
            }

            // Check if the assembly has embedded symbols.
            using var peReader = new PEReader(fileStream);

            using (var embeddedSymbolsProvider = peReader.GetEmbeddedSymbolsProviderOrNull())
            {
                if (embeddedSymbolsProvider != null)
                {
                    var pdbReader = embeddedSymbolsProvider.GetMetadataReader();

                    if (!pdbReader.HasSourceLink())
                    {
                        ctx.Messages.Add("The NuGet package does not have SourceLink");
                        return(false);
                    }
                }
            }

            // The assembly does not have symbols within the package. Try to load the symbols from a symbol server.
            foreach (var symbolKey in peReader.GetSymbolKeys())
            {
                using var pdbStream = await _symbols.GetSymbolsAsync(symbolKey.Key, symbolKey.Checksums, cancellationToken);

                if (pdbStream != null)
                {
                    using var seekablePdbStream = new MemoryStream();
                    await pdbStream.CopyToAsync(seekablePdbStream, cancellationToken);

                    seekablePdbStream.Position = 0;

                    if (!HasSourceLink(seekablePdbStream))
                    {
                        ctx.Messages.Add("The NuGet package does not have SourceLink");
                        return(false);
                    }

                    return(true);
                }
            }

            ctx.Messages.Add("NuGet package does not have symbols");
            return(false);
        }
Esempio n. 41
0
        /// <summary>
        /// Constructs a PEImage class for a given PE image (dll/exe) in memory.
        /// </summary>
        /// <param name="stream">A Stream that contains a PE image at its 0th offset.  This stream must be seekable.</param>
        /// <param name="leaveOpen">Whether or not to leave the stream open, if this is set to false stream will be
        /// disposed when this object is.</param>
        /// <param name="isVirtual">Whether stream points to a PE image mapped into an address space (such as in a live process or crash dump).</param>
        public PEImage(Stream stream, bool leaveOpen, bool isVirtual)
        {
            _isVirtual = isVirtual;
            _stream    = stream ?? throw new ArgumentNullException(nameof(stream));

            if (!stream.CanSeek)
            {
                throw new ArgumentException($"{nameof(stream)} is not seekable.");
            }

            ushort dosHeaderMagic = Read <ushort>(0);

            if (dosHeaderMagic != ExpectedDosHeaderMagic)
            {
                if (!leaveOpen)
                {
                    stream.Dispose();
                }

                return;
            }

            int peHeaderOffset = Read <int>(PESignatureOffsetLocation);

            if (peHeaderOffset == 0)
            {
                if (!leaveOpen)
                {
                    stream.Dispose();
                }

                return;
            }

            uint peSignature = Read <uint>(peHeaderOffset);

            if (peSignature != ExpectedPESignature)
            {
                if (!leaveOpen)
                {
                    stream.Dispose();
                }

                return;
            }

            SeekTo(0);

            PEStreamOptions options = PEStreamOptions.Default;

            if (leaveOpen)
            {
                options |= PEStreamOptions.LeaveOpen;
            }

            if (isVirtual)
            {
                options |= PEStreamOptions.IsLoadedImage;
            }

            try
            {
                var reader = new PEReader(stream, options);
                _peHeaders = reader.PEHeaders;
                Reader     = reader;
            }
            catch (BadImageFormatException)
            {
            }
        }
        public void DebugDirectoryData_Errors()
        {
            var reader = new PEReader(new MemoryStream(Misc.Members));

            Assert.Throws<ArgumentException>("entry", () => reader.ReadCodeViewDebugDirectoryData(new DebugDirectoryEntry(0, 0, 0, DebugDirectoryEntryType.Coff, 0, 0, 0)));
            Assert.Throws<BadImageFormatException>(() => reader.ReadCodeViewDebugDirectoryData(new DebugDirectoryEntry(0, 0, 0, DebugDirectoryEntryType.CodeView, 0, 0, 0)));

            Assert.Throws<ArgumentException>("entry", () => reader.ReadEmbeddedPortablePdbDebugDirectoryData(new DebugDirectoryEntry(0, 0, 0, DebugDirectoryEntryType.Coff, 0, 0, 0)));
            Assert.Throws<BadImageFormatException>(() => reader.ReadEmbeddedPortablePdbDebugDirectoryData(new DebugDirectoryEntry(0, 0, 0, DebugDirectoryEntryType.EmbeddedPortablePdb, 0, 0, 0)));
        }
        private EcmaModule AddModule(string filePath, string expectedSimpleName, bool useForBinding, ModuleData oldModuleData = null)
        {
            PEReader peReader = null;
            MemoryMappedViewAccessor mappedViewAccessor = null;
            PdbSymbolReader          pdbReader          = null;

            try
            {
                if (oldModuleData == null)
                {
                    peReader = OpenPEFile(filePath, out mappedViewAccessor);

#if !READYTORUN
                    if (peReader.HasMetadata && (peReader.PEHeaders.CorHeader.Flags & (CorFlags.ILLibrary | CorFlags.ILOnly)) == 0)
                    {
                        throw new NotSupportedException($"Error: C++/CLI is not supported: '{filePath}'");
                    }
#endif

                    pdbReader = PortablePdbSymbolReader.TryOpenEmbedded(peReader, GetMetadataStringDecoder()) ?? OpenAssociatedSymbolFile(filePath, peReader);
                }
                else
                {
                    filePath           = oldModuleData.FilePath;
                    peReader           = oldModuleData.Module.PEReader;
                    mappedViewAccessor = oldModuleData.MappedViewAccessor;
                    pdbReader          = oldModuleData.Module.PdbReader;
                }

                EcmaModule module = EcmaModule.Create(this, peReader, containingAssembly: null, pdbReader);

                MetadataReader metadataReader = module.MetadataReader;
                string         simpleName     = metadataReader.GetString(metadataReader.GetAssemblyDefinition().Name);

                if (expectedSimpleName != null && !simpleName.Equals(expectedSimpleName, StringComparison.OrdinalIgnoreCase))
                {
                    throw new FileNotFoundException("Assembly name does not match filename " + filePath);
                }

                ModuleData moduleData = new ModuleData()
                {
                    SimpleName         = simpleName,
                    FilePath           = filePath,
                    Module             = module,
                    MappedViewAccessor = mappedViewAccessor
                };

                lock (this)
                {
                    if (useForBinding)
                    {
                        ModuleData actualModuleData = _simpleNameHashtable.AddOrGetExisting(moduleData);
                        if (actualModuleData != moduleData)
                        {
                            if (actualModuleData.FilePath != filePath)
                            {
                                throw new FileNotFoundException("Module with same simple name already exists " + filePath);
                            }
                            return(actualModuleData.Module);
                        }
                    }
                    mappedViewAccessor = null; // Ownership has been transfered
                    pdbReader          = null; // Ownership has been transferred

                    _moduleHashtable.AddOrGetExisting(moduleData);
                }

                return(module);
            }
            finally
            {
                if (mappedViewAccessor != null)
                {
                    mappedViewAccessor.Dispose();
                }
                if (pdbReader != null)
                {
                    pdbReader.Dispose();
                }
            }
        }
        private void ValidateEmbeddedPortablePdb(PEReader reader)
        {
            var entries = reader.ReadDebugDirectory();
            Assert.Equal(DebugDirectoryEntryType.CodeView, entries[0].Type);
            Assert.Equal(DebugDirectoryEntryType.Reproducible, entries[1].Type);
            Assert.Equal(DebugDirectoryEntryType.EmbeddedPortablePdb, entries[2].Type);

            var provider = reader.ReadEmbeddedPortablePdbDebugDirectoryData(entries[2]);
            var pdbReader = provider.GetMetadataReader();
            var document = pdbReader.GetDocument(pdbReader.Documents.First());
            Assert.Equal(@"C:\Documents.cs", pdbReader.GetString(document.Name));
        }
Esempio n. 45
0
 internal FieldLayout(PEReader buff)
 {
     offset  = buff.ReadUInt32();
     fieldIx = buff.GetIndex(MDTable.Field);
     tabIx   = MDTable.FieldLayout;
 }
Esempio n. 46
0
        public void Dispose()
        {
            var peStream = new MemoryStream(PortablePdbs.DocumentsEmbeddedDll);
            var reader = new PEReader(peStream);

            MetadataReaderProvider pdbProvider;
            string pdbPath;

            Assert.True(reader.TryOpenAssociatedPortablePdb(@"x", _ => null, out pdbProvider, out pdbPath));
            Assert.NotNull(pdbProvider);
            Assert.Null(pdbPath);

            var ddEntries = reader.ReadDebugDirectory();
            var ddCodeView = ddEntries[0];
            var ddEmbedded = ddEntries[2];

            var embeddedPdbProvider = reader.ReadEmbeddedPortablePdbDebugDirectoryData(ddEmbedded);

            // dispose the PEReader:
            reader.Dispose();

            Assert.False(reader.IsEntireImageAvailable);

            Assert.Throws<ObjectDisposedException>(() => reader.PEHeaders);
            Assert.Throws<ObjectDisposedException>(() => reader.HasMetadata);
            Assert.Throws<ObjectDisposedException>(() => reader.GetMetadata());
            Assert.Throws<ObjectDisposedException>(() => reader.GetSectionData(1000));
            Assert.Throws<ObjectDisposedException>(() => reader.GetMetadataReader());
            Assert.Throws<ObjectDisposedException>(() => reader.GetMethodBody(0));
            Assert.Throws<ObjectDisposedException>(() => reader.GetEntireImage());
            Assert.Throws<ObjectDisposedException>(() => reader.ReadDebugDirectory());
            Assert.Throws<ObjectDisposedException>(() => reader.ReadCodeViewDebugDirectoryData(ddCodeView));
            Assert.Throws<ObjectDisposedException>(() => reader.ReadEmbeddedPortablePdbDebugDirectoryData(ddEmbedded));

            MetadataReaderProvider __;
            string ___;
            Assert.Throws<ObjectDisposedException>(() => reader.TryOpenAssociatedPortablePdb(@"x", _ => null, out __, out ___));

            // ok to use providers after PEReader disposed:
            var pdbReader = pdbProvider.GetMetadataReader();
            Assert.Equal(13, pdbReader.Documents.Count);

            pdbReader = embeddedPdbProvider.GetMetadataReader();
            Assert.Equal(13, pdbReader.Documents.Count);

            embeddedPdbProvider.Dispose();
        }
Esempio n. 47
0
        private unsafe void ValidateSectionData(PEReader reader)
        {
            var relocBlob1 = reader.GetSectionData(".reloc").GetContent();
            var relocBlob2 = reader.GetSectionData(0x6000).GetContent();

            AssertEx.Equal(new byte[] 
            {
                0x00, 0x20, 0x00, 0x00,
                0x0C, 0x00, 0x00, 0x00,
                0xD0, 0x38, 0x00, 0x00
            }, relocBlob1);

            AssertEx.Equal(relocBlob1, relocBlob2);

            var data = reader.GetSectionData(0x5fff);
            Assert.True(data.Pointer == null);
            Assert.Equal(0, data.Length);
            AssertEx.Equal(new byte[0], data.GetContent());

            data = reader.GetSectionData(0x600B);
            Assert.True(data.Pointer != null);
            Assert.Equal(1, data.Length);
            AssertEx.Equal(new byte[] { 0x00 }, data.GetContent());

            data = reader.GetSectionData(0x600C);
            Assert.True(data.Pointer == null);
            Assert.Equal(0, data.Length);
            AssertEx.Equal(new byte[0], data.GetContent());

            data = reader.GetSectionData(0x600D);
            Assert.True(data.Pointer == null);
            Assert.Equal(0, data.Length);
            AssertEx.Equal(new byte[0], data.GetContent());

            data = reader.GetSectionData(int.MaxValue);
            Assert.True(data.Pointer == null);
            Assert.Equal(0, data.Length);
            AssertEx.Equal(new byte[0], data.GetContent());

            data = reader.GetSectionData(".nonexisting");
            Assert.True(data.Pointer == null);
            Assert.Equal(0, data.Length);
            AssertEx.Equal(new byte[0], data.GetContent());

            data = reader.GetSectionData("");
            Assert.True(data.Pointer == null);
            Assert.Equal(0, data.Length);
            AssertEx.Equal(new byte[0], data.GetContent());
        }
        /// <summary>
        /// Read everything from the assembly in a single stream.
        /// </summary>
        /// <returns></returns>
        private void CorePopulateMetadata()
        {
            if (_metadataRead)
            {
                return;
            }

            lock (this)
            {
                if (_metadataRead)
                {
                    return;
                }

                using (var stream = File.OpenRead(_sourceFile))
                    using (var peFile = new PEReader(stream))
                    {
                        var metadataReader = peFile.GetMetadataReader();

                        List <AssemblyNameExtension> ret = new List <AssemblyNameExtension>();

                        foreach (var handle in metadataReader.AssemblyReferences)
                        {
                            var entry = metadataReader.GetAssemblyReference(handle);

                            var assemblyName = new AssemblyName
                            {
                                Name        = metadataReader.GetString(entry.Name),
                                Version     = entry.Version,
                                CultureName = metadataReader.GetString(entry.Culture)
                            };
                            var publicKeyOrToken = metadataReader.GetBlobBytes(entry.PublicKeyOrToken);
                            if (publicKeyOrToken != null)
                            {
                                if (publicKeyOrToken.Length <= 8)
                                {
                                    assemblyName.SetPublicKeyToken(publicKeyOrToken);
                                }
                                else
                                {
                                    assemblyName.SetPublicKey(publicKeyOrToken);
                                }
                            }
                            assemblyName.Flags = (AssemblyNameFlags)(int)entry.Flags;

                            ret.Add(new AssemblyNameExtension(assemblyName));
                        }

                        _assemblyDependencies = ret.ToArray();

                        var attrs = metadataReader.GetAssemblyDefinition().GetCustomAttributes()
                                    .Select(ah => metadataReader.GetCustomAttribute(ah));

                        foreach (var attr in attrs)
                        {
                            var ctorHandle = attr.Constructor;
                            if (ctorHandle.Kind != HandleKind.MemberReference)
                            {
                                continue;
                            }

                            var container = metadataReader.GetMemberReference((MemberReferenceHandle)ctorHandle).Parent;
                            var name      = metadataReader.GetTypeReference((TypeReferenceHandle)container).Name;
                            if (!string.Equals(metadataReader.GetString(name), "TargetFrameworkAttribute"))
                            {
                                continue;
                            }

                            var arguments = GetFixedStringArguments(metadataReader, attr);
                            if (arguments.Count == 1)
                            {
                                _frameworkName = new FrameworkName(arguments[0]);
                            }
                        }
                    }

                _metadataRead = true;
            }
        }
Esempio n. 49
0
        public void SubStream()
        {
            var stream = new MemoryStream();
            stream.WriteByte(0xff);
            stream.Write(Misc.Members, 0, Misc.Members.Length);
            stream.WriteByte(0xff);
            stream.WriteByte(0xff);

            stream.Position = 1;
            var peReader1 = new PEReader(stream, PEStreamOptions.LeaveOpen, Misc.Members.Length);

            Assert.Equal(Misc.Members.Length, peReader1.GetEntireImage().Length);
            peReader1.GetMetadataReader();

            stream.Position = 1;
            var peReader2 = new PEReader(stream, PEStreamOptions.LeaveOpen | PEStreamOptions.PrefetchMetadata, Misc.Members.Length);

            Assert.Equal(Misc.Members.Length, peReader2.GetEntireImage().Length);
            peReader2.GetMetadataReader();
            stream.Position = 1;

            var peReader3 = new PEReader(stream, PEStreamOptions.LeaveOpen | PEStreamOptions.PrefetchEntireImage, Misc.Members.Length);

            Assert.Equal(Misc.Members.Length, peReader3.GetEntireImage().Length);
            peReader3.GetMetadataReader();
        }
Esempio n. 50
0
        public void ResourceStatementKinds()
        {
            string source = @"
using System;

public class C
{
    public static void Main()
    {
        int z = 11;
        int x = z + 10;
        switch (z)
        {
            case 1:
                break;
            case 2:
                break;
            case 3:
                break;
            default:
                break;
        }

        if (x > 10)
        {
            x++;
        }
        else
        {
            x--;
        }

        for (int y = 0; y < 50; y++)
        {
            if (y < 30)
            {
                x++;
                continue;
            }
            else
                break;
        }

        int[] a = new int[] { 1, 2, 3, 4 };
        foreach (int i in a)
        {
            x++;
        }

        while (x < 100)
        {
            x++;
        }

        try
        {
            x++;
            if (x > 10)
            {
                throw new System.Exception();
            }
            x++;
        }
        catch (System.Exception e)
        {
            x++;
        }
        finally
        {
            x++;
        }

        lock (new object())
        {
            ;
        }

        Console.WriteLine(x);

        try
        {
            using ((System.IDisposable)new object())
            {
                ;
            }
        }
        catch (System.Exception e)
        {
        }

        return;
    }
}
";

            var c       = CreateCompilation(Parse(source + InstrumentationHelperSource, @"C:\myproject\doc1.cs"));
            var peImage = c.EmitToArray(EmitOptions.Default.WithInstrumentationKinds(ImmutableArray.Create(InstrumentationKind.TestCoverage)));

            var peReader = new PEReader(peImage);
            var reader   = DynamicAnalysisDataReader.TryCreateFromPE(peReader, "<DynamicAnalysisData>");

            VerifyDocuments(reader, reader.Documents,
                            @"'C:\myproject\doc1.cs' 6A-DC-C0-8A-16-CB-7C-A5-99-8B-2E-0C-3C-81-69-2C-B2-10-EE-F1 (SHA1)");

            Assert.Equal(6, reader.Methods.Length);

            string[] sourceLines = source.Split('\n');

            VerifySpans(reader, reader.Methods[0], sourceLines,
                        new SpanResult(5, 4, 89, 5, "public static void Main()"),
                        new SpanResult(7, 8, 7, 19, "int z = 11"),
                        new SpanResult(8, 8, 8, 23, "int x = z + 10"),
                        new SpanResult(12, 16, 12, 22, "break"),
                        new SpanResult(14, 16, 14, 22, "break"),
                        new SpanResult(16, 16, 16, 22, "break"),
                        new SpanResult(18, 16, 18, 22, "break"),
                        new SpanResult(9, 16, 9, 17, "z"),
                        new SpanResult(23, 12, 23, 16, "x++"),
                        new SpanResult(27, 12, 27, 16, "x--"),
                        new SpanResult(21, 12, 21, 18, "x > 10"),
                        new SpanResult(30, 17, 30, 22, "y = 0"),
                        new SpanResult(30, 32, 30, 35, "y++"),
                        new SpanResult(34, 16, 34, 20, "x++"),
                        new SpanResult(35, 16, 35, 25, "continue"),
                        new SpanResult(38, 16, 38, 22, "break"),
                        new SpanResult(32, 16, 32, 22, "y < 30"),
                        new SpanResult(41, 8, 41, 43, "int[] a = new int[] { 1, 2, 3, 4 }"),
                        new SpanResult(44, 12, 44, 16, "x++"),
                        new SpanResult(42, 26, 42, 27, "a"),
                        new SpanResult(49, 12, 49, 16, "x++"),
                        new SpanResult(47, 15, 47, 22, "x < 100"),
                        new SpanResult(54, 12, 54, 16, "x++"),
                        new SpanResult(57, 16, 57, 45, "throw new System.Exception()"),
                        new SpanResult(55, 16, 55, 22, "x > 10"),
                        new SpanResult(59, 12, 59, 16, "x++"),
                        new SpanResult(63, 12, 63, 16, "x++"),
                        new SpanResult(67, 12, 67, 16, "x++"),
                        new SpanResult(72, 12, 72, 13, ";"),
                        new SpanResult(70, 14, 70, 26, "new object()"),
                        new SpanResult(75, 8, 75, 29, "Console.WriteLine(x)"),
                        new SpanResult(81, 16, 81, 17, ";"),
                        new SpanResult(79, 19, 79, 51, "(System.IDisposable)new object()"),
                        new SpanResult(88, 8, 88, 15, "return"));

            VerifySpans(reader, reader.Methods[1]);
        }
Esempio n. 51
0
 public void EntireImage_LazyLoad()
 {
     var peStream = new MemoryStream(Misc.Members);
     using (var reader = new PEReader(peStream, PEStreamOptions.LeaveOpen))
     {
         Assert.Equal(4608, reader.GetEntireImage().Length);
     }
 }
Esempio n. 52
0
        public void TestMethodSpansWithAttributes()
        {
            string source = @"
using System;
using System.Security;

public class C
{
    static int x;

    public static void Main()                       // Method 0
    {
        Fred();
    }
            
    [Obsolete()]
    static void Fred()                              // Method 1
    {
    }

    static C()                                      // Method 2
    {
        x = 12;
    }

    [Obsolete()]
    public C()                                      // Method 3
    {
    }

    int Wilma
    {
        [SecurityCritical]
        get { return 12; }                          // Method 4
    }

    [Obsolete()]
    int Betty => 13;                                // Method 5

    [SecurityCritical]
    int Pebbles()                                   // Method 6
    {
        return 3;
    }

    [SecurityCritical]
    ref int BamBam(ref int x)                       // Method 7
    {
        return ref x;
    }

    [SecurityCritical]
    C(int x)                                        // Method 8
    {
    }

    [Obsolete()]
    public int Barney => 13;                        // Method 9

    [SecurityCritical]
    public static C operator +(C a, C b)            // Method 10
    {
        return a;
    }
}
";

            var c       = CreateCompilation(Parse(source + InstrumentationHelperSource, @"C:\myproject\doc1.cs"));
            var peImage = c.EmitToArray(EmitOptions.Default.WithInstrumentationKinds(ImmutableArray.Create(InstrumentationKind.TestCoverage)));

            var peReader = new PEReader(peImage);
            var reader   = DynamicAnalysisDataReader.TryCreateFromPE(peReader, "<DynamicAnalysisData>");

            VerifyDocuments(reader, reader.Documents,
                            @"'C:\myproject\doc1.cs' A3-08-94-55-7C-64-8D-C7-61-7A-11-0B-4B-68-2C-3B-51-C3-C4-58 (SHA1)");

            Assert.Equal(15, reader.Methods.Length);

            string[] sourceLines = source.Split('\n');

            VerifySpans(reader, reader.Methods[0], sourceLines,
                        new SpanResult(8, 4, 11, 5, "public static void Main()"),
                        new SpanResult(10, 8, 10, 15, "Fred()"));

            VerifySpans(reader, reader.Methods[1], sourceLines,
                        new SpanResult(14, 4, 16, 5, "static void Fred()"));

            VerifySpans(reader, reader.Methods[2], sourceLines,
                        new SpanResult(18, 4, 21, 5, "static C()"),
                        new SpanResult(20, 8, 20, 15, "x = 12"));

            VerifySpans(reader, reader.Methods[3], sourceLines,
                        new SpanResult(24, 4, 26, 5, "public C()"));

            VerifySpans(reader, reader.Methods[4], sourceLines,
                        new SpanResult(31, 8, 31, 26, "get {"),
                        new SpanResult(31, 14, 31, 24, "return 12"));

            VerifySpans(reader, reader.Methods[5], sourceLines,
                        new SpanResult(35, 4, 35, 20, "int Betty"),
                        new SpanResult(35, 17, 35, 19, "13"));

            VerifySpans(reader, reader.Methods[6], sourceLines,
                        new SpanResult(38, 4, 41, 5, "int Pebbles()"),
                        new SpanResult(40, 8, 40, 17, "return 3"));

            VerifySpans(reader, reader.Methods[7], sourceLines,
                        new SpanResult(44, 4, 47, 5, "ref int BamBam"),
                        new SpanResult(46, 8, 46, 21, "return ref x"));

            VerifySpans(reader, reader.Methods[8], sourceLines,
                        new SpanResult(50, 4, 52, 5, "C(int x)"));

            VerifySpans(reader, reader.Methods[9], sourceLines,
                        new SpanResult(55, 4, 55, 28, "public int Barney"),
                        new SpanResult(55, 25, 55, 27, "13"));

            VerifySpans(reader, reader.Methods[10], sourceLines,
                        new SpanResult(58, 4, 61, 5, "public static C operator +"),
                        new SpanResult(60, 8, 60, 17, "return a"));
        }
Esempio n. 53
0
        private void metroButton1_Click(object sender, EventArgs e)
        {
            var ofd = new OpenFileDialog
            {
                Filter = "Dynamic Link Library (*.dll)|*.dll|System Driver Library (*.sys/*.drv)|*.sys;*.drv"
            };

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                if (File.Exists(ofd.FileName))
                {
                    var per = new PEReader(ofd.FileName);
                    txtDllToInj.Text = "File: " + Path.GetFileName(ofd.FileName);

                    if (per.GetExports != null)
                    {
                        txtDllToInj.Text += Environment.NewLine +
                                            Environment.NewLine + "EXPORTS:" + Environment.NewLine +
                                            Environment.NewLine;
                        foreach (var exp in per.GetExports)
                        {
                            txtDllToInj.Text += string.Format("Name: {0}{1}Address: 0x{2}{1}", exp.Name,
                                                              Environment.NewLine,
                                                              exp.Address);
                        }

                        FileToInject = ofd.FileName;
                        try
                        {
                            modToInject       = new Module(FileToInject);
                            btnInject.Enabled = true;

                            try
                            {
                                foreach (var pex in per.GetExports)
                                {
                                    var tmp = modToInject.GetExportAddress(pex.Name);
                                    cbExports.Items.Add(pex.Name);
                                }

                                hasExports = true;
                            }
                            catch (Exception emm)
                            {
                                log.Log(emm, "Failed to load export from Module...");
                            }
                        }
                        catch (Exception ex)
                        {
                            log.Log(ex, "Failed to initiate Module...");
                        }
                    }
                    else
                    {
                        if (MessageBox.Show(
                                "No exports could be located within the selected PE file to inject\r\n\r\nAre you really sure you wish to continue loading this PE?",
                                "Are you sure?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                        {
                            FileToInject = ofd.FileName;
                            try
                            {
                                modToInject       = new Module(FileToInject);
                                btnInject.Enabled = true;
                                hasExports        = false;
                            }
                            catch (Exception ex)
                            {
                                log.Log(ex, "Failed to initiate Module...");
                            }
                        }
                    }
                }
            }
        }
Esempio n. 54
0
        public unsafe void NativeResources()
        {
            var peStream = new MemoryStream();
            var ilBuilder = new BlobBuilder();
            var metadataBuilder = new MetadataBuilder();
            
            var peBuilder = new ManagedPEBuilder(
                PEHeaderBuilder.CreateLibraryHeader(),
                new MetadataRootBuilder(metadataBuilder),
                ilBuilder,
                nativeResources: new TestResourceSectionBuilder(),
                deterministicIdProvider: content => s_contentId);
            
            var peBlob = new BlobBuilder();
            
            var contentId = peBuilder.Serialize(peBlob);
            
            peBlob.WriteContentTo(peStream);

            peStream.Position = 0;
            var peReader = new PEReader(peStream);
            var sectionHeader = peReader.PEHeaders.SectionHeaders.Single(s => s.Name == ".rsrc");

            var image = peReader.GetEntireImage();

            var reader = new BlobReader(image.Pointer + sectionHeader.PointerToRawData, sectionHeader.SizeOfRawData);
            Assert.Equal(0x12345678, reader.ReadInt32());
            Assert.Equal(sectionHeader.PointerToRawData, reader.ReadInt32());
            Assert.Equal(sectionHeader.VirtualAddress, reader.ReadInt32());
        }
Esempio n. 55
0
        public void Metadata_LazyLoad()
        {
            var peStream = new MemoryStream(Misc.Members);
            using (var reader = new PEReader(peStream, PEStreamOptions.LeaveOpen))
            {
                var md = reader.GetMetadataReader();
                var method = md.GetMethodDefinition(MetadataTokens.MethodDefinitionHandle(1));

                Assert.Equal("MC1", md.GetString(method.Name));
            }
        }
Esempio n. 56
0
        public void TryOpenAssociatedPortablePdb_ExpectedExceptionFromStreamProvider_NoFallback()
        {
            var pdbBuilder = new BlobBuilder();
            pdbBuilder.WriteBytes(PortablePdbs.DocumentsPdb);

            var id = new BlobContentId(Guid.Parse("18091B06-32BB-46C2-9C3B-7C9389A2F6C6"), 0x12345678);
            var ddBuilder = new DebugDirectoryBuilder();
            ddBuilder.AddCodeViewEntry(@"/a/b/a.pdb", id, portablePdbVersion: 0x0100);

            var peStream = new MemoryStream(TestBuilders.BuildPEWithDebugDirectory(ddBuilder));

            using (var reader = new PEReader(peStream))
            {
                MetadataReaderProvider pdbProvider;
                string pdbPath;

                Assert.Throws<IOException>(() =>
                    reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), _ => { throw new IOException(); }, out pdbProvider, out pdbPath));

                AssertEx.Throws<BadImageFormatException>(() =>
                    reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), _ => { throw new BadImageFormatException("Bang!"); }, out pdbProvider, out pdbPath),
                    e => Assert.Equal("Bang!", e.Message));

                // file doesn't exist and no embedded => return false
                Assert.False(reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), _ => { throw new FileNotFoundException(); }, out pdbProvider, out pdbPath));
            }
        }
        public static string DetectTargetFrameworkId(this PEReader assembly, string assemblyPath = null)
        {
            if (assembly == null)
            {
                throw new ArgumentNullException(nameof(assembly));
            }

            const string TargetFrameworkAttributeName = "System.Runtime.Versioning.TargetFrameworkAttribute";
            var          reader = assembly.GetMetadataReader();

            foreach (var h in reader.GetCustomAttributes(Handle.AssemblyDefinition))
            {
                try
                {
                    var attribute = reader.GetCustomAttribute(h);
                    if (attribute.GetAttributeType(reader).GetFullTypeName(reader).ToString() != TargetFrameworkAttributeName)
                    {
                        continue;
                    }
                    var blobReader = reader.GetBlobReader(attribute.Value);
                    if (blobReader.ReadUInt16() == 0x0001)
                    {
                        return(blobReader.ReadSerializedString());
                    }
                }
                catch (BadImageFormatException)
                {
                    // ignore malformed attributes
                }
            }

            foreach (var h in reader.AssemblyReferences)
            {
                try
                {
                    var r = reader.GetAssemblyReference(h);
                    if (r.PublicKeyOrToken.IsNil)
                    {
                        continue;
                    }
                    string version;
                    switch (reader.GetString(r.Name))
                    {
                    case "netstandard":
                        version = r.Version.ToString(3);
                        return($".NETStandard,Version=v{version}");

                    case "System.Runtime":
                        // System.Runtime.dll uses the following scheme:
                        // 4.2.0 => .NET Core 2.0
                        // 4.2.1 => .NET Core 2.1 / 3.0
                        // 4.2.2 => .NET Core 3.1
                        if (r.Version >= new Version(4, 2, 0))
                        {
                            version = "2.0";
                            if (r.Version >= new Version(4, 2, 1))
                            {
                                version = "3.0";
                            }
                            if (r.Version >= new Version(4, 2, 2))
                            {
                                version = "3.1";
                            }
                            return($".NETCoreApp,Version=v{version}");
                        }
                        else
                        {
                            continue;
                        }

                    case "mscorlib":
                        version = r.Version.ToString(2);
                        return($".NETFramework,Version=v{version}");
                    }
                }
                catch (BadImageFormatException)
                {
                    // ignore malformed references
                }
            }

            // Optionally try to detect target version through assembly path as a fallback (use case: reference assemblies)
            if (assemblyPath != null)
            {
                /*
                 * Detected path patterns (examples):
                 *
                 * - .NETFramework -> C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\mscorlib.dll
                 * - .NETCore      -> C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.1.0\ref\netcoreapp2.1\System.Console.dll
                 * - .NETStandard  -> C:\Program Files\dotnet\sdk\NuGetFallbackFolder\netstandard.library\2.0.3\build\netstandard2.0\ref\netstandard.dll
                 */
                var pathMatch = Regex.Match(assemblyPath, PathPattern,
                                            RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.ExplicitCapture);
                if (pathMatch.Success)
                {
                    var type    = pathMatch.Groups["type"].Value;
                    var version = pathMatch.Groups["version"].Value;
                    if (string.IsNullOrEmpty(version))
                    {
                        version = reader.MetadataVersion;
                    }

                    if (type == "Microsoft.NET" || type == ".NETFramework")
                    {
                        return($".NETFramework,Version=v{version.TrimStart('v').Substring(0, 3)}");
                    }
                    else if (type.IndexOf("netcore", StringComparison.OrdinalIgnoreCase) >= 0)
                    {
                        return($".NETCoreApp,Version=v{version}");
                    }
                    else if (type.IndexOf("netstandard", StringComparison.OrdinalIgnoreCase) >= 0)
                    {
                        return($".NETStandard,Version=v{version}");
                    }
                }
                else
                {
                    return($".NETFramework,Version={reader.MetadataVersion.Substring(0, 4)}");
                }
            }

            return(string.Empty);
        }
Esempio n. 58
0
        public void TryOpenAssociatedPortablePdb_BadStreamProvider()
        {
            var pdbBuilder = new BlobBuilder();
            pdbBuilder.WriteBytes(PortablePdbs.DocumentsPdb);

            var id = new BlobContentId(Guid.Parse("18091B06-32BB-46C2-9C3B-7C9389A2F6C6"), 0x12345678);
            var ddBuilder = new DebugDirectoryBuilder();
            ddBuilder.AddCodeViewEntry(@"/a/b/a.pdb", id, portablePdbVersion: 0x0100);

            var peStream = new MemoryStream(TestBuilders.BuildPEWithDebugDirectory(ddBuilder));

            using (var reader = new PEReader(peStream))
            {
                MetadataReaderProvider pdbProvider;
                string pdbPath;

                // pass-thru:
                Assert.Throws<ArgumentException>(() =>
                    reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), _ => { throw new ArgumentException(); }, out pdbProvider, out pdbPath));

                Assert.Throws<InvalidOperationException>(() =>
                    reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), _ => { return new TestStream(canRead: false, canWrite: true, canSeek: true); }, out pdbProvider, out pdbPath));

                Assert.Throws<InvalidOperationException>(() =>
                    reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), _ => { return new TestStream(canRead: true, canWrite: true, canSeek: false); }, out pdbProvider, out pdbPath));
            }
        }
Esempio n. 59
0
 private ModuleMetadata(PEReader peReader)
     : base(isImageOwner: true, id: new MetadataId())
 {
     _module = new PEModule(this, peReader: peReader, metadataOpt: IntPtr.Zero, metadataSizeOpt: 0);
 }
Esempio n. 60
0
        public void TryOpenAssociatedPortablePdb_ExpectedExceptionFromStreamProvider_FallbackOnEmbedded_Valid()
        {
            var pdbBuilder = new BlobBuilder();
            pdbBuilder.WriteBytes(PortablePdbs.DocumentsPdb);

            var id = new BlobContentId(Guid.Parse("18091B06-32BB-46C2-9C3B-7C9389A2F6C6"), 0x12345678);
            var ddBuilder = new DebugDirectoryBuilder();
            ddBuilder.AddCodeViewEntry(@"/a/b/a.pdb", id, portablePdbVersion: 0x0100);
            ddBuilder.AddEmbeddedPortablePdbEntry(pdbBuilder, portablePdbVersion: 0x0100);

            var peStream = new MemoryStream(TestBuilders.BuildPEWithDebugDirectory(ddBuilder));

            using (var reader = new PEReader(peStream))
            {
                MetadataReaderProvider pdbProvider;
                string pdbPath;

                Assert.True(reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), _ => { throw new IOException(); }, out pdbProvider, out pdbPath));
                Assert.Null(pdbPath);
                Assert.Equal(13, pdbProvider.GetMetadataReader().Documents.Count);

                Assert.True(reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), _ => { throw new BadImageFormatException(); }, out pdbProvider, out pdbPath));
                Assert.Null(pdbPath);
                Assert.Equal(13, pdbProvider.GetMetadataReader().Documents.Count);

                Assert.True(reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), _ => { throw new FileNotFoundException(); }, out pdbProvider, out pdbPath));
                Assert.Null(pdbPath);
                Assert.Equal(13, pdbProvider.GetMetadataReader().Documents.Count);
            }
        }