/// <summary> /// Loads the results for the current page. /// </summary> private void LoadScanResults() { Snapshot snapshot = SnapshotManager.GetInstance().GetActiveSnapshot(createIfNone: false); ObservableCollection <ScanResult> newAddresses = new ObservableCollection <ScanResult>(); if (snapshot == null) { this.addresses = newAddresses; this.RaisePropertyChanged(nameof(this.Addresses)); return; } UInt64 startIndex = Math.Min(ScanResultsViewModel.PageSize * this.CurrentPage, snapshot.ElementCount); UInt64 endIndex = Math.Min((ScanResultsViewModel.PageSize * this.CurrentPage) + ScanResultsViewModel.PageSize, snapshot.ElementCount); for (UInt64 index = startIndex; index < endIndex; index++) { SnapshotElementIterator element = snapshot[index]; String label = String.Empty; if (element.GetElementLabel() != null) { label = element.GetElementLabel().ToString(); } String currentValue = String.Empty; if (element.HasCurrentValue()) { currentValue = element.GetCurrentValue().ToString(); } String previousValue = String.Empty; if (element.HasPreviousValue()) { previousValue = element.GetPreviousValue().ToString(); } newAddresses.Add(new ScanResult(element.BaseAddress, currentValue, previousValue, label)); } this.addresses = newAddresses; this.RaisePropertyChanged(nameof(this.Addresses)); // Ensure results are visible this.IsVisible = true; this.IsSelected = true; this.IsActive = true; }
/// <summary> /// Called when the scan updates. /// </summary> /// <param name="cancellationToken">The cancellation token for handling canceled tasks.</param> protected override void OnUpdate(CancellationToken cancellationToken) { Int32 processedRegions = 0; Boolean isProcess32Bit = EngineCore.GetInstance().Processes.IsOpenedProcess32Bit(); // Create the base snapshot from the loaded modules IEnumerable <SnapshotRegion> regions = EngineCore.GetInstance().VirtualMemory.GetModules().Select(region => new SnapshotRegion(region)); Snapshot moduleSnapshot = new Snapshot(regions); // Process the allowed amount of chunks from the priority queue Parallel.ForEach( this.Snapshot.Cast <SnapshotRegion>(), SettingsViewModel.GetInstance().ParallelSettingsFullCpu, (region) => { if (region.CurrentValues == null || region.CurrentValues.Length <= 0) { return; } if (isProcess32Bit) { for (IEnumerator <SnapshotElementIterator> enumerator = region.IterateElements(PointerIncrementMode.CurrentOnly); enumerator.MoveNext();) { SnapshotElementIterator element = enumerator.Current; UInt32 value = unchecked ((UInt32)element.GetCurrentValue()); // Enforce 4-byte alignment of destination, and filter out small (invalid) pointers if (value < UInt16.MaxValue || value % sizeof(UInt32) != 0) { continue; } // Check if it is possible that this pointer is valid, if so keep it if (this.Snapshot.ContainsAddress(value)) { if (moduleSnapshot.ContainsAddress(value)) { this.ModulePointers[element.BaseAddress.ToUInt64()] = value; } else { this.HeapPointers[element.BaseAddress.ToUInt64()] = value; } } } } else { for (IEnumerator <SnapshotElementIterator> enumerator = region.IterateElements(PointerIncrementMode.CurrentOnly); enumerator.MoveNext();) { SnapshotElementIterator element = enumerator.Current; UInt64 value = unchecked ((UInt64)element.GetCurrentValue()); // Enforce 8-byte alignment of destination, and filter out small (invalid) pointers if (value < UInt16.MaxValue || value % sizeof(UInt64) != 0) { continue; } // Check if it is possible that this pointer is valid, if so keep it if (this.Snapshot.ContainsAddress(value)) { if (moduleSnapshot.ContainsAddress(value)) { this.ModulePointers[element.BaseAddress.ToUInt64()] = value; } else { this.HeapPointers[element.BaseAddress.ToUInt64()] = value; } } } } // Clear the saved values, we do not need them now region.SetCurrentValues(null); lock (this.ProgressLock) { processedRegions++; // Limit how often we update the progress if (processedRegions % 10 == 0) { this.UpdateProgress(processedRegions, this.Snapshot.RegionCount, canFinalize: false); } } }); }