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)); }); }
/// <summary> /// Finds or downloads the ELF module /// </summary> /// <param name="module">module instance</param> /// <param name="flags"></param> /// <returns>module path or null</returns> private string DownloadELF(IModule module, KeyTypeFlags flags) { if ((flags & (KeyTypeFlags.IdentityKey | KeyTypeFlags.SymbolKey)) == 0) { throw new ArgumentException($"Key flag not supported {flags}"); } if (module.BuildId.IsDefaultOrEmpty) { Trace.TraceWarning($"DownloadELF: module {module.FileName} has no build id"); return(null); } SymbolStoreKey fileKey = ELFFileKeyGenerator.GetKeys(flags, module.FileName, module.BuildId.ToArray(), symbolFile: false, module.GetSymbolFileName()).SingleOrDefault(); if (fileKey is null) { Trace.TraceWarning($"DownloadELF: no index generated for module {module.FileName} "); return(null); } // Check if the file is local and the key matches the module string fileName = fileKey.FullPathName; if (File.Exists(fileName)) { using ELFModule elfModule = ELFModule.OpenFile(fileName); if (elfModule is not null) { var generator = new ELFFileKeyGenerator(Tracer.Instance, elfModule, fileName); foreach (SymbolStoreKey key in generator.GetKeys(flags)) { if (fileKey.Equals(key)) { Trace.TraceInformation("DownloadELF: local file match {0}", fileName); return(fileName); } } } } // Now download the module from the symbol server if local file doesn't exists or doesn't have the right key string downloadFilePath = DownloadFile(fileKey); if (!string.IsNullOrEmpty(downloadFilePath)) { Trace.TraceInformation("DownloadELF: downloaded {0}", downloadFilePath); return(downloadFilePath); } return(null); }