/// <summary> /// Finds or downloads the module and creates a PEReader for it. /// </summary> /// <param name="module">module instance</param> /// <returns>reader or null</returns> internal PEReader GetPEReader(IModule module) { if (!module.IndexTimeStamp.HasValue || !module.IndexFileSize.HasValue) { Trace.TraceWarning($"GetPEReader: module {module.FileName} has no index timestamp/filesize"); return(null); } SymbolStoreKey moduleKey = PEFileKeyGenerator.GetKey(Path.GetFileName(module.FileName), module.IndexTimeStamp.Value, module.IndexFileSize.Value); if (moduleKey is null) { Trace.TraceWarning($"GetPEReader: no index generated for module {module.FileName} "); return(null); } if (File.Exists(module.FileName)) { Stream stream = OpenFile(module.FileName); if (stream is not null) { var peFile = new PEFile(new StreamAddressSpace(stream), false); var generator = new PEFileKeyGenerator(Tracer.Instance, peFile, module.FileName); IEnumerable <SymbolStoreKey> keys = generator.GetKeys(KeyTypeFlags.IdentityKey); foreach (SymbolStoreKey key in keys) { if (moduleKey.Equals(key)) { Trace.TraceInformation("GetPEReader: local file match {0}", module.FileName); return(OpenPEReader(module.FileName)); } } } } // 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("GetPEReader: downloaded {0}", downloadFilePath); return(OpenPEReader(downloadFilePath)); } return(null); }
/// <summary> /// Finds or downloads the PE module /// </summary> /// <param name="module">module instance</param> /// <param name="flags"></param> /// <returns>module path or null</returns> private string DownloadPE(IModule module, KeyTypeFlags flags) { SymbolStoreKey fileKey = null; string fileName = null; if ((flags & KeyTypeFlags.IdentityKey) != 0) { if (!module.IndexTimeStamp.HasValue || !module.IndexFileSize.HasValue) { return(null); } fileName = module.FileName; fileKey = PEFileKeyGenerator.GetKey(Path.GetFileName(fileName), module.IndexTimeStamp.Value, module.IndexFileSize.Value); if (fileKey is null) { Trace.TraceWarning($"DownLoadPE: no key generated for module {fileName} "); return(null); } } else if ((flags & KeyTypeFlags.SymbolKey) != 0) { IEnumerable <PdbFileInfo> pdbInfos = module.GetPdbFileInfos(); if (!pdbInfos.Any()) { return(null); } foreach (PdbFileInfo pdbInfo in pdbInfos) { if (pdbInfo.IsPortable) { fileKey = PortablePDBFileKeyGenerator.GetKey(pdbInfo.Path, pdbInfo.Guid); if (fileKey is not null) { fileName = pdbInfo.Path; break; } } } if (fileKey is null) { foreach (PdbFileInfo pdbInfo in pdbInfos) { if (!pdbInfo.IsPortable) { fileKey = PDBFileKeyGenerator.GetKey(pdbInfo.Path, pdbInfo.Guid, pdbInfo.Revision); if (fileKey is not null) { fileName = pdbInfo.Path; break; } } } } if (fileKey is null) { Trace.TraceWarning($"DownLoadPE: no key generated for module PDB {module.FileName} "); return(null); } } else { throw new ArgumentException($"Key flag not supported {flags}"); } // Check if the file is local and the key matches the module if (File.Exists(fileName)) { using Stream stream = Utilities.TryOpenFile(fileName); if (stream is not null) { var peFile = new PEFile(new StreamAddressSpace(stream), false); var generator = new PEFileKeyGenerator(Tracer.Instance, peFile, fileName); foreach (SymbolStoreKey key in generator.GetKeys(flags)) { if (fileKey.Equals(key)) { Trace.TraceInformation($"DownloadPE: local file match {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("DownloadPE: downloaded {0}", downloadFilePath); return(downloadFilePath); } return(null); }