示例#1
0
        /// <summary>
        /// Gradually gathers pointers in the running process.
        /// </summary>
        private void GatherPointers()
        {
            Boolean isOpenedProcess32Bit             = EngineCore.GetInstance().Processes.IsOpenedProcess32Bit();
            dynamic invalidPointerMin                = isOpenedProcess32Bit ? (UInt32)UInt16.MaxValue : (UInt64)UInt16.MaxValue;
            dynamic invalidPointerMax                = isOpenedProcess32Bit ? Int32.MaxValue : Int64.MaxValue;
            ConcurrentHashSet <IntPtr> foundPointers = new ConcurrentHashSet <IntPtr>();

            // Test for conditions where we set the final found set and take a new snapshot to parse
            if (this.CurrentSnapshot == null || this.CurrentSnapshot.GetRegionCount() <= 0 || this.processedCount >= this.CurrentSnapshot.GetRegionCount())
            {
                this.processedCount  = 0;
                this.CurrentSnapshot = SnapshotManager.GetInstance().CollectSnapshot(useSettings: true, usePrefilter: false).Clone();
                this.FoundPointers   = this.ConstructingSet;
                this.ConstructingSet = new HashSet <IntPtr>();
            }

            List <SnapshotRegion> sortedRegions = new List <SnapshotRegion>(this.CurrentSnapshot.GetSnapshotRegions().OrderBy(x => x.GetTimeSinceLastRead()));

            // Process the allowed amount of chunks from the priority queue
            Parallel.For(
                0,
                Math.Min(sortedRegions.Count, PointerCollector.RegionLimit),
                SettingsViewModel.GetInstance().ParallelSettings,
                (index) =>
            {
                Interlocked.Increment(ref this.processedCount);

                SnapshotRegion region = sortedRegions[index];
                Boolean success;

                // Set to type of a pointer
                region.ElementType = EngineCore.GetInstance().Processes.IsOpenedProcess32Bit() ? typeof(UInt32) : typeof(UInt64);

                // Enforce 4-byte alignment of pointers
                region.Alignment = sizeof(Int32);

                // Read current page data for chunk
                region.ReadAllRegionMemory(out success);

                // Read failed; Deallocated page
                if (!success)
                {
                    return;
                }

                if (region.GetCurrentValues() == null || region.GetCurrentValues().Length <= 0)
                {
                    return;
                }

                foreach (SnapshotElementRef element in region)
                {
                    // Enforce user mode memory pointers
                    if (element.LessThanValue(invalidPointerMin) || element.GreaterThanValue(invalidPointerMax))
                    {
                        continue;
                    }

                    // Enforce 4-byte alignment of destination
                    if (element.GetCurrentValue() % 4 != 0)
                    {
                        continue;
                    }

                    IntPtr Value = new IntPtr(element.GetCurrentValue());

                    // Check if it is possible that this pointer is valid, if so keep it
                    if (this.CurrentSnapshot.ContainsAddress(Value))
                    {
                        foundPointers.Add(Value);
                    }
                }

                // Clear the saved values, we do not need them now
                region.SetCurrentValues(null);
            });

            IEnumerable <IntPtr> pointers = foundPointers.ToList();

            this.ConstructingSet.UnionWith(pointers);
            this.FoundPointers.UnionWith(pointers);
        }
        /// <summary>
        /// Called when the scan updates.
        /// </summary>
        protected override void OnUpdate()
        {
            Int32 processedPages = 0;

            // Read memory to get current values
            Parallel.ForEach(
                this.Snapshot.Cast <Object>(),
                SettingsViewModel.GetInstance().ParallelSettings,
                (regionObject) =>
            {
                SnapshotRegion region = regionObject as SnapshotRegion;
                Boolean readSuccess;

                region.ReadAllRegionMemory(out readSuccess, keepValues: true);

                if (!readSuccess)
                {
                    region.SetAllValidBits(false);
                    return;
                }

                // Ignore region if it requires current & previous values, but we cannot find them
                if (this.ScanConstraintManager.HasRelativeConstraint() && !region.CanCompare())
                {
                    region.SetAllValidBits(false);
                    return;
                }

                foreach (SnapshotElementRef element in region)
                {
                    // Enforce each value constraint on the element
                    foreach (ScanConstraint scanConstraint in this.ScanConstraintManager)
                    {
                        switch (scanConstraint.Constraint)
                        {
                        case ConstraintsEnum.Unchanged:
                            if (!element.Unchanged())
                            {
                                element.SetValid(false);
                            }

                            break;

                        case ConstraintsEnum.Changed:
                            if (!element.Changed())
                            {
                                element.SetValid(false);
                            }

                            break;

                        case ConstraintsEnum.Increased:
                            if (!element.Increased())
                            {
                                element.SetValid(false);
                            }

                            break;

                        case ConstraintsEnum.Decreased:
                            if (!element.Decreased())
                            {
                                element.SetValid(false);
                            }

                            break;

                        case ConstraintsEnum.IncreasedByX:
                            if (!element.IncreasedByValue(scanConstraint.ConstraintValue))
                            {
                                element.SetValid(false);
                            }

                            break;

                        case ConstraintsEnum.DecreasedByX:
                            if (!element.DecreasedByValue(scanConstraint.ConstraintValue))
                            {
                                element.SetValid(false);
                            }

                            break;

                        case ConstraintsEnum.Equal:
                            if (!element.EqualToValue(scanConstraint.ConstraintValue))
                            {
                                element.SetValid(false);
                            }

                            break;

                        case ConstraintsEnum.NotEqual:
                            if (!element.NotEqualToValue(scanConstraint.ConstraintValue))
                            {
                                element.SetValid(false);
                            }

                            break;

                        case ConstraintsEnum.GreaterThan:
                            if (!element.GreaterThanValue(scanConstraint.ConstraintValue))
                            {
                                element.SetValid(false);
                            }

                            break;

                        case ConstraintsEnum.GreaterThanOrEqual:
                            if (!element.GreaterThanOrEqualToValue(scanConstraint.ConstraintValue))
                            {
                                element.SetValid(false);
                            }

                            break;

                        case ConstraintsEnum.LessThan:
                            if (!element.LessThanValue(scanConstraint.ConstraintValue))
                            {
                                element.SetValid(false);
                            }

                            break;

                        case ConstraintsEnum.LessThanOrEqual:
                            if (!element.LessThanOrEqualToValue(scanConstraint.ConstraintValue))
                            {
                                element.SetValid(false);
                            }

                            break;

                        case ConstraintsEnum.NotScientificNotation:
                            if (element.IsScientificNotation())
                            {
                                element.SetValid(false);
                            }

                            break;
                        }
                    }
                    //// End foreach Constraint
                }
                //// End foreach Element

                lock (this.ProgressLock)
                {
                    processedPages++;
                    this.UpdateProgress(processedPages, this.Snapshot.GetRegionCount());
                }
            });
            //// End foreach Region

            base.OnUpdate();
        }