/// <summary> /// Called when the scan updates. /// </summary> /// <param name="cancellationToken">The cancellation token for handling canceled tasks.</param> protected override void OnUpdate(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); // Collect pointer roots foreach (UInt64 modulePointer in this.LevelPointers.ModulePointerPool.PointerAddresses) { this.DiscoveredPointers.AddPointerRoot(new PointerRoot(modulePointer)); } this.DiscoveredPointers.Sort(); // Build out pointer paths via a DFS foreach (PointerRoot pointerRoot in this.DiscoveredPointers.PointerRoots) { PointerPool nextLevel = this.LevelPointers.NonStaticPointerPools.First(); UInt64 pointerDestination = this.LevelPointers.ModulePointerPool[pointerRoot.BaseAddress]; pointerRoot.AddOffsets(nextLevel.FindOffsets(pointerDestination, this.PointerRadius)); // Recurse on the branches if (this.LevelPointers.NonStaticPointerPools.Count() > 1) { foreach (PointerBranch branch in pointerRoot) { this.BuildPointerPaths(this.ApplyOffset(pointerDestination, branch.Offset), branch, 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) { 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 repeated task completes. /// </summary> protected override void OnEnd() { this.CollectedPointersCallback?.Invoke(this.ModulePointers, this.HeapPointers); this.UpdateProgress(ScheduledTask.MaximumProgress); this.ModulePointers = null; this.HeapPointers = null; }
/// <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)); }
private void BuildPointerPaths(UInt64 currentPointer, PointerBranch pointerBranch, Int32 levelIndex) { PointerPool currentLevel = this.LevelPointers.NonStaticPointerPools.ElementAt(levelIndex); PointerPool nextLevel = this.LevelPointers.NonStaticPointerPools.ElementAt(levelIndex + 1); UInt64 pointerDestination = currentLevel[currentPointer]; pointerBranch.AddOffsets(nextLevel.FindOffsets(pointerDestination, this.PointerRadius)); // Stop recursing if no more levels if (levelIndex + 1 >= this.LevelPointers.NonStaticPointerPools.Count() - 1) { return; } foreach (PointerBranch branch in pointerBranch) { this.BuildPointerPaths(this.ApplyOffset(pointerDestination, branch.Offset), branch, levelIndex + 1); } }
/// <summary> /// Called when the scan updates. /// </summary> /// <param name="cancellationToken">The cancellation token for handling canceled tasks.</param> protected override void OnUpdate(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); Int32 processedPointerRoots = 0; // We start from modules and build paths to the destination. Create the roots from our found module pointers. this.ScannedPointers.CreatePointerRoots(this.LevelPointers.ModulePointerPool.PointerAddresses); // Build out pointer paths via a DFS foreach (PointerRoot pointerRoot in this.ScannedPointers.PointerRoots) { cancellationToken.ThrowIfCancellationRequested(); PointerPool nextLevel = this.LevelPointers.DynamicPointerPools.First(); UInt64 pointerDestination = this.LevelPointers.ModulePointerPool[pointerRoot.BaseAddress]; pointerRoot.AddOffsets(nextLevel.FindOffsets(pointerDestination, this.PointerRadius)); // Recurse on the branches if (this.LevelPointers.IsMultiLevel) { foreach (PointerBranch branch in pointerRoot) { this.BuildPointerPaths(this.ApplyOffset(pointerDestination, branch.Offset), branch); } } // Update scan progress if (Interlocked.Increment(ref processedPointerRoots) % 32 == 0) { this.UpdateProgress(processedPointerRoots, this.ScannedPointers.PointerRoots.Count(), canFinalize: false); } } this.ScannedPointers.BuildCount(); }
/// <summary> /// Called when the scheduled task starts. /// </summary> protected override void OnBegin() { this.ModulePointers = new PointerPool(); this.HeapPointers = new PointerPool(); }
/// <summary> /// Callback function from the pointer collector to retrieve the collected pointers. /// </summary> /// <param name="modulePointers">The collected pointers residing in modules.</param> /// <param name="heapPointers">The collected pointers residing in the heap.</param> private void SetCollectedPointers(PointerPool modulePointers, PointerPool heapPointers) { this.ModulePointers = modulePointers; this.HeapPointers = heapPointers; }