コード例 #1
0
        /// <summary>
        /// Returns the ELF module build id or the MachO module uuid
        /// </summary>
        /// <param name="address">module base address</param>
        /// <param name="size">module size</param>
        /// <returns>build id or null</returns>
        internal byte[] GetBuildId(ulong address, ulong size)
        {
            Debug.Assert(size > 0);
            Stream stream = MemoryService.CreateMemoryStream(address, size);

            byte[] buildId = null;
            try
            {
                if (Target.OperatingSystem == OSPlatform.Linux)
                {
                    var elfFile = new ELFFile(new StreamAddressSpace(stream), 0, true);
                    if (elfFile.IsValid())
                    {
                        buildId = elfFile.BuildID;
                    }
                }
                else if (Target.OperatingSystem == OSPlatform.OSX)
                {
                    var machOFile = new MachOFile(new StreamAddressSpace(stream), 0, true);
                    if (machOFile.IsValid())
                    {
                        buildId = machOFile.Uuid;
                    }
                }
            }
            catch (Exception ex) when(ex is InvalidVirtualAddressException || ex is BadInputFormatException || ex is IOException)
            {
                Trace.TraceError($"GetBuildId: {address:X16} exception {ex.Message}");
            }
            return(buildId);
        }
コード例 #2
0
ファイル: MachOUuidIndexer.cs プロジェクト: runt18/symstore
        public string ComputeIndexKey(string path, Stream fileStream)
        {
            try
            {
                string extension = Path.GetExtension(path);
                if (extension != ".dylib" && extension != ".dylib.dwarf")
                {
                    return(null);
                }
                MachOFile machO = new MachOFile(new StreamAddressSpace(fileStream));
                if (!machO.HeaderMagic.IsMagicValid.Check())
                {
                    return(null);
                }

                string        filename = Path.GetFileName(path).ToLowerInvariant();
                StringBuilder key      = new StringBuilder();
                key.Append(filename);
                key.Append("/mach-uuid-");
                //TODO: it would be nice to really check if the file is stripped rather than
                // assuming it is based on the extension
                bool isStripped = extension == ".dylib";
                key.Append(isStripped ? "" : "sym-");
                key.Append(string.Concat(machO.Uuid.Select(b => b.ToString("x2"))).ToLowerInvariant());
                key.Append("/");
                key.Append(filename);
                return(key.ToString());
            }
            catch (InputParsingException)
            {
                return(null);
            }
        }
コード例 #3
0
ファイル: ModuleService.cs プロジェクト: dotnet/diagnostics
        /// <summary>
        /// Returns the ELF module build id or the MachO module uuid
        /// </summary>
        /// <param name="address">module base address</param>
        /// <returns>build id or null</returns>
        internal byte[] GetBuildId(ulong address)
        {
            // This code is called by the image mapping memory service so it needs to use the
            // original or raw memory service to prevent recursion so it can't use the ELFFile
            // or MachOFile instance that is available from the IModule.Services provider.
            Stream stream = RawMemoryService.CreateMemoryStream();

            byte[] buildId = null;
            try
            {
                if (Target.OperatingSystem == OSPlatform.Linux)
                {
                    var elfFile = new ELFFile(new StreamAddressSpace(stream), address, true);
                    if (elfFile.IsValid())
                    {
                        buildId = elfFile.BuildID;
                    }
                }
                else if (Target.OperatingSystem == OSPlatform.OSX)
                {
                    var machOFile = new MachOFile(new StreamAddressSpace(stream), address, true);
                    if (machOFile.IsValid())
                    {
                        buildId = machOFile.Uuid;
                    }
                }
            }
            catch (Exception ex) when(ex is InvalidVirtualAddressException || ex is BadInputFormatException || ex is IOException)
            {
                Trace.TraceError($"GetBuildId: {address:X16} exception {ex.Message}");
            }
            return(buildId);
        }
コード例 #4
0
 private KeyGenerator CreateGenerator(ELFLoadedImage loadedImage)
 {
     try
     {
         if (loadedImage.Image.IsValid())
         {
             return(new ELFFileKeyGenerator(Tracer, loadedImage.Image, loadedImage.Path));
         }
         // TODO - mikem 7/1/17 - need to figure out a better way to determine the file vs loaded layout
         bool layout = loadedImage.Path.StartsWith("/");
         var  reader = new RelativeAddressSpace(_core.DataSource, loadedImage.LoadAddress, _core.DataSource.Length);
         var  peFile = new PEFile(reader, layout);
         if (peFile.IsValid())
         {
             return(new PEFileKeyGenerator(Tracer, peFile, loadedImage.Path));
         }
         // Check if this is a macho module in a ELF 5.0.x MacOS dump
         var machOFile = new MachOFile(reader, 0, true);
         if (machOFile.IsValid())
         {
             return(new MachOFileKeyGenerator(Tracer, machOFile, loadedImage.Path));
         }
         Tracer.Warning("Unknown ELF core image {0:X16} {1}", loadedImage.LoadAddress, loadedImage.Path);
     }
     catch (InvalidVirtualAddressException ex)
     {
         Tracer.Error("{0}: {1:X16} {2}", ex.Message, loadedImage.LoadAddress, loadedImage.Path);
     }
     return(null);
 }
