예제 #1
0
        /// <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()));
        }
예제 #2
0
 /// <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)
     {
     }
 }
예제 #3
0
파일: PointerScan.cs 프로젝트: wau/Squalr
        /// <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)));
        }
예제 #4
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>
        /// <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;
            }
        }
예제 #5
0
 private ExtractedPointer ExtractPointerFromElement(SnapshotElementIndexer element)
 {
     return(new ExtractedPointer(element.GetBaseAddress(PointerSize.ToSize()), element.HasCurrentValue()
         ? (this.PointerSize == PointerSize.Byte4 ? (UInt32)element.LoadCurrentValue(PointerSize.ToDataType())
         : (UInt64)element.LoadCurrentValue(PointerSize.ToDataType())) : 0));
 }
예제 #6
0
        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));
        }