/// <summary> /// Finds or downloads the MachO module. /// </summary> /// <param name="module">module instance</param> /// <param name="flags"></param> /// <returns>module path or null</returns> private string DownloadMachO(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($"DownloadMachO: module {module.FileName} has no build id"); return(null); } SymbolStoreKey fileKey = MachOFileKeyGenerator.GetKeys(flags, module.FileName, module.BuildId.ToArray(), symbolFile: false, module.GetSymbolFileName()).SingleOrDefault(); if (fileKey is null) { Trace.TraceWarning($"DownloadMachO: 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 MachOModule machOModule = MachOModule.OpenFile(fileName); if (machOModule is not null) { var generator = new MachOFileKeyGenerator(Tracer.Instance, machOModule, fileName); IEnumerable <SymbolStoreKey> keys = generator.GetKeys(flags); foreach (SymbolStoreKey key in keys) { if (fileKey.Equals(key)) { Trace.TraceInformation("DownloadMachO: 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("DownloadMachO: downloaded {0}", downloadFilePath); return(downloadFilePath); } return(null); }
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> /// 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> public static MachOModule OpenFile(string filePath) { Stream stream = Utilities.TryOpenFile(filePath); if (stream is not null) { try { var machoModule = new MachOModule(stream); if (!machoModule.IsValid()) { Trace.TraceError($"OpenMachOFile: not a valid file"); return(null); } return(machoModule); } catch (Exception ex) when(ex is InvalidVirtualAddressException || ex is BadInputFormatException || ex is IOException) { Trace.TraceError($"OpenMachOFile: exception {ex.Message}"); } } return(null); }