コード例 #5
0
        /// <summary>
        /// Creates a key generator for the runtime module pointed to by the address/size.
        /// </summary>
        /// <param name="memoryService">memory service instance</param>
        /// <param name="config">Target configuration: Windows, Linux or OSX</param>
        /// <param name="moduleFilePath">module path</param>
        /// <param name="address">module base address</param>
        /// <param name="size">module size</param>
        /// <returns>KeyGenerator or null if error</returns>
        public static KeyGenerator GetKeyGenerator(this IMemoryService memoryService, OSPlatform config, string moduleFilePath, ulong address, ulong size)
        {
            Stream       stream    = memoryService.CreateMemoryStream(address, size);
            KeyGenerator generator = null;

            if (config == OSPlatform.Linux)
            {
                var elfFile = new ELFFile(new StreamAddressSpace(stream), 0, true);
                generator = new ELFFileKeyGenerator(Tracer.Instance, elfFile, moduleFilePath);
            }
            else if (config == OSPlatform.OSX)
            {
                var machOFile = new MachOFile(new StreamAddressSpace(stream), 0, true);
                generator = new MachOFileKeyGenerator(Tracer.Instance, machOFile, moduleFilePath);
            }
            else if (config == OSPlatform.Windows)
            {
                var peFile = new PEFile(new StreamAddressSpace(stream), true);
                generator = new PEFileKeyGenerator(Tracer.Instance, peFile, moduleFilePath);
            }
            else
            {
                Trace.TraceError("GetKeyGenerator: unsupported platform {0}", config);
            }
            return(generator);
        }
コード例 #6
0
        /// <summary>
        /// Get the version string from a Linux or MacOS image
        /// </summary>
        /// <param name="address">image base</param>
        /// <param name="size">image size</param>
        /// <returns>version string or null</returns>
        protected string GetVersionString(ulong address, ulong size)
        {
            Stream stream = MemoryService.CreateMemoryStream(address, size);

            try
            {
                if (Target.OperatingSystem == OSPlatform.Linux)
                {
                    var elfFile = new ELFFile(new StreamAddressSpace(stream), 0, true);
                    if (elfFile.IsValid())
                    {
                        foreach (ELFProgramHeader programHeader in elfFile.Segments.Select((segment) => segment.Header))
                        {
                            uint flags = MemoryService.PointerSize == 8 ? programHeader.Flags : programHeader.Flags32;
                            if (programHeader.Type == ELFProgramHeaderType.Load &&
                                (flags & (uint)ELFProgramHeaderAttributes.Writable) != 0)
                            {
                                ulong loadAddress = programHeader.VirtualAddress.Value;
                                long  loadSize    = (long)programHeader.VirtualSize;
                                if (SearchVersionString(address + loadAddress, loadSize, out string productVersion))
                                {
                                    return(productVersion);
                                }
                            }
                        }
                    }
                }
                else if (Target.OperatingSystem == OSPlatform.OSX)
                {
                    var machOFile = new MachOFile(new StreamAddressSpace(stream), 0, true);
                    if (machOFile.IsValid())
                    {
                        foreach (MachSegmentLoadCommand loadCommand in machOFile.Segments.Select((segment) => segment.LoadCommand))
                        {
                            if (loadCommand.Command == LoadCommandType.Segment64 &&
                                (loadCommand.InitProt & VmProtWrite) != 0 &&
                                loadCommand.SegName.ToString() != "__LINKEDIT")
                            {
                                ulong loadAddress = loadCommand.VMAddress;
                                long  loadSize    = (long)loadCommand.VMSize;
                                if (SearchVersionString(address + loadAddress, loadSize, out string productVersion))
                                {
                                    return(productVersion);
                                }
                            }
                        }
                    }
                }
                else
                {
                    Trace.TraceError("GetVersionString: unsupported platform {0}", Target.OperatingSystem);
                }
            }
            catch (Exception ex) when(ex is InvalidVirtualAddressException || ex is BadInputFormatException || ex is IOException)
            {
                Trace.TraceError($"GetVersionString: {address:X16} exception {ex.Message}");
            }
            return(null);
        }
コード例 #7
0
        /// <summary>
        /// Finds or downloads the ELF module and creates a MachOFile instance for it.
        /// </summary>
        /// <param name="module">module instance</param>
        /// <returns>MachO file instance or null</returns>
        internal MachOFile GetMachOFile(IModule module)
        {
            string    downloadFilePath = null;
            MachOFile machoFile        = null;

            if (File.Exists(module.FileName))
            {
                // TODO - Need to verify the build id matches this local file
                downloadFilePath = module.FileName;
            }
            else
            {
                if (SymbolService.IsSymbolStoreEnabled)
                {
                    if (!module.BuildId.IsDefaultOrEmpty)
                    {
                        var key = MachOFileKeyGenerator.GetKeys(KeyTypeFlags.IdentityKey, module.FileName, module.BuildId.ToArray(), symbolFile: false, symbolFileName: null).SingleOrDefault();
                        if (key != null)
                        {
                            // Now download the module from the symbol server
                            downloadFilePath = SymbolService.DownloadFile(key);
                        }
                    }
                }
            }

            if (!string.IsNullOrEmpty(downloadFilePath))
            {
                Trace.TraceInformation("GetMachOFile: downloaded {0}", downloadFilePath);
                Stream stream;
                try
                {
                    stream = File.OpenRead(downloadFilePath);
                }
                catch (Exception ex) when(ex is DirectoryNotFoundException || ex is FileNotFoundException || ex is UnauthorizedAccessException || ex is IOException)
                {
                    Trace.TraceError($"GetMachOFile: OpenRead exception {ex.Message}");
                    return(null);
                }
                try
                {
                    machoFile = new MachOFile(new StreamAddressSpace(stream), position: 0, dataSourceIsVirtualAddressSpace: false);
                    if (!machoFile.IsValid())
                    {
                        return(null);
                    }
                }
                catch (Exception ex) when(ex is InvalidVirtualAddressException || ex is BadInputFormatException || ex is IOException)
                {
                    Trace.TraceError($"GetMachOFile: exception {ex.Message}");
                    return(null);
                }
            }

            return(machoFile);
        }
