private ExtractedPointer ExtractRandomPointer(Snapshot snapshot) { SnapshotRegion extractedRegion = snapshot.SnapshotRegions[Random.Next(0, snapshot.SnapshotRegions.Length)]; SnapshotElementIndexer extractedElement = extractedRegion[Random.Next(0, extractedRegion.GetElementCount(PointerSize.ToSize()))]; return(this.ExtractPointerFromElement(extractedElement)); }
protected override void OnUpdate() { ConcurrentDictionary <dynamic, Int64> histogram = new ConcurrentDictionary <dynamic, Int64>(); Int32 processedPages = 0; lock (this.SnapshotLock) { if (this.Snapshot == null) { this.Cancel(); return; } Parallel.ForEach( this.Snapshot.Cast <Object>(), SettingsViewModel.GetInstance().ParallelSettings, (regionObject) => { SnapshotRegion region = regionObject as SnapshotRegion; if (((dynamic)region).GetElementLabels() == null || region.GetElementCount() <= 0) { return; } foreach (SnapshotElementRef element in region) { lock (this.ItemLock) { if (histogram.ContainsKey(((dynamic)element).GetElementLabel())) { histogram[((dynamic)element).GetElementLabel()]++; } else { histogram.TryAdd(((dynamic)element).GetElementLabel(), 1); } } } lock (this.ProgressLock) { processedPages++; this.UpdateProgress(processedPages, this.Snapshot.GetRegionCount()); } //// End foreach element }); //// End foreach region } this.Histogram = new SortedList <dynamic, Int64>(histogram); this.UpdateHistogram(); this.Cancel(); base.OnUpdate(); }
/// <summary> /// Gets a random pointer from the pointer collection. /// </summary> /// <returns>A random discovered pointer, or null if unable to find one.</returns> public Pointer GetRandomPointer(Int32 levelIndex) { if (levelIndex >= this.Levels.Count || this.Levels[levelIndex].StaticPointers == null) { return(null); } Snapshot currentSnapshot = this.Levels[levelIndex].StaticPointers; ExtractedPointer pointer = this.ExtractRandomPointer(currentSnapshot); UInt64 pointerBase = pointer.BaseAddress; List <Int32> offsets = new List <Int32>(); foreach (Level level in this.Levels.Take(levelIndex + 1).Reverse()) { IEnumerable <Int32> shuffledOffsets = Enumerable.Range(-(Int32)this.MaxOffset, (Int32)(this.MaxOffset * 2) + 1).Shuffle(); Boolean found = false; // Brute force all possible offsets in a random order to find the next path (this guarantees uniform path probabilities) foreach (Int32 nextRandomOffset in shuffledOffsets) { UInt64 newDestination = nextRandomOffset < 0 ? pointer.Destination.Subtract(-nextRandomOffset, wrapAround: false) : pointer.Destination.Add(nextRandomOffset, wrapAround: false); SnapshotRegion snapshotRegion = level.HeapPointers.SnapshotRegions.Select(x => x).Where(y => newDestination >= y.BaseAddress && newDestination <= y.EndAddress).FirstOrDefault(); if (snapshotRegion != null) { // We may have sampled an offset that results in a mis-aligned index, so just randomly take an element from this snapshot rather than using the random offset SnapshotElementIndexer randomElement = snapshotRegion[Random.Next(0, snapshotRegion.GetElementCount(PointerSize.ToSize()))]; UInt64 baseAddress = randomElement.GetBaseAddress(PointerSize.ToSize()); Int32 alignedOffset = pointer.Destination >= baseAddress ? -((Int32)(pointer.Destination - baseAddress)) : ((Int32)(baseAddress - pointer.Destination)); pointer = this.ExtractPointerFromElement(randomElement); offsets.Add(alignedOffset); found = true; break; } } if (!found) { Logger.Log(LogLevel.Error, "Unable to collect a pointer, encountered dead end path"); return(null); } } return(new Pointer(pointerBase, this.PointerSize, offsets.ToArray())); }