private static void Process(string path) { try { if (string.IsNullOrEmpty(path)) { Console.Error.WriteLine("ETL file location not provided..."); return; } using (ITraceProcessor trace = TraceProcessor.Create(path)) { IPendingResult <IProcessDataSource> pendingProcessData = trace.UseProcesses(); trace.Process(); IProcessDataSource processData = pendingProcessData.Result; foreach (IProcess process in processData.Processes) { log.Info(process.CommandLine); } } } catch (Exception ex) { Console.WriteLine($"An error occured while processing. {ex}"); throw ex; } }
// Get a dictionary of Chrome process paths, indexed by the IProcess object // which serves as a unique identifier. Don't return a Dictionary keyed by // PID because that will lose records whenever there is PID reuse, which is // often. static Dictionary <IProcess, string> GetChromePaths(IProcessDataSource processData) { var chromePaths = new Dictionary <IProcess, string>(); foreach (var process in processData.Processes) { if (process.ImageName != "chrome.exe") { continue; } // Extract the exePath from the command line. It is also possible to // grab it from the process.Images.Path attribute but that sometimes // gives weird results, is not clearly better, and makes comparing // with the Python script more difficult. // The exePath may or may not be quoted, and may or not have the .exe // suffix but if we strip quotes or split on spaces it works. string commandLine = process.CommandLine ?? "<Unknown>"; string exePath; if (commandLine.StartsWith("\"")) { exePath = commandLine.Substring(1, commandLine.IndexOf('\"', 1) - 1); } else { exePath = commandLine.Split(' ')[0]; } chromePaths[process] = exePath; } return(chromePaths); }
private static int Main(string[] args) { if (args.Length != 1) { Console.Error.WriteLine("Usage CheckForAppCrash <trace.etl>"); return(-1); } string tracePath = args[0]; using (ITraceProcessor trace = TraceProcessor.Create(tracePath)) { IPendingResult <IProcessDataSource> pendingProcesses = trace.UseProcesses(); trace.Process(); IProcessDataSource processData = pendingProcesses.Result; foreach (IProcess process in processData.Processes) { if (string.Equals("werfault.exe", process.ImageName, StringComparison.OrdinalIgnoreCase)) { return(1); } } } return(0); }
static void Run(string tracePath) { using (ITraceProcessor trace = TraceProcessor.Create(tracePath)) { IPendingResult <IProcessDataSource> pendingProcessData = trace.UseProcesses(); trace.Process(); IProcessDataSource processData = pendingProcessData.Result; Console.WriteLine(processData.Processes.Count); } }
private void GatherProcessData(IProcessDataSource processDataSource) { foreach (IProcess process in processDataSource.Processes) { Process ownProcess = new Process(process.Id, process.ImageName); Processes.Add(ownProcess); foreach (IImage image in process.Images) { if (!Images.ContainsKey(ownProcess)) { Images.Add(ownProcess, new List <Image>()); } Images[ownProcess].Add(new Image(image.FileName)); } } }
static void Main(string[] args) { if (args.Length != 1) { Console.Error.WriteLine("Usage: <trace.etl>"); return; } using (ITraceProcessor trace = TraceProcessor.Create(args[0])) { IPendingResult <IProcessDataSource> pendingProcessData = trace.UseProcesses(); trace.Process(); IProcessDataSource processData = pendingProcessData.Result; foreach (IProcess process in processData.Processes) { Console.WriteLine(process.CommandLine); } } }
static void Main(string[] args) { if (args.Length != 1) { Console.Error.WriteLine("Usage: ListImages.exe <trace.etl>"); return; } string tracePath = args[0]; using (ITraceProcessor trace = TraceProcessor.Create(tracePath)) { IPendingResult <IProcessDataSource> pendingProcessData = trace.UseProcesses(); trace.Process(); IProcessDataSource processData = pendingProcessData.Result; foreach (IProcess process in processData.Processes) { foreach (IImage image in process.Images) { DataSize ImageSize = image.Size; long TimeDataStamp = image.Timestamp; string OrigFileName = image.OriginalFileName; string FileDescription = image.FileDescription; string FileVersion = image.FileVersion; Version BinFileVersion = image.FileVersionNumber; CultureInfo VerLanguage = image.Locale; string ProductName = image.ProductName; string CompanyName = image.CompanyName; string ProductVersion = image.ProductVersion; string FileId = image.CompatibilityFileId; string ProgramId = image.CompatibilityProgramId; } } } }
// Get a list of Chrome processes. Most of the logic is from getting a // a full exe path name. Don't return a Dictionary keyed by PID because // that will lose records whenever there is PID reuse, which is often. static List <ProcessSummary> GetProcessSummaries(IProcessDataSource processData) { var processSummaries = new List <ProcessSummary>(); foreach (var process in processData.Processes) { string imageName = process.ImageName; if (imageName != "chrome.exe") { continue; } uint pid = process.Id; uint parentPid = process.ParentId; // Extract the exePath from the command line. It is also possible to // grab it from the process.Images.Path attribute but that sometimes // gives weird results, is not clearly better, and makes comparing // with the Python script more difficult. // The exePath may or may not be quoted, and may or not have the .exe // suffix but if we strip quotes or split on spaces it works. string commandLine = process.CommandLine != null ? process.CommandLine : "<Unknown>"; string exe_path; if (commandLine.StartsWith("\"")) { exe_path = commandLine.Substring(1, commandLine.IndexOf('\"', 1) - 1); } else { exe_path = commandLine.Split(' ')[0]; } processSummaries.Add(new ProcessSummary(imageName, exe_path, commandLine, pid, parentPid)); } return(processSummaries); }
/// <summary> /// Отправляет данные /// </summary> /// <param name="worker">Отправитель</param> /// <param name="source"></param> /// <param name="settings"></param> private async void Process(IProcessPackageWorker worker, IProcessDataSource source, IExchangeSettings settings) { do { if (!settings.SilentCancel) { _cancellationToken.ThrowIfCancellationRequested(); } worker.GetProcessPackage(source, settings); var lastDateUpdated = DateTime.Now; if (!worker.IsBufferEmpty) { var tasks = new List <Task>(); for (var i = 0; i < settings.CountThreads; i++) { tasks.Add(ProcessAction(worker, source)); } while (tasks.Count > 0) { var finishedTask = await Task.WhenAny(tasks); tasks.Remove(finishedTask); } } else { var timeOut = (int)(DateTime.Now - lastDateUpdated).TotalMilliseconds; if (timeOut < settings.Timeout) { Thread.Sleep(settings.Timeout - timeOut); } } } while (!settings.StopServiceAfterFirstRun); }
static Dictionary <IProcess, Counters> FindInterestingProcesses(IProcessDataSource processData) { var countersByProcess = new Dictionary <IProcess, Counters>(); foreach (var process in processData.Processes) { string description = ""; // We are interested in all Chrome processes. if (process.ImageName == "chrome.exe") { // Find the space-terminated word after 'type='. // Mark the first .* as lazy/ungreedy/reluctant so that if // there are multiple --type options (such as with the V8 // Proxy Resolver utility process) the first one will win. // Or, at least, that's what the comments in the Python // version of this said. var r = new Regex(@".*? --type=(?<type>[^ ]*) .*"); // Find the utility sub-type, if present. var r_sub = new Regex(@".*? --utility-sub-type=(?<subtype>[^ ]*) .*"); string type; var match = r.Match(process.CommandLine); if (match.Success) { type = match.Groups["type"].ToString(); // Shorten the tag for better formatting if (type == "crashpad-handler") { type = "crashpad"; } if (type == "renderer" && process.CommandLine.Contains(" --extension-process ")) { // Extension processes are renderers with // --extension-process on the command line. type = "extension"; } var match_sub = r_sub.Match(process.CommandLine); if (match_sub.Success) { // Split utility-process sub-types on period // boundaries and take the last component. This // changes video_capture.mojom.VideoCaptureService // into just VideoCaptureService. char[] separator = { '.' }; var parts = match_sub.Groups["subtype"].ToString() .Split(separator); type = parts[parts.Length - 1]; } } else { type = "browser"; } description = "chrome - " + type; } else if (process.ImageName == "svchost.exe") { if (process.CommandLine.Contains("-k Camera") || process.CommandLine.Contains("-s FrameServer")) { description = "svchost - FrameServer"; } } else if (process.ImageName == "dwm.exe" || process.ImageName == "audiodg.exe" || process.ImageName == "System") { description = process.ImageName; } if (description.Length > 0) { countersByProcess[process] = new Counters(description); } } return(countersByProcess); }
/// <summary> /// Получает задачу отправки /// </summary> /// <param name="worker">Отправитель</param> /// <returns>Задача отправки</returns> private async Task ProcessAction(IProcessPackageWorker worker, IProcessDataSource source) { await Task.Run(() => worker.Process(source), _cancellationToken); }
static int Main(string[] args) { if (args.Length != 1) { Console.Error.WriteLine("Usage: PotentialDelayLoads.exe <trace.etl>"); return(1); } string tracePath = args[0]; var settings = new TraceProcessorSettings { AllowLostEvents = true, }; using (ITraceProcessor trace = TraceProcessor.Create(tracePath, settings)) { IPendingResult <IReferenceSetDataSource> pendingReferenceSet = trace.UseReferenceSetData(); IPendingResult <IProcessDataSource> pendingProcesses = trace.UseProcesses(); IPendingResult <ISymbolDataSource> pendingSymbols = trace.UseSymbols(); IPendingResult <IImageSectionDataSource> pendingImageSections = trace.UseImageSections(); trace.Process(); IProcessDataSource processData = pendingProcesses.Result; IReferenceSetDataSource referenceSetData = pendingReferenceSet.Result; ISymbolDataSource symbolData = pendingSymbols.Result; IImageSectionDataSource imageSectionData = pendingImageSections.Result; symbolData.LoadSymbolsForConsoleAsync(SymCachePath.Automatic, SymbolPath.Automatic).GetAwaiter().GetResult(); // // Create a mapping of all static images loaded into all processes during the course of the trace. // This is a mapping of images to a dictionary of [processes, IsPotentialDelayLoadTarget] // Dictionary <string, Dictionary <string, bool> > potentialDelayLoads = new Dictionary <string, Dictionary <string, bool> >(); // // Keep track of the image data for all of the images we've seen loaded. We use this later to look up // section names for the offsets being accessed. // Dictionary <string, IImage> imageData = new Dictionary <string, IImage>(); foreach (var proc in processData.Processes) { foreach (var image in proc.Images) { string processName = GenerateProcessNameString(proc); if (image.LoadTime != null) { Dictionary <string, bool> processDict; if (!potentialDelayLoads.ContainsKey(image.Path)) { processDict = new Dictionary <string, bool>(); potentialDelayLoads.Add(image.Path, processDict); } else { processDict = potentialDelayLoads[image.Path]; } if (!processDict.ContainsKey(processName)) { bool eligibleForDelayLoad = (image.LoadReason == ImageLoadReason.StaticDependency); processDict.Add(processName, eligibleForDelayLoad); } // // Save off whether or not this image is a potential delay load target. We only consider // static dependencies for delay loads. // processDict[processName] = processDict[processName] && (image.LoadReason == ImageLoadReason.StaticDependency); // // Save off a pointer to the image data for this image so we can look up sections later // if (!imageData.ContainsKey(image.Path)) { imageData.Add(image.Path, image); } } } } // // Enumerate every page access. We're going to check each one to see if it was a 'code' page being accessed, // and if it was we conclude that code from this image was used during the trace by that process. Therefore, // it's not something that should be delay loaded. // foreach (IReferenceSetInterval refSetInterval in referenceSetData.Intervals) { foreach (IReferenceSetAccessedPage pageAccess in refSetInterval.PageAccesses) { // // Make sure the page was accessed from the usermode process. // if (pageAccess.ImpactedProcess == null) { continue; } // // Ignore the memory compression process. This is a system service. // if (pageAccess.ImpactedProcess.ImageName.Equals("MemCompression")) { continue; } // // Make sure we have a file path // if (pageAccess?.Page?.Path == null) { continue; } var fileBeingAccessed = pageAccess?.Page?.Path; // // Not all file paths are images (think MFT or data files). Make sure this is in our image // dictionary. // if (!imageData.ContainsKey(pageAccess.Page.Path)) { continue; } // // Make sure that this image was listed in the image data // if (!potentialDelayLoads.ContainsKey(fileBeingAccessed)) { continue; } // // Grab the image data, and use this to get the info on the page that was being accessed. // var data = imageData[pageAccess.Page.Path]; var sectionName = GetSectionNameFromPage(pageAccess, data, imageSectionData, pageAccess.ImpactedProcess); // // We really only want consider .text pages, as we want to find images where the 'code' is never // used. We have to include "unknown" as well since this is what shows up for images that we // can't find symbols for. This effectively means for images without symbols we consider all pages. // if (!(sectionName.Contains(".text") || sectionName.Contains("Unknown"))) { continue; } // // If the loader accessed the page, it's still a potential delay load candidiate. // if (IsLoaderAccessedPage(pageAccess)) { continue; } // // A .text page was accessed from somewhere other then the loader. This image isn't // a delay load candidate for this process. // string processName = GenerateProcessNameString(pageAccess.ImpactedProcess); if ((potentialDelayLoads[fileBeingAccessed]).ContainsKey(processName)) { if ((potentialDelayLoads[fileBeingAccessed])[processName]) { (potentialDelayLoads[fileBeingAccessed])[processName] = false; } } else { potentialDelayLoads[fileBeingAccessed].Add(processName, false); } } } // // Print out all potential delays loads we found. We modify the output format to be in // process->image style for easier consumption from the console. // List <Tuple <string, string> > delayLoads = new List <Tuple <string, string> >(); foreach (var imagesLoaded in potentialDelayLoads) { foreach (var processesDict in imagesLoaded.Value) { if (processesDict.Value == true) { delayLoads.Add(new Tuple <string, string>(processesDict.Key, imagesLoaded.Key)); } } } delayLoads.Sort(); foreach (var delayload in delayLoads) { Console.WriteLine("{0} can delay load {1}", delayload.Item1, delayload.Item2); } } return(0); }