コード例 #8
0
ファイル: ModuleService.cs プロジェクト: dotnet/diagnostics
 /// <summary>
 /// Get the version string from a Linux or MacOS image
 /// </summary>
 /// <param name="module">module to get version string</param>
 /// <returns>version string or null</returns>
 protected string GetVersionString(IModule module)
 {
     try
     {
         ELFFile elfFile = module.Services.GetService <ELFFile>();
         if (elfFile is not null)
         {
             foreach (ELFProgramHeader programHeader in elfFile.Segments.Select((segment) => segment.Header))
             {
                 uint flags = MemoryService.PointerSize == 8 ? programHeader.Flags : programHeader.Flags32;
                 if (programHeader.Type == ELFProgramHeaderType.Load &&
                     (flags & (uint)ELFProgramHeaderAttributes.Writable) != 0)
                 {
                     ulong loadAddress = programHeader.VirtualAddress.Value;
                     long  loadSize    = (long)programHeader.VirtualSize;
                     if (SearchVersionString(module.ImageBase + loadAddress, loadSize, out string productVersion))
                     {
                         return(productVersion);
                     }
                 }
             }
             Trace.TraceInformation($"GetVersionString: not found in ELF file {module}");
         }
         else
         {
             MachOFile machOFile = module.Services.GetService <MachOFile>();
             if (machOFile is not null)
             {
                 foreach (MachSegmentLoadCommand loadCommand in machOFile.Segments.Select((segment) => segment.LoadCommand))
                 {
                     if (loadCommand.Command == LoadCommandType.Segment64 &&
                         (loadCommand.InitProt & VmProtWrite) != 0 &&
                         loadCommand.SegName.ToString() != "__LINKEDIT")
                     {
                         ulong loadAddress = loadCommand.VMAddress + machOFile.PreferredVMBaseAddress;
                         long  loadSize    = (long)loadCommand.VMSize;
                         if (SearchVersionString(loadAddress, loadSize, out string productVersion))
                         {
                             return(productVersion);
                         }
                     }
                 }
                 Trace.TraceInformation($"GetVersionString: not found in MachO file {module}");
             }
             else
             {
                 Trace.TraceError($"GetVersionString: unsupported module {module} or platform {Target.OperatingSystem}");
             }
         }
     }
     catch (Exception ex) when(ex is InvalidVirtualAddressException || ex is BadInputFormatException || ex is IOException)
     {
         Trace.TraceError($"GetVersionString: {module} exception {ex.Message}");
     }
     return(null);
 }
コード例 #9
0
ファイル: Tests.cs プロジェクト: runt18/symstore
 public void CheckDwarfIndexingInfo()
 {
     //https://dotnet.myget.org/feed/dotnet-core/package/nuget/runtime.osx.10.10-x64.Microsoft.NETCore.Runtime.CoreCLR/1.0.2
     using (FileStream dwarf = File.OpenRead("TestBinaries\\libcoreclr.dylib.dwarf"))
     {
         StreamAddressSpace dataSource = new StreamAddressSpace(dwarf);
         MachOFile          machO      = new MachOFile(dataSource);
         Assert.Equal(Guid.Parse("c988806d-a15d-5e3d-9a26-42cedad97a2f"), new Guid(machO.Uuid));
     }
 }
コード例 #10
0
    public static int Main(string[] args)
    {
        if (args.Length < 2 || string.IsNullOrEmpty(args[0]) || string.IsNullOrEmpty(args[1]))
        {
            throw new ArgumentException("Invalid command line arguments");
        }
        string moduleFileName = args[0];
        string outputFileName = args[1];

        using (FileStream stream = File.OpenRead(moduleFileName))
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                var    elfFile = new ELFFile(new StreamAddressSpace(stream));
                byte[] buildId = elfFile.BuildID;
                if (buildId != null)
                {
                    // First byte is the number of bytes total in the build id
                    string outputText = string.Format("0x{0:x2}, {1}", buildId.Length, ToHexString(buildId));
                    File.WriteAllText(outputFileName, outputText);
                }
                else
                {
                    throw new BadInputFormatException($"{moduleFileName} does not have a build id");
                }
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                var peFile = new PEFile(new StreamAddressSpace(stream));
                // First byte is the number of bytes total in the index
                string outputText = string.Format("0x{0:x2}, {1} {2}", 8, ToHexString(peFile.Timestamp), ToHexString(peFile.SizeOfImage));
                File.WriteAllText(outputFileName, outputText);
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
            {
                var    machoFile = new MachOFile(new StreamAddressSpace(stream));
                byte[] uuid      = machoFile.Uuid;
                if (uuid != null)
                {
                    // First byte is the number of bytes total in the build id
                    string outputText = string.Format("0x{0:x2}, {1}", uuid.Length, ToHexString(uuid));
                    File.WriteAllText(outputFileName, outputText);
                }
                else
                {
                    throw new BadInputFormatException($"{moduleFileName} does not have a uuid");
                }
            }
            else
            {
                throw new PlatformNotSupportedException(RuntimeInformation.OSDescription);
            }
        }
        return(0);
    }
コード例 #11
0
        /// <summary>
        /// Load native symbols and modules (i.e. dac, dbi).
        /// </summary>
        /// <param name="callback">called back for each symbol file loaded</param>
        /// <param name="parameter">callback parameter</param>
        /// <param name="tempDirectory">temp directory unique to this instance of SOS</param>
        /// <param name="moduleFilePath">module path</param>
        /// <param name="address">module base address</param>
        /// <param name="size">module size</param>
        /// <param name="readMemory">read memory callback delegate</param>
        public static void LoadNativeSymbols(SymbolFileCallback callback, IntPtr parameter, string tempDirectory, string moduleFilePath, ulong address, int size, ReadMemoryDelegate readMemory)
        {
            if (IsSymbolStoreEnabled())
            {
                Debug.Assert(s_tracer != null);
                Stream       stream    = new TargetStream(address, size, readMemory);
                KeyTypeFlags flags     = KeyTypeFlags.SymbolKey | KeyTypeFlags.ClrKeys;
                KeyGenerator generator = null;

                if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                {
                    var elfFile = new ELFFile(new StreamAddressSpace(stream), 0, true);
                    generator = new ELFFileKeyGenerator(s_tracer, elfFile, moduleFilePath);
                }
                else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
                {
                    var machOFile = new MachOFile(new StreamAddressSpace(stream), 0, true);
                    generator = new MachOFileKeyGenerator(s_tracer, machOFile, moduleFilePath);
                }
                else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    var peFile = new PEFile(new StreamAddressSpace(stream), true);
                    generator = new PEFileKeyGenerator(s_tracer, peFile, moduleFilePath);
                }
                else
                {
                    return;
                }

                try
                {
                    IEnumerable <SymbolStoreKey> keys = generator.GetKeys(flags);
                    foreach (SymbolStoreKey key in keys)
                    {
                        string moduleFileName = Path.GetFileName(key.FullPathName);
                        s_tracer.Verbose("{0} {1}", key.FullPathName, key.Index);

                        // Don't download the sos binaries that come with the runtime
                        if (moduleFileName != "SOS.NETCore.dll" && !moduleFileName.StartsWith("libsos."))
                        {
                            string downloadFilePath = GetSymbolFile(key, tempDirectory);
                            if (downloadFilePath != null)
                            {
                                s_tracer.Information("{0}: {1}", moduleFileName, downloadFilePath);
                                callback(parameter, moduleFileName, downloadFilePath);
                            }
                        }
                    }
                }
                catch (Exception ex) when(ex is BadInputFormatException || ex is InvalidVirtualAddressException)
                {
                    s_tracer.Error("{0}/{1:X16}: {2}", moduleFilePath, address, ex.Message);
                }
            }
        }
