Exemple #1
0
        public void CheckIndexingInfo()
        {
            using (Stream libcoreclr = TestUtilities.OpenCompressedFile("TestBinaries/libcoreclr.so.gz"))
            {
                StreamAddressSpace dataSource = new StreamAddressSpace(libcoreclr);
                ELFFile            elf        = new ELFFile(dataSource);
                Assert.True(elf.IsValid());
                Assert.True(elf.Header.Type == ELFHeaderType.Shared);
                string buildId = TestUtilities.ToHexString(elf.BuildID);

                //this is the build id for libcoreclr.so from package:
                // https://dotnet.myget.org/feed/dotnet-core/package/nuget/runtime.ubuntu.14.04-x64.Microsoft.NETCore.Runtime.CoreCLR/2.0.0-preview3-25428-01
                Assert.Equal("ef8f58a0b402d11c68f78342ef4fcc7d23798d4c", buildId);
            }

            // 32 bit arm ELF binary
            using (Stream apphost = TestUtilities.OpenCompressedFile("TestBinaries/apphost.gz"))
            {
                StreamAddressSpace dataSource = new StreamAddressSpace(apphost);
                ELFFile            elf        = new ELFFile(dataSource);
                Assert.True(elf.IsValid());
                Assert.True(elf.Header.Type == ELFHeaderType.Executable);
                string buildId = TestUtilities.ToHexString(elf.BuildID);

                //this is the build id for apphost from package:
                // https://dotnet.myget.org/F/dotnet-core/symbols/runtime.linux-arm.Microsoft.NETCore.DotNetAppHost/2.1.0-preview2-25512-03
                Assert.Equal("316d55471a8d5ebd6f2cb0631f0020518ab13dc0", buildId);
            }
        }
        /// <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);
        }
Exemple #3
0
        /// <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);
        }
Exemple #4
0
        public string GetSymbolFileName()
        {
            if (InitializeValue(Flags.InitializeSymbolFileName))
            {
                if (Target.OperatingSystem == OSPlatform.Linux)
                {
                    try
                    {
                        Stream stream  = ModuleService.RawMemoryService.CreateMemoryStream();
                        var    elfFile = new ELFFile(new StreamAddressSpace(stream), ImageBase, true);
                        if (elfFile.IsValid())
                        {
                            ELFSection section = elfFile.FindSectionByName(".gnu_debuglink");
                            if (section != null)
                            {
                                _symbolFileName = section.Contents.Read <string>(0);
                            }
                        }
                    }
                    catch (Exception ex) when
                        (ex is InvalidVirtualAddressException ||
                        ex is ArgumentOutOfRangeException ||
                        ex is IndexOutOfRangeException ||
                        ex is BadInputFormatException)

                    {
                        Trace.TraceWarning("ELF .gnu_debuglink section in {0}: {1}", this, ex.Message);
                    }
                }
            }
            return(_symbolFileName);
        }
        /// <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);
        }
        /// <summary>
        /// Finds or downloads the ELF module and creates a ELFFile instance for it.
        /// </summary>
        /// <param name="module">module instance</param>
        /// <returns>ELFFile instance or null</returns>
        internal ELFFile GetELFFile(IModule module)
        {
            string  downloadFilePath = null;
            ELFFile elfFile          = 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 = ELFFileKeyGenerator.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("GetELFFile: 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($"GetELFFile: OpenRead exception {ex.Message}");
                    return(null);
                }
                try
                {
                    elfFile = new ELFFile(new StreamAddressSpace(stream), position: 0, isDataSourceVirtualAddressSpace: false);
                    if (!elfFile.IsValid())
                    {
                        return(null);
                    }
                }
                catch (Exception ex) when(ex is InvalidVirtualAddressException || ex is BadInputFormatException || ex is IOException)
                {
                    Trace.TraceError($"GetELFFile: exception {ex.Message}");
                    return(null);
                }
            }

            return(elfFile);
        }
