/// <summary> /// Called when the scan updates. /// </summary> /// <param name="cancellationToken">The cancellation token for handling canceled tasks.</param> protected override void OnUpdate(CancellationToken cancellationToken) { UInt64 processedPointers = 0; // Create a snapshot only containing the destination SnapshotRegion destinationRegion = new SnapshotRegion(baseAddress: this.TargetAddress.ToIntPtr(), regionSize: 1); destinationRegion.Expand(this.PointerRadius); // Start with the previous level as the destination (as this is a back-tracing algorithm, we work backwards from the destination) Snapshot previousLevelSnapshot = new Snapshot(destinationRegion); // Find all pointers that point to the previous level for (Int32 level = 0; level < this.PointerDepth; level++) { Boolean isModuleLevel = level == this.PointerDepth - 1; PointerPool currentLevelPointers = new PointerPool(); // Iterate all of the heap or module pointers Parallel.ForEach( isModuleLevel ? this.ModulePointers : this.HeapPointers, SettingsViewModel.GetInstance().ParallelSettingsFullCpu, (pointer) => { // Accept this pointer if it is points to the previous level snapshot if (previousLevelSnapshot.ContainsAddress(pointer.Value)) { currentLevelPointers[pointer.Key] = pointer.Value; } // Update scan progress lock (this.ProgressLock) { processedPointers++; // Limit how often we update the progress if (processedPointers % 10000 == 0) { this.UpdateProgress((processedPointers / this.PointerDepth).ToInt32(), this.HeapPointers.Count + this.ModulePointers.Count, canFinalize: false); } } }); // Create a snapshot from this level of pointers previousLevelSnapshot = currentLevelPointers.ToSnapshot(this.PointerRadius); // Add the pointer pool to the level structure if (isModuleLevel) { this.LevelPointers.ModulePointerPool = currentLevelPointers; } else { this.LevelPointers.AddHeapPointerPool(currentLevelPointers); } } // Add the destination pointer pool this.LevelPointers.DestinationPointerPool = new PointerPool(new KeyValuePair <UInt64, UInt64>(this.TargetAddress, 0)); }
/// <summary> /// Called when the scan updates. /// </summary> /// <param name="cancellationToken">The cancellation token for handling canceled tasks.</param> protected override void OnUpdate(CancellationToken cancellationToken) { Int64 processedPointers = 0; // Create a snapshot only containing the destination (as this is a back-tracing algorithm, we work backwards from the destination) Snapshot previousLevelSnapshot = new Snapshot(null, new ReadGroup[] { new ReadGroup(this.TargetAddress.ToIntPtr().Subtract(this.PointerRadius, wrapAround: false), this.PointerRadius) }); // Find all pointers that point to the previous level for (Int32 level = 0; level < this.PointerDepth; level++) { Boolean isModuleLevel = level == this.PointerDepth - 1; PointerPool currentLevelPointers = new PointerPool(); // Check if any pointers point to the previous level Parallel.ForEach( isModuleLevel ? this.ModulePointers : this.HeapPointers, SettingsViewModel.GetInstance().ParallelSettingsFastest, (pointer) => { // Accept this pointer if it is points to the previous level snapshot if (previousLevelSnapshot.ContainsAddress(pointer.Value)) { currentLevelPointers[pointer.Key] = pointer.Value; } // Update scan progress if (Interlocked.Increment(ref processedPointers) % 1024 == 0) { this.UpdateProgress((processedPointers / unchecked ((UInt32)this.PointerDepth)).ToInt32(), this.HeapPointers.Count + this.ModulePointers.Count, canFinalize: false); } }); // Create a snapshot from this level of pointers previousLevelSnapshot = currentLevelPointers.ToSnapshot(this.PointerRadius); // Add the pointer pool to the level structure if (isModuleLevel) { this.LevelPointers.ModulePointerPool = currentLevelPointers; } else { this.LevelPointers.AddHeapPointerPool(currentLevelPointers); } } // Add the destination pointer pool this.LevelPointers.DestinationPointerPool = new PointerPool(new KeyValuePair <UInt64, UInt64>(this.TargetAddress, 0)); }