コード例 #12
0
 public void CheckDwarfIndexingInfo()
 {
     // From a local build
     using (Stream dwarf = TestUtilities.OpenCompressedFile("TestBinaries/libclrjit.dylib.dwarf.gz"))
     {
         StreamAddressSpace dataSource = new StreamAddressSpace(dwarf);
         MachOFile          machO      = new MachOFile(dataSource);
         Assert.True(machO.IsValid());
         Assert.Equal(Guid.Parse("0c235eb3-e98e-ef32-b6e6-e6ed18a604a8"), new Guid(machO.Uuid));
     }
 }
コード例 #13
0
 public void CheckIndexingInfo()
 {
     // https://dotnet.myget.org/feed/dotnet-core/package/nuget/runtime.osx.10.12-x64.Microsoft.NETCore.Runtime.CoreCLR/1.1.2
     using (Stream dylib = TestUtilities.OpenCompressedFile("TestBinaries/libcoreclr.dylib.gz"))
     {
         StreamAddressSpace dataSource = new StreamAddressSpace(dylib);
         MachOFile          machO      = new MachOFile(dataSource);
         Assert.True(machO.IsValid());
         Assert.Equal(Guid.Parse("da2b37b5-cdbc-f838-899b-6a782ceca847"), new Guid(machO.Uuid));
     }
 }
コード例 #14
0
        public Module(ITarget target)
        {
            ServiceProvider = new ServiceProvider();
            ServiceProvider.AddServiceFactoryWithNoCaching <PEFile>(() => GetPEInfo());
            ServiceProvider.AddService <IExportSymbols>(this);

            ServiceProvider.AddServiceFactory <PEReader>(() => {
                if (!IndexTimeStamp.HasValue || !IndexFileSize.HasValue)
                {
                    return(null);
                }
                return(Utilities.OpenPEReader(ModuleService.SymbolService.DownloadModuleFile(this)));
            });

            if (target.OperatingSystem == OSPlatform.Linux)
            {
                ServiceProvider.AddServiceFactory <ELFModule>(() => {
                    if (BuildId.IsDefaultOrEmpty)
                    {
                        return(null);
                    }
                    return(ELFModule.OpenFile(ModuleService.SymbolService.DownloadModuleFile(this)));
                });
                ServiceProvider.AddServiceFactory <ELFFile>(() => {
                    Stream stream = ModuleService.MemoryService.CreateMemoryStream();
                    var elfFile   = new ELFFile(new StreamAddressSpace(stream), ImageBase, true);
                    return(elfFile.IsValid() ? elfFile : null);
                });
            }

            if (target.OperatingSystem == OSPlatform.OSX)
            {
                ServiceProvider.AddServiceFactory <MachOModule>(() => {
                    if (BuildId.IsDefaultOrEmpty)
                    {
                        return(null);
                    }
                    return(MachOModule.OpenFile(ModuleService.SymbolService.DownloadModuleFile(this)));
                });
                ServiceProvider.AddServiceFactory <MachOFile>(() => {
                    Stream stream = ModuleService.MemoryService.CreateMemoryStream();
                    var machoFile = new MachOFile(new StreamAddressSpace(stream), ImageBase, true);
                    return(machoFile.IsValid() ? machoFile : null);
                });
            }

            _onChangeEvent = target.Services.GetService <ISymbolService>()?.OnChangeEvent.Register(() => {
                ServiceProvider.RemoveService(typeof(MachOModule));
                ServiceProvider.RemoveService(typeof(ELFModule));
                ServiceProvider.RemoveService(typeof(PEReader));
            });
        }
コード例 #15
0
ファイル: Tests.cs プロジェクト: runt18/symstore
 public void ParseCore()
 {
     using (FileStream core = File.OpenRead("TestBinaries\\core.12985"))
     {
         StreamAddressSpace dataSource = new StreamAddressSpace(core);
         // hard-coding the dylinker position so we don't pay to search for it each time
         // the code is capable of finding it by brute force search even if we don't provide the hint
         MachCore          coreReader = new MachCore(dataSource, 0x00007fff68a59000);
         MachLoadedImage[] images     = coreReader.LoadedImages.Where(i => i.Path.EndsWith("libcoreclr.dylib")).ToArray();
         MachOFile         libCoreclr = images[0].Image;
         Assert.Equal(Guid.Parse("c988806d-a15d-5e3d-9a26-42cedad97a2f"), new Guid(libCoreclr.Uuid));
     }
 }