Exemple #7
0
 public void CheckCustomNamedBuildIdSection()
 {
     using (Stream stream = File.OpenRead("TestBinaries/renamed_build_id_section"))
     {
         StreamAddressSpace dataSource = new StreamAddressSpace(stream);
         ELFFile            elf        = new ELFFile(dataSource);
         Assert.True(elf.IsValid());
         Assert.True(elf.Header.Type == ELFHeaderType.Shared);
         string buildId = TestUtilities.ToHexString(elf.BuildID);
         Assert.Equal("1bd6a199dcb6f234558d9439cfcbba2727f1e1d9", buildId);
     }
 }
Exemple #8
0
 public void CheckFreeBSDIndexingInfo()
 {
     using (Stream stream = File.OpenRead("TestBinaries/ilasm.dbg"))
     {
         StreamAddressSpace dataSource = new StreamAddressSpace(stream);
         ELFFile            elf        = new ELFFile(dataSource);
         Assert.True(elf.IsValid());
         Assert.True(elf.Header.Type == ELFHeaderType.Executable);
         string buildId = TestUtilities.ToHexString(elf.BuildID);
         Assert.Equal("4a91e41002a1307ef4097419d7875df001969daa", buildId);
     }
 }
Exemple #9
0
 public void CheckDbgIndexingInfo()
 {
     using (Stream stream = TestUtilities.OpenCompressedFile("TestBinaries/libcoreclrtraceptprovider.so.dbg.gz"))
     {
         StreamAddressSpace dataSource = new StreamAddressSpace(stream);
         ELFFile            elf        = new ELFFile(dataSource);
         Assert.True(elf.IsValid());
         Assert.True(elf.Header.Type == ELFHeaderType.Shared);
         string buildId = TestUtilities.ToHexString(elf.BuildID);
         Assert.Equal("ce4ce0558d878a05754dff246ccea2a70a1db3a8", buildId);
     }
 }
Exemple #10
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));
            });
        }
Exemple #11
0
 void DisplaySegments(ulong address)
 {
     try
     {
         if (Target.OperatingSystem == OSPlatform.Linux)
         {
             Stream stream  = MemoryService.CreateMemoryStream();
             var    elfFile = new ELFFile(new StreamAddressSpace(stream), address, true);
             if (elfFile.IsValid())
             {
                 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 if (Target.OperatingSystem == OSPlatform.OSX)
         {
             Stream    stream    = MemoryService.CreateMemoryStream();
             MachOFile machOFile = new(new StreamAddressSpace(stream), address, true);
             if (machOFile.IsValid())
             {
                 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}");
     }
 }
Exemple #12
0
        /// <summary>
        /// Opens and returns an ELFFile instance from the local file path
        /// </summary>
        /// <param name="filePath">ELF file to open</param>
        /// <returns>ELFFile instance or null</returns>
        private ELFFile OpenELFFile(string filePath)
        {
            Stream stream = OpenFile(filePath);

            if (stream is not null)
            {
                try
                {
                    ELFFile elfFile = new ELFFile(new StreamAddressSpace(stream), position: 0, isDataSourceVirtualAddressSpace: false);
                    if (!elfFile.IsValid())
                    {
                        Trace.TraceError($"OpenELFFile: not a valid file");
                        return(null);
                    }
                    return(elfFile);
                }
                catch (Exception ex) when(ex is InvalidVirtualAddressException || ex is BadInputFormatException || ex is IOException)
                {
                    Trace.TraceError($"OpenELFFile: exception {ex.Message}");
                }
            }
            return(null);
        }
Exemple #13
0
        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}");
                }
            }
        }
 public override bool IsValid()
 {
     return(_elfFile.IsValid() &&
            (_elfFile.Header.Type == ELFHeaderType.Executable || _elfFile.Header.Type == ELFHeaderType.Shared));
 }