/// <summary> /// Starts the pointer scan. /// </summary> private void StartScan() { TrackableTask <PointerBag> pointerScanTask = PointerScan.Scan(this.TargetAddress, (UInt32)this.PointerRadius, this.PointerDepth, 4); TaskTrackerViewModel.GetInstance().TrackTask(pointerScanTask); PointerScanResultsViewModel.GetInstance().DiscoveredPointers = pointerScanTask.Result; }
/// <summary> /// Starts the scan using the current constraints. /// </summary> private void StartScan() { // Create a constraint manager that includes the current active constraint ConstraintNode scanConstraints = this.ActiveConstraint.Clone(); if (!scanConstraints.IsValid()) { Logger.Log(LogLevel.Warn, "Unable to start scan with given constraints"); return; } DataType dataType = ScanResultsViewModel.GetInstance().ActiveType; // Collect values TrackableTask <Snapshot> valueCollectorTask = ValueCollector.CollectValues( SnapshotManager.GetSnapshot(Snapshot.SnapshotRetrievalMode.FromActiveSnapshotOrPrefilter, dataType)); TaskTrackerViewModel.GetInstance().TrackTask(valueCollectorTask); // Perform manual scan on value collection complete valueCollectorTask.OnCompletedEvent += ((completedValueCollection) => { Snapshot snapshot = valueCollectorTask.Result; TrackableTask <Snapshot> scanTask = ManualScanner.Scan( snapshot, scanConstraints); TaskTrackerViewModel.GetInstance().TrackTask(scanTask); SnapshotManager.SaveSnapshot(scanTask.Result); }); }
/// <summary> /// Starts the pointer value rescan. /// </summary> private void StartPointerRetargetScan() { TrackableTask <PointerBag> pointerRetargetScanTask = PointerRetargetScan.Scan(this.RetargetAddress, 4, PointerScanResultsViewModel.GetInstance().DiscoveredPointers); TaskTrackerViewModel.GetInstance().TrackTask(pointerRetargetScanTask); PointerScanResultsViewModel.GetInstance().DiscoveredPointers = pointerRetargetScanTask.Result; }
public static TrackableTask <Snapshot> CollectValues(Snapshot snapshot, String taskIdentifier = null) { try { return(TrackableTask <Snapshot> .Create(ValueCollector.Name, taskIdentifier, out UpdateProgress updateProgress, out CancellationToken cancellationToken) .With(Task <Snapshot> .Run(() => { try { Int32 processedRegions = 0; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); ParallelOptions options = ParallelSettings.ParallelSettingsFastest.Clone(); options.CancellationToken = cancellationToken; // Read memory to get current values for each region Parallel.ForEach( snapshot.OptimizedReadGroups, options, (readGroup) => { // Check for canceled scan cancellationToken.ThrowIfCancellationRequested(); // Read the memory for this region readGroup.ReadAllMemory(); // Update progress every N regions if (Interlocked.Increment(ref processedRegions) % 32 == 0) { updateProgress((float)processedRegions / (float)snapshot.RegionCount * 100.0f); } }); cancellationToken.ThrowIfCancellationRequested(); stopwatch.Stop(); Logger.Log(LogLevel.Info, "Values collected in: " + stopwatch.Elapsed); return snapshot; } catch (OperationCanceledException ex) { Logger.Log(LogLevel.Warn, "Scan canceled", ex); return null; } catch (Exception ex) { Logger.Log(LogLevel.Error, "Error performing scan", ex); return null; } }, cancellationToken))); } catch (TaskConflictException ex) { Logger.Log(LogLevel.Warn, "Unable to start scan. Scan is already queued."); throw ex; } }
/// <summary> /// Starts the pointer address rebase. /// </summary> private void StartPointerRebase() { TrackableTask <PointerBag> pointerRebaseTask = PointerRebase.Scan(PointerScanResultsViewModel.GetInstance().DiscoveredPointers, readMemory: true, performUnchangedScan: true); TaskTrackerViewModel.GetInstance().TrackTask(pointerRebaseTask); PointerScanResultsViewModel.GetInstance().DiscoveredPointers = pointerRebaseTask.Result; }
private void StartScan(int index, Int64 searchAddress, bool validatingProcess = false) { if (index > 0) { SnapshotManager.ClearSnapshots(); } ConstraintNode scanConstraints = new ScanConstraint(ScanConstraint.ConstraintType.Equal, searchAddress, dataType); TrackableTask <Snapshot> valueCollectorTask = ValueCollector.CollectValues( SnapshotManager.GetSnapshot(Snapshot.SnapshotRetrievalMode.FromActiveSnapshotOrPrefilter, dataType), TrackableTask.UniversalIdentifier); valueCollectorTask.OnCompletedEvent += ((completedValueCollectionTask) => { Snapshot snapshot = valueCollectorTask.Result; TrackableTask <Snapshot> scanTask = ManualScanner.Scan( snapshot, scanConstraints, TrackableTask.UniversalIdentifier); SnapshotManager.SaveSnapshot(scanTask.Result); snapshot = scanTask.Result; scannedAddresses.Add(new List <Int64>()); if (snapshot != null) { for (UInt64 i = 0; i < snapshot.ElementCount; ++i) { SnapshotElementIndexer element = snapshot[i]; Object currentValue = element.HasCurrentValue() ? element.LoadCurrentValue() : null; Object previousValue = element.HasPreviousValue() ? element.LoadPreviousValue() : null; String moduleName = String.Empty; UInt64 address = Query.Default.AddressToModule(element.BaseAddress, out moduleName); PointerItem pointerItem = new PointerItem(baseAddress: address, dataType: dataType, moduleName: moduleName, value: currentValue); pointerItem.ForceResolveAddress(); scannedAddresses[index].Add(Int64.Parse(pointerItem.AddressSpecifier, NumberStyles.HexNumber, CultureInfo.CurrentCulture)); } } int nextIteration = index + 1; if (nextIteration < addressesToFind.Count) { StartScan(nextIteration, addressesToFind[nextIteration], validatingProcess); } else { SearchLogic(validatingProcess); } }); }
public static TrackableTask <Snapshot> CollectDataSegments(Boolean ignoreSystemModules = true) { return(TrackableTask <Snapshot> .Create(DataSegmentCollector.Name, out UpdateProgress updateProgress, out CancellationToken cancellationToken) .With(Task.Factory.StartNew <Snapshot>(() => { try { Int32 processedModules = 0; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); // Construct a snapshot from static data segments in target process modules IEnumerable <NormalizedModule> modules = Query.Default.GetModules(); DirectoryInfo systemPathInfo = new DirectoryInfo(Environment.SystemDirectory); ConcurrentBag <IList <SnapshotRegion> > dataRegions = new ConcurrentBag <IList <SnapshotRegion> >(); Parallel.ForEach( modules, ParallelSettings.ParallelSettingsFastest, (module) => { DirectoryInfo modulePathInfo = new DirectoryInfo(module.FullPath); // Collect module data segments, unless it is a system module and ignore is set if (!ignoreSystemModules || modulePathInfo.Parent != systemPathInfo) { IList <SnapshotRegion> dataSegments = MetaData.Default.GetDataSegments(module.BaseAddress, module.FullPath); dataRegions.Add(dataSegments); } // Update progress every N regions if (Interlocked.Increment(ref processedModules) % 32 == 0) { updateProgress((float)processedModules / (float)modules.Count() * 100.0f); } }); Snapshot result = new Snapshot(DataSegmentCollector.Name, dataRegions.SelectMany(region => region)); cancellationToken.ThrowIfCancellationRequested(); stopwatch.Stop(); Logger.Log(LogLevel.Info, "Data segments collected in: " + stopwatch.Elapsed); return result; } catch (OperationCanceledException ex) { Logger.Log(LogLevel.Warn, "Data segment collection canceled", ex); return null; } catch (Exception ex) { Logger.Log(LogLevel.Error, "Error performing data segment collection", ex); return null; } }, cancellationToken))); }
/// <summary> /// Tracks a given task until it is canceled or completed. /// </summary> /// <param name="task">The task to track.</param> public void TrackTask(TrackableTask task) { Application.Current.Dispatcher.Invoke(new Action(() => { task.OnCanceledEvent += this.RemoveTask; task.OnCompletedEvent += this.RemoveTask; this.TrackedTasks.Add(task); })); }
/// <summary> /// Removes a tracked task from the list of tracked tasks. /// </summary> /// <param name="task">The task to remove.</param> private void RemoveTask(TrackableTask task) { Application.Current.Dispatcher.Invoke(new Action(() => { if (this.TrackedTasks.Contains(task)) { this.TrackedTasks.Remove(task); } })); }
/// <summary> /// Begins the value collection. /// </summary> private void CollectValues() { DataType dataType = ScanResultsViewModel.GetInstance().ActiveType; TrackableTask <Snapshot> valueCollectTask = ValueCollector.CollectValues( SnapshotManager.GetSnapshot(Snapshot.SnapshotRetrievalMode.FromActiveSnapshotOrPrefilter, dataType)); TaskTrackerViewModel.GetInstance().TrackTask(valueCollectTask); SnapshotManager.SaveSnapshot(valueCollectTask.Result); }
/// <summary> /// Starts the pointer address rebase. /// </summary> private void StartPointerRebase() { try { TrackableTask <PointerBag> pointerRebaseTask = PointerRebase.Scan(PointerScanResultsViewModel.GetInstance().DiscoveredPointers, readMemory: true, performUnchangedScan: true, taskIdentifier: PointerScannerViewModel.PointerScanTaskIdentifier); TaskTrackerViewModel.GetInstance().TrackTask(pointerRebaseTask); PointerScanResultsViewModel.GetInstance().DiscoveredPointers = pointerRebaseTask.Result; } catch (TaskConflictException) { } }
/// <summary> /// Starts the pointer value rescan. /// </summary> private void StartPointerRetargetScan() { try { TrackableTask <PointerBag> pointerRetargetScanTask = PointerRetargetScan.Scan(this.RetargetAddress, 4, PointerScanResultsViewModel.GetInstance().DiscoveredPointers, PointerScannerViewModel.PointerScanTaskIdentifier); TaskTrackerViewModel.GetInstance().TrackTask(pointerRetargetScanTask); PointerScanResultsViewModel.GetInstance().DiscoveredPointers = pointerRetargetScanTask.Result; } catch (TaskConflictException) { } }
/// <summary> /// Begins the value collection. /// </summary> private void CollectValues() { DataTypeBase dataType = ScanResultsViewModel.GetInstance().ActiveType; TrackableTask <Snapshot> valueCollectTask = ValueCollector.CollectValues( SessionManager.Session?.OpenedProcess, SessionManager.Session.SnapshotManager.GetActiveSnapshotCreateIfNone(SessionManager.Session.OpenedProcess), TrackableTask.UniversalIdentifier ); TaskTrackerViewModel.GetInstance().TrackTask(valueCollectTask); SessionManager.Session.SnapshotManager.SaveSnapshot(valueCollectTask.Result); }
/// <summary> /// Starts the pointer value rescan. /// </summary> private void StartPointerRetargetScan() { try { PointerSize pointerSize = SessionManager.Session.OpenedProcess.Is32Bit() ? PointerSize.Byte4 : PointerSize.Byte8; TrackableTask <PointerBag> pointerRetargetScanTask = PointerRetargetScan.Scan( SessionManager.Session.OpenedProcess, this.RetargetAddress, pointerSize.ToSize(), PointerScanResultsViewModel.GetInstance().DiscoveredPointers, PointerScannerViewModel.PointerScanTaskIdentifier ); TaskTrackerViewModel.GetInstance().TrackTask(pointerRetargetScanTask); PointerScanResultsViewModel.GetInstance().DiscoveredPointers = pointerRetargetScanTask.Result; } catch (TaskConflictException) { } }
/// <summary> /// Starts the scan using the current constraints. /// </summary> private void StartScan() { // Create a constraint manager that includes the current active constraint DataTypeBase dataType = ScanResultsViewModel.GetInstance().ActiveType; ScanConstraints scanConstraints = new ScanConstraints(dataType, this.ActiveConstraint?.Clone()); if (!scanConstraints.IsValid()) { Logger.Log(LogLevel.Warn, "Unable to start scan with given constraints"); return; } try { // Collect values TrackableTask <Snapshot> valueCollectorTask = ValueCollector.CollectValues( SessionManager.Session.OpenedProcess, SessionManager.Session.SnapshotManager.GetActiveSnapshotCreateIfNone(SessionManager.Session.OpenedProcess), TrackableTask.UniversalIdentifier ); TaskTrackerViewModel.GetInstance().TrackTask(valueCollectorTask); // Perform manual scan on value collection complete valueCollectorTask.OnCompletedEvent += ((completedValueCollectionTask) => { Snapshot snapshot = valueCollectorTask.Result; TrackableTask <Snapshot> scanTask = ManualScanner.Scan( snapshot, scanConstraints, TrackableTask.UniversalIdentifier); TaskTrackerViewModel.GetInstance().TrackTask(scanTask); SessionManager.Session.SnapshotManager.SaveSnapshot(scanTask.Result); }); } catch (TaskConflictException) { } }
public Int32 Handle() { // If set to 0.0, assume unset and set to 1.0. Otherwise, clamp in bounds. Intensity = Intensity <= 0.0 ? 1.0 : Math.Clamp(Intensity, 0.0, 1.0); // Collect values TrackableTask <Snapshot> valueCollectorTask = ValueCollector.CollectValues( SessionManager.Session.SnapshotManager.GetActiveSnapshotCreateIfNone(SessionManager.Session.OpenedProcess, DataTypeBase.Int32), TrackableTask.UniversalIdentifier); // Recollect values TrackableTask <Snapshot> valueRecollectorTask = ValueCollector.CollectValues( valueCollectorTask.Result, TrackableTask.UniversalIdentifier); // Scan for any changed values TrackableTask <Snapshot> scanTask = ManualScanner.Scan( valueRecollectorTask.Result, new ScanConstraint(ScanConstraint.ConstraintType.Changed, DataTypeBase.Int32), TrackableTask.UniversalIdentifier); Random random = new Random(); // Start overwriting any memory that changed with 0s foreach (SnapshotRegion region in scanTask.Result.SnapshotRegions) { for (Int32 index = 0; index < region.ElementCount; index++) { if (random.NextDouble() <= Intensity) { MemoryWriter.Instance.Write <Int32>(SessionManager.Session.OpenedProcess, region[index].BaseAddress, 0); } } } return(0); }
/// <summary> /// Performs a pointer scan for a given address. /// </summary> /// <param name="address">The address for which to perform a pointer scan.</param> /// <param name="maxOffset">The maximum pointer offset.</param> /// <param name="depth">The maximum pointer search depth.</param> /// <param name="alignment">The pointer scan alignment.</param> /// <returns>Atrackable task that returns the scan results.</returns> public static TrackableTask <PointerBag> Scan(UInt64 address, UInt32 maxOffset, Int32 depth, Int32 alignment) { TrackableTask <PointerBag> pointerScanTask = TrackableTask <PointerBag> .Create(PointerScan.Name, out UpdateProgress updateProgress, out CancellationToken cancellationToken); return(pointerScanTask.With(Task.Factory.StartNew <PointerBag>(() => { try { cancellationToken.ThrowIfCancellationRequested(); PointerSize pointerSize = Processes.Default.IsOpenedProcess32Bit() ? PointerSize.Byte4 : PointerSize.Byte8; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); // Step 1) Create a snapshot of the target address Snapshot targetAddress = new Snapshot(new SnapshotRegion[] { new SnapshotRegion(new ReadGroup(address, pointerSize.ToSize(), pointerSize.ToDataType(), alignment), 0, pointerSize.ToSize()) }); // Step 2) Collect static pointers Snapshot staticPointers = SnapshotManager.GetSnapshot(Snapshot.SnapshotRetrievalMode.FromModules, pointerSize.ToDataType()); TrackableTask <Snapshot> valueCollector = ValueCollector.CollectValues(staticPointers); staticPointers = valueCollector.Result; // Step 3) Collect heap pointers Snapshot heapPointers = SnapshotManager.GetSnapshot(Snapshot.SnapshotRetrievalMode.FromHeaps, pointerSize.ToDataType()); TrackableTask <Snapshot> heapValueCollector = ValueCollector.CollectValues(heapPointers); heapPointers = heapValueCollector.Result; // Step 3) Build levels IList <Level> levels = new List <Level>(); if (depth > 0) { // Create 1st level with target address and static pointers levels.Add(new Level(targetAddress, staticPointers)); // Initialize each level with all static addresses and all heap addresses for (Int32 index = 0; index < depth - 1; index++) { levels.Add(new Level(heapPointers, staticPointers)); } } // Exit if canceled cancellationToken.ThrowIfCancellationRequested(); // Step 4) Rebase to filter out unwanted pointers PointerBag newPointerBag = new PointerBag(levels, maxOffset, pointerSize); TrackableTask <PointerBag> pointerRebaseTask = PointerRebase.Scan(newPointerBag, readMemory: false, performUnchangedScan: false); PointerBag rebasedPointerBag = pointerRebaseTask.Result; // Exit if canceled cancellationToken.ThrowIfCancellationRequested(); stopwatch.Stop(); Logger.Log(LogLevel.Info, "Pointer scan complete in: " + stopwatch.Elapsed); return rebasedPointerBag; } catch (OperationCanceledException ex) { Logger.Log(LogLevel.Warn, "Pointer scan canceled", ex); } catch (Exception ex) { Logger.Log(LogLevel.Error, "Error performing pointer scan", ex); } return null; }, cancellationToken))); }
/// <summary> /// Filters the given snapshot to find all values that are valid pointers. /// </summary> /// <param name="snapshot">The snapshot on which to perfrom the scan.</param> /// <returns></returns> public static TrackableTask <Snapshot> Filter(TrackableTask parentTask, Snapshot snapshot, IVectorSearchKernel searchKernel, PointerSize pointerSize, Snapshot DEBUG, UInt32 RADIUS_DEBUG) { return(TrackableTask <Snapshot> .Create(PointerFilter.Name, out UpdateProgress updateProgress, out CancellationToken cancellationToken) .With(Task <Snapshot> .Run(() => { try { parentTask.CancellationToken.ThrowIfCancellationRequested(); ConcurrentBag <IList <SnapshotRegion> > regions = new ConcurrentBag <IList <SnapshotRegion> >(); ParallelOptions options = ParallelSettings.ParallelSettingsFastest.Clone(); options.CancellationToken = parentTask.CancellationToken; // ISearchKernel DEBUG_KERNEL = new SpanSearchKernel(DEBUG, RADIUS_DEBUG); Parallel.ForEach( snapshot.OptimizedSnapshotRegions, options, (region) => { // Check for canceled scan parentTask.CancellationToken.ThrowIfCancellationRequested(); if (!region.ReadGroup.CanCompare(null)) { return; } ScanConstraints constraints = new ScanConstraints(pointerSize.ToDataType(), null); SnapshotElementVectorComparer vectorComparer = new SnapshotElementVectorComparer(region: region, constraints: constraints); vectorComparer.SetCustomCompareAction(searchKernel.GetSearchKernel(vectorComparer)); // SnapshotElementVectorComparer DEBUG_COMPARER = new SnapshotElementVectorComparer(region: region); // DEBUG_COMPARER.SetCustomCompareAction(DEBUG_KERNEL.GetSearchKernel(DEBUG_COMPARER)); IList <SnapshotRegion> results = vectorComparer.Compare(); // When debugging, these results should be the same as the results above // IList<SnapshotRegion> DEBUG_RESULTS = vectorComparer.Compare(); if (!results.IsNullOrEmpty()) { regions.Add(results); } }); // Exit if canceled parentTask.CancellationToken.ThrowIfCancellationRequested(); snapshot = new Snapshot(PointerFilter.Name, regions.SelectMany(region => region)); } catch (OperationCanceledException ex) { Logger.Log(LogLevel.Warn, "Pointer filtering canceled", ex); throw ex; } catch (Exception ex) { Logger.Log(LogLevel.Error, "Error performing pointer filtering", ex); return null; } return snapshot; }, parentTask.CancellationToken))); }
/// <summary> /// Fetches and applies updates from the Github repository. The application is not restarted. /// </summary> public static void UpdateApp() { if (!ApplicationUpdater.IsSquirrelInstalled()) { Logger.Log(LogLevel.Warn, "Updater not found, Squalr will not check for automatic updates."); return; } Task.Run(async() => { try { using (UpdateManager manager = await UpdateManager.GitHubUpdateManager(ApplicationUpdater.GithubRepositoryUrl)) { UpdateInfo updates = await manager.CheckForUpdate(); ReleaseEntry lastVersion = updates?.ReleasesToApply?.OrderBy(x => x.Version).LastOrDefault(); if (lastVersion == null) { Logger.Log(LogLevel.Info, "Squalr is up to date."); return; } Logger.Log(LogLevel.Info, "New version of Squalr found. Downloading files in background..."); TrackableTask <Boolean> downloadTask = TrackableTask <Boolean> .Create("Downloading Updates", out UpdateProgress updateProgress, out CancellationToken cancellationToken) .With(Task <Boolean> .Run(() => { try { manager.DownloadReleases(new[] { lastVersion }, (progress) => updateProgress(progress)).Wait(); } catch (Exception ex) { Logger.Log(LogLevel.Error, "Error downloading updates.", ex); return(false); } return(true); }, cancellationToken)); TaskTrackerViewModel.GetInstance().TrackTask(downloadTask); if (!downloadTask.Result) { return; } TrackableTask <Boolean> applyReleasesTask = TrackableTask <Boolean> .Create("Applying Releases", out updateProgress, out cancellationToken) .With(Task <Boolean> .Run(() => { try { manager.ApplyReleases(updates, (progress) => updateProgress(progress)).Wait(); } catch (Exception ex) { Logger.Log(LogLevel.Error, "Error applying releases.", ex); return(false); } return(true); }, cancellationToken)); TaskTrackerViewModel.GetInstance().TrackTask(applyReleasesTask); if (!applyReleasesTask.Result) { return; } TrackableTask <Boolean> updateTask = TrackableTask <Boolean> .Create("Updating", out updateProgress, out cancellationToken) .With(Task <Boolean> .Run(() => { try { manager.UpdateApp((progress) => updateProgress(progress)).Wait(); } catch (Exception ex) { Logger.Log(LogLevel.Error, "Error applying updates.", ex); return(false); } return(true); }, cancellationToken)); TaskTrackerViewModel.GetInstance().TrackTask(updateTask); if (!updateTask.Result) { return; } Logger.Log(LogLevel.Info, "New Squalr version downloaded. Restart the application to apply updates."); } } catch (Exception ex) { Logger.Log(LogLevel.Error, "Error updating Squalr.", ex); } }); }
/// <summary> /// Performs a pointer scan for a given address. /// </summary> /// <param name="address">The address for which to perform a pointer scan.</param> /// <param name="maxOffset">The maximum pointer offset.</param> /// <param name="depth">The maximum pointer search depth.</param> /// <param name="alignment">The pointer scan alignment.</param> /// <param name="taskIdentifier">The unique identifier to prevent duplicate tasks.</param> /// <returns>Atrackable task that returns the scan results.</returns> public static TrackableTask <PointerBag> Scan(UInt64 newAddress, Int32 alignment, PointerBag oldPointerBag, String taskIdentifier = null) { try { return(TrackableTask <PointerBag> .Create(PointerRetargetScan.Name, taskIdentifier, out UpdateProgress updateProgress, out CancellationToken cancellationToken) .With(Task <PointerBag> .Run(() => { try { cancellationToken.ThrowIfCancellationRequested(); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); // Step 1) Create a snapshot of the new target address Snapshot targetAddress = new Snapshot(new SnapshotRegion[] { new SnapshotRegion(new ReadGroup(newAddress, oldPointerBag.PointerSize.ToSize(), oldPointerBag.PointerSize.ToDataType(), alignment), 0, oldPointerBag.PointerSize.ToSize()) }); // Step 2) Collect heap pointers Snapshot heapPointers = SnapshotManager.GetSnapshot(Snapshot.SnapshotRetrievalMode.FromHeaps, oldPointerBag.PointerSize.ToDataType()); TrackableTask <Snapshot> heapValueCollector = ValueCollector.CollectValues(heapPointers); heapPointers = heapValueCollector.Result; // Step 3) Rebuild levels IList <Level> levels = new List <Level>(); if (oldPointerBag.Depth > 0) { // Create 1st level with target address and previous static pointers levels.Add(new Level(targetAddress, oldPointerBag.Levels.First().StaticPointers)); // Copy over all old static pointers, and replace the heaps with a full heap foreach (Level level in oldPointerBag.Levels.Skip(1)) { levels.Add(new Level(heapPointers, level.StaticPointers)); } } // Exit if canceled cancellationToken.ThrowIfCancellationRequested(); // Step 4) Perform a rebase from the old static addresses onto the new heaps PointerBag newPointerBag = new PointerBag(levels, oldPointerBag.MaxOffset, oldPointerBag.PointerSize); TrackableTask <PointerBag> pointerRebaseTask = PointerRebase.Scan(newPointerBag, readMemory: true, performUnchangedScan: true); PointerBag rebasedPointerBag = pointerRebaseTask.Result; stopwatch.Stop(); Logger.Log(LogLevel.Info, "Pointer retarget complete in: " + stopwatch.Elapsed); return rebasedPointerBag; } catch (OperationCanceledException ex) { Logger.Log(LogLevel.Warn, "Pointer retarget canceled", ex); } catch (Exception ex) { Logger.Log(LogLevel.Error, "Error performing pointer retarget", ex); } return null; }, cancellationToken))); } catch (TaskConflictException ex) { Logger.Log(LogLevel.Warn, "A pointer scan is already scheduled."); throw ex; } }
/// <summary> /// Performs a pointer scan for a given address. /// </summary> /// <param name="address">The address for which to perform a pointer scan.</param> /// <param name="maxOffset">The maximum pointer offset.</param> /// <param name="depth">The maximum pointer search depth.</param> /// <param name="alignment">The pointer scan alignment.</param> /// <param name="taskIdentifier">The unique identifier to prevent duplicate tasks.</param> /// <returns>Atrackable task that returns the scan results.</returns> public static TrackableTask <PointerBag> Scan(Process process, PointerBag previousPointerBag, Boolean readMemory, Boolean performUnchangedScan, String taskIdentifier = null) { try { TrackableTask <PointerBag> pointerScanTask = TrackableTask <PointerBag> .Create(PointerRebase.Name, taskIdentifier, out UpdateProgress updateProgress, out CancellationToken cancellationToken); return(pointerScanTask.With(Task <PointerBag> .Run(() => { try { cancellationToken.ThrowIfCancellationRequested(); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); DataTypeBase pointerDataType = previousPointerBag.PointerSize.ToDataType(); ScanConstraint scanConstraint = new ScanConstraint(ScanConstraint.ConstraintType.Unchanged); ScanConstraints scanConstraints = new ScanConstraints(pointerDataType, scanConstraint); IList <Level> oldLevels = previousPointerBag.Levels; IList <Level> newLevels = new List <Level>(); for (Int32 levelIndex = 0; levelIndex < oldLevels.Count; levelIndex++) { Snapshot updatedStaticPointers = oldLevels[levelIndex].StaticPointers; Snapshot updatedHeapPointers = oldLevels[levelIndex].HeapPointers; // Step 1) Re-read values of all pointers if (readMemory) { TrackableTask <Snapshot> staticValueCollector = ValueCollector.CollectValues(process, updatedStaticPointers); // Does not apply to target address if (levelIndex > 0) { TrackableTask <Snapshot> heapValueCollector = ValueCollector.CollectValues(process, updatedHeapPointers); updatedHeapPointers = heapValueCollector.Result; } updatedStaticPointers = staticValueCollector.Result; } // Step 2) A neat (optional) trick: Scan for unchanged values to filter out dynamic pointers if (performUnchangedScan) { TrackableTask <Snapshot> staticValueScanner = ManualScanner.Scan(updatedStaticPointers, scanConstraints); // Does not apply to target address if (levelIndex > 0) { TrackableTask <Snapshot> heapValueScanner = ManualScanner.Scan(updatedHeapPointers, scanConstraints); updatedHeapPointers = heapValueScanner.Result; } updatedStaticPointers = staticValueScanner.Result; } Stopwatch levelStopwatch = new Stopwatch(); levelStopwatch.Start(); // Step 3) Rebase heap onto new previous heap if (levelIndex > 0) { IVectorSearchKernel heapSearchKernel = SearchKernelFactory.GetSearchKernel(newLevels.Last().HeapPointers, previousPointerBag.MaxOffset, previousPointerBag.PointerSize); TrackableTask <Snapshot> heapFilterTask = PointerFilter.Filter(pointerScanTask, updatedHeapPointers, heapSearchKernel, previousPointerBag.PointerSize, newLevels.Last().HeapPointers, previousPointerBag.MaxOffset); updatedHeapPointers = heapFilterTask.Result; } // Step 4) Filter static pointers that still point into the updated heap IVectorSearchKernel staticSearchKernel = SearchKernelFactory.GetSearchKernel(updatedHeapPointers, previousPointerBag.MaxOffset, previousPointerBag.PointerSize); TrackableTask <Snapshot> staticFilterTask = PointerFilter.Filter(pointerScanTask, updatedStaticPointers, staticSearchKernel, previousPointerBag.PointerSize, updatedHeapPointers, previousPointerBag.MaxOffset); updatedStaticPointers = staticFilterTask.Result; levelStopwatch.Stop(); Logger.Log(LogLevel.Info, "Pointer rebase from level " + (levelIndex) + " => " + (levelIndex + 1) + " completed in: " + levelStopwatch.Elapsed); newLevels.Add(new Level(updatedHeapPointers, updatedStaticPointers)); } // Exit if canceled cancellationToken.ThrowIfCancellationRequested(); PointerBag pointerBag = new PointerBag(newLevels, previousPointerBag.MaxOffset, previousPointerBag.PointerSize); stopwatch.Stop(); Logger.Log(LogLevel.Info, "Pointer rebase complete in: " + stopwatch.Elapsed); return pointerBag; } catch (OperationCanceledException ex) { Logger.Log(LogLevel.Warn, "Pointer rebase canceled", ex); } catch (Exception ex) { Logger.Log(LogLevel.Error, "Error performing pointer rebase", ex); } return null; }, cancellationToken))); } catch (TaskConflictException ex) { Logger.Log(LogLevel.Warn, "A pointer scan is already scheduled."); throw ex; } }
/// <summary> /// Performs a pointer scan for a given address. /// </summary> /// <param name="address">The address for which to perform a pointer scan.</param> /// <param name="maxOffset">The maximum pointer offset.</param> /// <param name="depth">The maximum pointer search depth.</param> /// <param name="alignment">The pointer scan alignment.</param> /// <param name="taskIdentifier">The unique identifier to prevent duplicate tasks.</param> /// <returns>Atrackable task that returns the scan results.</returns> public static TrackableTask <PointerBag> Scan(Process process, UInt64 address, UInt32 maxOffset, Int32 depth, Int32 alignment, PointerSize pointerSize, String taskIdentifier = null) { try { return(TrackableTask <PointerBag> .Create(PointerScan.Name, taskIdentifier, out UpdateProgress updateProgress, out CancellationToken cancellationToken) .With(Task <PointerBag> .Run(() => { try { cancellationToken.ThrowIfCancellationRequested(); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); // Step 1) Create a snapshot of the target address Snapshot targetAddress = new Snapshot(new SnapshotRegion[] { new SnapshotRegion(new ReadGroup(address, pointerSize.ToSize()), 0, pointerSize.ToSize()) }); // Step 2) Collect static pointers Snapshot staticPointers = SnapshotQuery.GetSnapshot(process, SnapshotQuery.SnapshotRetrievalMode.FromModules); TrackableTask <Snapshot> valueCollector = ValueCollector.CollectValues(process, staticPointers); staticPointers = valueCollector.Result; // Step 3) Collect heap pointers Snapshot heapPointers = SnapshotQuery.GetSnapshot(process, SnapshotQuery.SnapshotRetrievalMode.FromHeaps); TrackableTask <Snapshot> heapValueCollector = ValueCollector.CollectValues(process, heapPointers); heapPointers = heapValueCollector.Result; // Step 4) Build levels IList <Level> levels = new List <Level>(); if (depth > 0) { // Create 1st level with target address and static pointers levels.Add(new Level(targetAddress, staticPointers)); // Initialize each level with all static addresses and all heap addresses for (Int32 index = 0; index < depth - 1; index++) { levels.Add(new Level(heapPointers, staticPointers)); } } // Exit if canceled cancellationToken.ThrowIfCancellationRequested(); // Step 4) Rebase to filter out unwanted pointers PointerBag newPointerBag = new PointerBag(levels, maxOffset, pointerSize); TrackableTask <PointerBag> pointerRebaseTask = PointerRebase.Scan(process, newPointerBag, readMemory: false, performUnchangedScan: false); PointerBag rebasedPointerBag = pointerRebaseTask.Result; // Exit if canceled cancellationToken.ThrowIfCancellationRequested(); stopwatch.Stop(); Logger.Log(LogLevel.Info, "Pointer scan complete in: " + stopwatch.Elapsed); return rebasedPointerBag; } catch (OperationCanceledException ex) { Logger.Log(LogLevel.Warn, "Pointer scan canceled", ex); } catch (Exception ex) { Logger.Log(LogLevel.Error, "Error performing pointer scan", ex); } return null; }, cancellationToken))); } catch (TaskConflictException ex) { Logger.Log(LogLevel.Warn, "A pointer scan is already scheduled."); throw ex; } }
public Int32 Handle() { if (String.IsNullOrWhiteSpace(this.DataTypeString)) { this.DataTypeString = "int"; } switch (this.DataTypeString.ToLower()) { case "aob": ScanSettings.DataType = DataTypeBase.ByteArray; break; case "bool": ScanSettings.DataType = DataTypeBase.Boolean; break; case "sbyte": ScanSettings.DataType = DataTypeBase.SByte; break; case "i16": case "short": case "int16": ScanSettings.DataType = DataTypeBase.Int16; break; case "i": case "int": case "int32": ScanSettings.DataType = DataTypeBase.Int32; break; case "l": case "i64": case "long": case "int64": ScanSettings.DataType = DataTypeBase.Int64; break; case "b": case "byte": ScanSettings.DataType = DataTypeBase.Byte; break; case "ui16": case "ushort": case "uint16": ScanSettings.DataType = DataTypeBase.Byte; break; case "ui32": case "uint": case "uint32": ScanSettings.DataType = DataTypeBase.UInt32; break; case "ui64": case "ul": case "ulong": case "uint64": ScanSettings.DataType = DataTypeBase.UInt64; break; case "f": case "float": case "single": ScanSettings.DataType = DataTypeBase.Single; break; case "d": case "double": ScanSettings.DataType = DataTypeBase.Double; break; case "str": case "string": ScanSettings.DataType = DataTypeBase.String; break; case "char": ScanSettings.DataType = DataTypeBase.Char; break; default: Console.WriteLine("Unknown data type '" + this.DataTypeString + "', defaulting to int"); ScanSettings.DataType = DataTypeBase.Int32; break; } SessionManager.Session.SnapshotManager.ClearSnapshots(); Console.WriteLine("Data type for new scan set to: " + ScanSettings.DataType.ToString()); // Collect values TrackableTask <Snapshot> valueCollectorTask = ValueCollector.CollectValues( SessionManager.Session.SnapshotManager.GetActiveSnapshotCreateIfNone(SessionManager.Session.OpenedProcess, ScanSettings.DataType), TrackableTask.UniversalIdentifier); valueCollectorTask.OnCompletedEvent += ((completedValueCollectionTask) => { Console.WriteLine(); }); return(0); }
public Int32 Handle() { DataTypeBase dataType = ScanSettings.DataType; ScanConstraint.ConstraintType constraintType = ScanConstraint.ConstraintType.Equal; if (String.IsNullOrWhiteSpace(this.Constraint)) { // Default to equals this.Constraint = "e"; } switch (this.Constraint.ToLower()) { case "le": break; case "l": break; case "g": break; case "ge": break; case "e": break; case "c": break; case "u": break; case "i": break; case "d": break; default: Console.WriteLine("Unknown constraint type '" + this.Constraint + "', defaulting to equal"); break; } if (!SyntaxChecker.CanParseValue(dataType, this.Value)) { Console.WriteLine("Failed to parse '" + this.Value + "' as data type " + dataType?.ToString()); return(-1); } ScanConstraint scanConstraints = new ScanConstraint(constraintType, dataType, Conversions.ParsePrimitiveStringAsPrimitive(dataType, this.Value)); // Collect values TrackableTask <Snapshot> valueCollectorTask = ValueCollector.CollectValues( SessionManager.Session.SnapshotManager.GetActiveSnapshotCreateIfNone(SessionManager.Session.OpenedProcess, dataType), TrackableTask.UniversalIdentifier); // Perform manual scan Snapshot snapshot = valueCollectorTask.Result; TrackableTask <Snapshot> scanTask = ManualScanner.Scan( snapshot, scanConstraints, TrackableTask.UniversalIdentifier); SessionManager.Session.SnapshotManager.SaveSnapshot(scanTask.Result); Console.WriteLine(); return(0); }
/// <summary> /// Begins the manual scan based on the provided snapshot and parameters. /// </summary> /// <param name="snapshot">The snapshot on which to perfrom the scan.</param> /// <param name="constraints">The collection of scan constraints to use in the manual scan.</param> /// <param name="taskIdentifier">The unique identifier to prevent duplicate tasks.</param> /// <returns></returns> public static TrackableTask <Snapshot> Scan(Snapshot snapshot, ConstraintNode constraints, String taskIdentifier = null) { try { return(TrackableTask <Snapshot> .Create(ManualScanner.Name, taskIdentifier, out UpdateProgress updateProgress, out CancellationToken cancellationToken) .With(Task <Snapshot> .Run(() => { Snapshot result = null; try { cancellationToken.ThrowIfCancellationRequested(); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); Int32 processedPages = 0; ConcurrentBag <IList <SnapshotRegion> > regions = new ConcurrentBag <IList <SnapshotRegion> >(); ParallelOptions options = ParallelSettings.ParallelSettingsFastest.Clone(); options.CancellationToken = cancellationToken; Parallel.ForEach( snapshot.OptimizedSnapshotRegions, options, (region) => { // Check for canceled scan cancellationToken.ThrowIfCancellationRequested(); if (!region.ReadGroup.CanCompare(constraints.HasRelativeConstraint())) { return; } SnapshotElementVectorComparer vectorComparer = new SnapshotElementVectorComparer(region: region, constraints: constraints); IList <SnapshotRegion> results = vectorComparer.Compare(); if (!results.IsNullOrEmpty()) { regions.Add(results); } // Update progress every N regions if (Interlocked.Increment(ref processedPages) % 32 == 0) { updateProgress((float)processedPages / (float)snapshot.RegionCount * 100.0f); } }); //// End foreach Region // Exit if canceled cancellationToken.ThrowIfCancellationRequested(); result = new Snapshot(ManualScanner.Name, regions.SelectMany(region => region)); stopwatch.Stop(); Logger.Log(LogLevel.Info, "Scan complete in: " + stopwatch.Elapsed); } catch (OperationCanceledException ex) { Logger.Log(LogLevel.Warn, "Scan canceled", ex); } catch (Exception ex) { Logger.Log(LogLevel.Error, "Error performing scan", ex); } return result; }, cancellationToken))); } catch (TaskConflictException ex) { Logger.Log(LogLevel.Warn, "Unable to start scan. Scan is already queued."); throw ex; } }