コード例 #16
0
        public void ContainsASymbolTable()
        {
            Stream           lib   = HelloSwiftAsLibrary(null);
            List <MachOFile> macho = MachO.Read(lib, null).ToList();

            Assert.IsNotNull(macho);
            Assert.AreEqual(1, macho.Count);
            MachOFile file           = macho [0];
            bool      hasSymbolTable = file.load_commands.Exists(lc => lc.cmd == (uint)MachO.LoadCommands.SymTab ||
                                                                 lc.cmd == (uint)MachO.LoadCommands.DySymTab);

            Assert.IsTrue(hasSymbolTable);
        }
コード例 #17
0
 public void ParseCore()
 {
     using (Stream core = TestUtilities.DecompressFile("TestBinaries/core.gz", "TestBinaries/core"))
     {
         StreamAddressSpace dataSource = new StreamAddressSpace(core);
         // hard-coding the dylinker position so we don't pay to search for it each time
         // the code is capable of finding it by brute force search even if we don't provide the hint
         MachCore coreReader = new MachCore(dataSource, 0x000000010750c000);
         Assert.True(coreReader.IsValid());
         MachLoadedImage[] images     = coreReader.LoadedImages.Where(i => i.Path.EndsWith("libcoreclr.dylib")).ToArray();
         MachOFile         libCoreclr = images[0].Image;
         Assert.True(libCoreclr.IsValid());
         Assert.Equal(Guid.Parse("c5660f3e-7352-b138-8141-e9d63b8ab415"), new Guid(libCoreclr.Uuid));
     }
 }
コード例 #18
0
        public void HasOneRealPublicSymbol()
        {
            Stream           lib   = HelloSwiftAsLibrary(null);
            List <MachOFile> macho = MachO.Read(lib, null).ToList();

            Assert.IsNotNull(macho);
            Assert.AreEqual(1, macho.Count);
            MachOFile file = macho [0];
            List <SymTabLoadCommand> symbols = file.load_commands.OfType <SymTabLoadCommand> ().ToList();

            Assert.AreEqual(1, symbols.Count);
            NListEntryType    nlet    = symbols [0].nlist [0].EntryType;
            List <NListEntry> entries = symbols [0].nlist.
                                        Where((nle, i) => nle.IsPublic && nle.EntryType == NListEntryType.InSection).ToList();

            Assert.AreEqual(1, entries.Count);
        }
コード例 #19
0
        /// <summary>
        /// Finds or downloads the ELF module and creates a MachOFile instance for it.
        /// </summary>
        /// <param name="module">module instance</param>
        /// <returns>MachO file instance or null</returns>
        internal MachOFile GetMachOFile(IModule module)
        {
            if (module.BuildId.IsDefaultOrEmpty)
            {
                Trace.TraceWarning($"GetMachOFile: module {module.FileName} has no build id");
                return(null);
            }

            SymbolStoreKey moduleKey = MachOFileKeyGenerator.GetKeys(KeyTypeFlags.IdentityKey, module.FileName, module.BuildId.ToArray(), symbolFile: false, symbolFileName: null).SingleOrDefault();

            if (moduleKey is null)
            {
                Trace.TraceWarning($"GetMachOFile: no index generated for module {module.FileName} ");
                return(null);
            }

            if (File.Exists(module.FileName))
            {
                MachOFile machOFile = OpenMachOFile(module.FileName);
                if (machOFile is not null)
                {
                    var generator = new MachOFileKeyGenerator(Tracer.Instance, machOFile, module.FileName);
                    IEnumerable <SymbolStoreKey> keys = generator.GetKeys(KeyTypeFlags.IdentityKey);
                    foreach (SymbolStoreKey key in keys)
                    {
                        if (moduleKey.Equals(key))
                        {
                            Trace.TraceInformation("GetMachOFile: local file match {0}", module.FileName);
                            return(machOFile);
                        }
                    }
                }
            }

            // Now download the module from the symbol server if local file doesn't exists or doesn't have the right key
            string downloadFilePath = SymbolService.DownloadFile(moduleKey);

            if (!string.IsNullOrEmpty(downloadFilePath))
            {
                Trace.TraceInformation("GetMachOFile: downloaded {0}", downloadFilePath);
                return(OpenMachOFile(downloadFilePath));
            }

            return(null);
        }
コード例 #20
0
 void DisplaySegments(IModule module)
 {
     try
     {
         ELFFile elfFile = module.Services.GetService <ELFFile>();
         if (elfFile is not null)
         {
             foreach (ELFProgramHeader programHeader in elfFile.Segments.Select((segment) => segment.Header))
             {
                 uint   flags       = MemoryService.PointerSize == 8 ? programHeader.Flags : programHeader.Flags32;
                 ulong  loadAddress = programHeader.VirtualAddress;
                 ulong  loadSize    = programHeader.VirtualSize;
                 ulong  fileOffset  = programHeader.FileOffset;
                 string type        = programHeader.Type.ToString();
                 WriteLine($"        Segment: {loadAddress:X16} {loadSize:X16} {fileOffset:X16} {flags:x2} {type}");
             }
         }
         else
         {
             MachOFile machOFile = module.Services.GetService <MachOFile>();
             if (machOFile is not null)
             {
                 WriteLine("    LoadAddress:     {0:X16}", machOFile.LoadAddress);
                 WriteLine("    LoadBias:        {0:X16}", machOFile.PreferredVMBaseAddress);
                 for (int i = 0; i < machOFile.Segments.Length; i++)
                 {
                     MachSegment segment     = machOFile.Segments[i];
                     ulong       loadAddress = segment.LoadCommand.VMAddress;
                     ulong       loadSize    = segment.LoadCommand.VMSize;
                     ulong       fileOffset  = segment.LoadCommand.FileOffset;
                     uint        prot        = segment.LoadCommand.InitProt;
                     string      name        = segment.LoadCommand.SegName.ToString();
                     WriteLine($"        Segment {i}: {loadAddress:X16} {loadSize:X16} {fileOffset:X16} {prot:x2} {name}");
                 }
             }
         }
     }
     catch (Exception ex) when(ex is InvalidVirtualAddressException || ex is BadInputFormatException)
     {
         Trace.TraceError($"Exception displaying module segments: {ex}");
     }
 }
