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); }
/// <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); }
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); }
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); } }
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); } }
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); } }
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)); }); }
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}"); } }
/// <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); }
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)); }