コード例 #21
0
        static void TLFunctionsForStream(Stream stm, PlatformName platform, Dictionary <string, string> functions)
        {
            List <NListEntry> entries = null;
            List <MachOFile>  macho   = MachO.Read(stm, null).ToList();
            MachOFile         file    = macho [0];

            List <SymTabLoadCommand> symbols = file.load_commands.OfType <SymTabLoadCommand> ().ToList();
            NListEntryType           nlet    = symbols [0].nlist [0].EntryType;

            entries = symbols [0].nlist.
                      Where((nle, i) => nle.IsPublic && nle.EntryType == NListEntryType.InSection).ToList();

            bool isOldVersion = IsOldVersion(entries);

            foreach (var entry in entries)
            {
                if (!entry.IsSwiftEntryPoint())
                {
                    continue;
                }
                TLDefinition def = null;
                try {
                    def = Decomposer.Decompose(entry.str, isOldVersion, Offset(entry));
                } catch { }
                if (def != null)
                {
                    // this skips over privatized names
                    var tlf = def as TLFunction;
                    if (tlf != null && tlf.Name != null && tlf.Name.Name.Contains("..."))
                    {
                        continue;
                    }
                    if (tlf?.Name != null)
                    {
                        if (!functions.ContainsKey(tlf.Name.Name))
                        {
                            functions.Add(tlf.Name.Name, tlf.MangledName);
                        }
                    }
                }
            }
        }
コード例 #22
0
        /// <summary>
        /// Opens and returns an MachOFile instance from the local file path
        /// </summary>
        /// <param name="filePath">MachO file to open</param>
        /// <returns>MachOFile instance or null</returns>
        private MachOFile OpenMachOFile(string filePath)
        {
            Stream stream = OpenFile(filePath);

            if (stream is not null)
            {
                try
                {
                    var machoFile = new MachOFile(new StreamAddressSpace(stream), position: 0, dataSourceIsVirtualAddressSpace: false);
                    if (!machoFile.IsValid())
                    {
                        Trace.TraceError($"OpenMachOFile: not a valid file");
                        return(null);
                    }
                    return(machoFile);
                }
                catch (Exception ex) when(ex is InvalidVirtualAddressException || ex is BadInputFormatException || ex is IOException)
                {
                    Trace.TraceError($"OpenMachOFile: exception {ex.Message}");
                }
            }
            return(null);
        }
コード例 #23
0
ファイル: MachOKeyGenerator.cs プロジェクト: nosami/symstore
 public MachOFileKeyGenerator(ITracer tracer, MachOFile machoFile, string path)
     : base(tracer)
 {
     _machoFile = machoFile;
     _path      = path;
 }
コード例 #24
0
        static ModuleInventory FromStreamInto(Stream stm, ModuleInventory inventory,
                                              ErrorHandling errors, string fileName = null)
        {
            Ex.ThrowOnNull(errors, "errors");
            Ex.ThrowOnNull(stm, "stm");
            OffsetStream      osstm   = null;
            List <NListEntry> entries = null;

            try {
                List <MachOFile> macho = MachO.Read(stm, null).ToList();
                MachOFile        file  = macho [0];

                List <SymTabLoadCommand> symbols = file.load_commands.OfType <SymTabLoadCommand> ().ToList();
                NListEntryType           nlet    = symbols [0].nlist [0].EntryType;
                entries = symbols [0].nlist.
                          Where((nle, i) => nle.IsPublic && nle.EntryType == NListEntryType.InSection).ToList();
                inventory.Architecture = file.Architecture;
                osstm = new OffsetStream(stm, file.StartOffset);
            } catch (Exception e) {
                errors.Add(ErrorHelper.CreateError(ReflectorError.kCantHappenBase + 58, e, "Unable to retrieve functions from {0}: {1}",
                                                   fileName ?? "stream", e.Message));
                return(inventory);
            }

            bool isOldVersion = IsOldVersion(entries);

            foreach (var entry in entries)
            {
                if (!entry.IsSwiftEntryPoint())
                {
                    continue;
                }
                TLDefinition def = null;
                try {
                    def = Decomposer.Decompose(entry.str, isOldVersion, Offset(entry));
                } catch (RuntimeException e) {
                    var except = new RuntimeException(e.Code, false, e, $"error decomposing {entry.str}: {e.Message}, skipping");
                    errors.Add(except);
                }
                catch (Exception e) {
                    var except = new RuntimeException(ReflectorError.kDecomposeBase + 0, false, e, $"unexpected error handling {entry.str}: {e.Message}, skipping.");
                    errors.Add(except);
                }
                if (def != null)
                {
                    // this skips over privatized names
                    var tlf = def as TLFunction;
                    if (tlf != null && tlf.Name != null && tlf.Name.Name.Contains("..."))
                    {
                        continue;
                    }
                    try {
                        inventory.Add(def, osstm);
                    } catch (RuntimeException e) {
                        e = new RuntimeException(e.Code, e.Error, $"error dispensing top level definition of type {def.GetType ().Name} decomposed from {entry.str}: {e.Message}");
                        errors.Add(e);
                    }
                }
                else
                {
                    var ex = ErrorHelper.CreateWarning(ReflectorError.kInventoryBase + 18, $"entry {entry.str} uses an unsupported swift feature, skipping.");
                    errors.Add(ex);
                }
            }

            return(inventory);
        }
コード例 #25
0
 public FileEntryPair(MachOFile file, NListEntry entry)
 {
     File  = file;
     Entry = entry;
 }
コード例 #26
0
 public FileSymbolPair(MachOFile file, string symbol)
 {
     File   = file;
     Symbol = symbol;
 }
コード例 #27
0
 public static bool AllFiles(MachOFile file)
 {
     return(true);
 }
コード例 #28
0
        /// <summary>
        /// Load native symbols and modules (i.e. DAC, DBI).
        /// </summary>
        /// <param name="callback">called back for each symbol file loaded</param>
        /// <param name="parameter">callback parameter</param>
        /// <param name="config">Target configuration: Windows, Linux or OSX</param>
        /// <param name="moduleFilePath">module path</param>
        /// <param name="address">module base address</param>
        /// <param name="size">module size</param>
        /// <param name="readMemory">read memory callback delegate</param>
        private void LoadNativeSymbols(
            IntPtr self,
            SymbolFileCallback callback,
            IntPtr parameter,
            RuntimeConfiguration config,
            string moduleFilePath,
            ulong address,
            uint size)
        {
            if (_symbolService.IsSymbolStoreEnabled)
            {
                try
                {
                    Stream       stream    = MemoryService.CreateMemoryStream(address, size);
                    KeyGenerator generator = null;
                    if (config == RuntimeConfiguration.UnixCore)
                    {
                        var elfFile = new ELFFile(new StreamAddressSpace(stream), 0, true);
                        generator = new ELFFileKeyGenerator(Tracer.Instance, elfFile, moduleFilePath);
                    }
                    else if (config == RuntimeConfiguration.OSXCore)
                    {
                        var machOFile = new MachOFile(new StreamAddressSpace(stream), 0, true);
                        generator = new MachOFileKeyGenerator(Tracer.Instance, machOFile, moduleFilePath);
                    }
                    else if (config == RuntimeConfiguration.WindowsCore || config == RuntimeConfiguration.WindowsDesktop)
                    {
                        var peFile = new PEFile(new StreamAddressSpace(stream), true);
                        generator = new PEFileKeyGenerator(Tracer.Instance, peFile, moduleFilePath);
                    }
                    else
                    {
                        Trace.TraceError("LoadNativeSymbols: unsupported config {0}", config);
                    }
                    if (generator != null)
                    {
                        IEnumerable <SymbolStoreKey> keys = generator.GetKeys(KeyTypeFlags.SymbolKey | KeyTypeFlags.DacDbiKeys);
                        foreach (SymbolStoreKey key in keys)
                        {
                            string moduleFileName = Path.GetFileName(key.FullPathName);
                            Trace.TraceInformation("{0} {1}", key.FullPathName, key.Index);

                            string downloadFilePath = _symbolService.DownloadFile(key);
                            if (downloadFilePath != null)
                            {
                                Trace.TraceInformation("{0}: {1}", moduleFileName, downloadFilePath);
                                callback(parameter, moduleFileName, downloadFilePath);
                            }
                        }
                    }
                }
                catch (Exception ex) when
                    (ex is DiagnosticsException ||
                    ex is BadInputFormatException ||
                    ex is InvalidVirtualAddressException ||
                    ex is ArgumentOutOfRangeException ||
                    ex is IndexOutOfRangeException ||
                    ex is TaskCanceledException)
                {
                    Trace.TraceError("{0} address {1:X16}: {2}", moduleFilePath, address, ex.Message);
                }
            }
        }
コード例 #29
0
        /// <summary>
        /// Load native symbols and modules (i.e. dac, dbi).
        /// </summary>
        /// <param name="callback">called back for each symbol file loaded</param>
        /// <param name="parameter">callback parameter</param>
        /// <param name="moduleDirectory">module path</param>
        /// <param name="moduleFileName">module file name</param>
        /// <param name="address">module base address</param>
        /// <param name="size">module size</param>
        /// <param name="readMemory">read memory callback delegate</param>
        internal static void LoadNativeSymbols(SymbolFileCallback callback, IntPtr parameter, string tempDirectory, string moduleDirectory, string moduleFileName,
                                               ulong address, int size, ReadMemoryDelegate readMemory)
        {
            if (s_symbolStore != null)
            {
                Debug.Assert(s_tracer != null);
                string       path      = Path.Combine(moduleDirectory, moduleFileName);
                Stream       stream    = new TargetStream(address, size, readMemory);
                KeyTypeFlags flags     = KeyTypeFlags.SymbolKey | KeyTypeFlags.ClrKeys;
                KeyGenerator generator = null;

                if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                {
                    var elfFile = new ELFFile(new StreamAddressSpace(stream), 0, true);
                    generator = new ELFFileKeyGenerator(s_tracer, elfFile, path);
                }
                else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
                {
                    var machOFile = new MachOFile(new StreamAddressSpace(stream), 0, true);
                    generator = new MachOFileKeyGenerator(s_tracer, machOFile, path);
                }
                else
                {
                    return;
                }

                try
                {
                    IEnumerable <SymbolStoreKey> keys = generator.GetKeys(flags);
                    foreach (SymbolStoreKey key in keys)
                    {
                        string symbolFileName = Path.GetFileName(key.FullPathName);
                        s_tracer.Verbose("{0} {1}", key.FullPathName, key.Index);

                        // Don't download the sos binaries that come with the runtime
                        if (symbolFileName != "SOS.NETCore.dll" && !symbolFileName.StartsWith("libsos."))
                        {
                            using (SymbolStoreFile file = GetSymbolStoreFile(key))
                            {
                                if (file != null)
                                {
                                    try
                                    {
                                        string downloadFileName = file.FileName;

                                        // If the downloaded doesn't already exists on disk in the cache, then write it to a temporary location.
                                        if (!File.Exists(downloadFileName))
                                        {
                                            downloadFileName = Path.Combine(tempDirectory, symbolFileName);

                                            using (Stream destinationStream = File.OpenWrite(downloadFileName)) {
                                                file.Stream.CopyTo(destinationStream);
                                            }
                                            s_tracer.WriteLine("Downloaded symbol file {0}", key.FullPathName);
                                        }
                                        s_tracer.Information("{0}: {1}", symbolFileName, downloadFileName);
                                        callback(parameter, symbolFileName, downloadFileName);
                                    }
                                    catch (Exception ex) when(ex is UnauthorizedAccessException || ex is DirectoryNotFoundException)
                                    {
                                        s_tracer.Error("{0}", ex.Message);
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception ex) when(ex is BadInputFormatException || ex is InvalidVirtualAddressException)
                {
                    s_tracer.Error("Exception: {0}/{1}: {2:X16}", moduleDirectory, moduleFileName, address);
                }
            }
        }
コード例 #30
0
ファイル: Program.cs プロジェクト: mikem8361/symstore
        internal void VerifyCoreDump()
        {
            foreach (string inputFile in GetInputFiles())
            {
                Console.WriteLine($"{inputFile}");

                using Stream inputStream = File.Open(inputFile, FileMode.Open, FileAccess.Read, FileShare.Read);
                var dataSource = new StreamAddressSpace(inputStream);
                var core       = new ELFCoreFile(dataSource);

                if (Tracer.Enabled)
                {
                    foreach (ELFProgramSegment segment in core.Segments)
                    {
                        Tracer.Information("{0:X16}-{1:X16} {2:X8} {3:X8} {4}",
                                           segment.Header.VirtualAddress.Value,
                                           segment.Header.VirtualAddress + segment.Header.VirtualSize,
                                           segment.Header.FileOffset.Value,
                                           (ulong)segment.Header.FileSize,
                                           segment.Header.Type);
                    }
                }

                foreach (ELFLoadedImage image in core.LoadedImages)
                {
                    Console.WriteLine("{0:X16} {1}", image.LoadAddress, image.Path);
                    Exception elfException   = null;
                    Exception machoException = null;
                    Exception peException    = null;
                    try
                    {
                        ELFFile elfFile = image.Image;
                        if (elfFile.IsValid())
                        {
                            try
                            {
                                byte[] buildid = elfFile.BuildID;
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine("                 ELF file invalid build id - {0}", ex.Message);
                            }
                            foreach (ELFProgramSegment segment in elfFile.Segments)
                            {
                                Tracer.Verbose("                 {0:X16}-{1:X16} file off {2:X8} file size {3:X8} {4}",
                                               segment.Header.VirtualAddress.Value,
                                               segment.Header.VirtualAddress + segment.Header.VirtualSize,
                                               segment.Header.FileOffset.Value,
                                               (ulong)segment.Header.FileSize,
                                               segment.Header.Type);

                                if (segment.Header.Type == ELFProgramHeaderType.Note ||
                                    segment.Header.Type == ELFProgramHeaderType.Dynamic ||
                                    segment.Header.Type == ELFProgramHeaderType.GnuEHFrame)
                                {
                                    try
                                    {
                                        byte[] data = segment.Contents.Read(0, (uint)segment.Header.VirtualSize);
                                    }
                                    catch (Exception ex)
                                    {
                                        Console.WriteLine("                 ELF file segment {0} virt addr {1:X16} virt size {2:X8} INVALID - {3}",
                                                          segment.Header.Type, segment.Header.VirtualAddress, segment.Header.VirtualSize, ex.Message);
                                    }
                                }
                            }

                            // The ELF module was valid try next module
                            continue;
                        }
                    }
                    catch (Exception ex)
                    {
                        elfException = ex;
                    }

                    IAddressSpace addressSpace = new RelativeAddressSpace(core.DataSource, image.LoadAddress, core.DataSource.Length);
                    try
                    {
                        var machoFile = new MachOFile(addressSpace);
                        if (machoFile.IsValid())
                        {
                            try
                            {
                                byte[] uuid = machoFile.Uuid;
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine("                 MachO file invalid uuid - {0}", ex.Message);
                            }
                            foreach (MachSegment segment in machoFile.Segments)
                            {
                                Tracer.Verbose("                 {0:X16}-{1:X16} offset {2:X16} size {3:X16} {4} {5}",
                                               (ulong)segment.LoadCommand.VMAddress,
                                               segment.LoadCommand.VMAddress + segment.LoadCommand.VMSize,
                                               (ulong)segment.LoadCommand.FileOffset,
                                               (ulong)segment.LoadCommand.FileSize,
                                               segment.LoadCommand.Command,
                                               segment.LoadCommand.SegName);

                                foreach (MachSection section in segment.Sections)
                                {
                                    Tracer.Verbose("                         addr {0:X16} size {1:X16} offset {2:X8} {3}",
                                                   (ulong)section.Address,
                                                   (ulong)section.Size,
                                                   section.Offset,
                                                   section.SectionName);
                                }
                            }

                            // The MachO module was valid try next module
                            continue;
                        }
                    }
                    catch (Exception ex)
                    {
                        machoException = ex;
                    }

                    try
                    {
                        var peFile = new PEFile(addressSpace, true);
                        if (peFile.IsValid())
                        {
                            // The PE module was valid try next module
                            continue;
                        }
                    }
                    catch (Exception ex)
                    {
                        peException = ex;
                    }

                    Console.WriteLine("{0:X16} invalid image - {1}", image.LoadAddress, image.Path);
                    if (elfException != null)
                    {
                        Tracer.Verbose("ELF {0}", elfException.Message);
                    }
                    if (machoException != null)
                    {
                        Tracer.Verbose("MachO {0}", machoException.Message);
                    }
                    if (peException != null)
                    {
                        Tracer.Verbose("PE {0}", peException.Message);
                    }
                }

                ulong segmentsTotal = core.Segments.Max(s => s.Header.FileOffset + s.Header.FileSize);
                if (segmentsTotal > dataSource.Length)
                {
                    Console.WriteLine($"ERROR: Core file not complete: file size 0x{dataSource.Length:X8} segments total 0x{segmentsTotal:X8}");
                }
            }
        }
コード例 #31
0
 // return the ids found in a macho file
 List<Guid> GetUuids(MachOFile file)
 {
     var result = new List<Guid> ();
     foreach (var cmd in file.load_commands) {
         if (cmd is UuidCommand) {
             var uuidCmd = cmd as UuidCommand;
             result.Add (new Guid (uuidCmd.uuid));
         }
     }
     return result;
 }