public static uint GetTypeLength(MemoryScanner.SCAN_TYPE type)
        {
            switch (type)
            {
            case MemoryScanner.SCAN_TYPE.BYTE:
                return(1);

            case MemoryScanner.SCAN_TYPE.SHORT:
                return(2);

            case MemoryScanner.SCAN_TYPE.INTEGER:
                return(4);

            case MemoryScanner.SCAN_TYPE.LONG:
                return(8);

            case MemoryScanner.SCAN_TYPE.FLOAT:
                return(4);

            case MemoryScanner.SCAN_TYPE.DOUBLE:
                return(8);

            default:
                return(0);
            }
        }
        public static MemoryScanner.SCAN_TYPE StringToType(string str)
        {
            MemoryScanner.SCAN_TYPE scanType = MemoryScanner.SCAN_TYPE.BYTE;
            string upper = str.ToUpper();

            if (!(upper == "BYTE"))
            {
                if (!(upper == "SHORT"))
                {
                    if (!(upper == "INTEGER"))
                    {
                        if (!(upper == "LONG"))
                        {
                            if (!(upper == "FLOAT"))
                            {
                                if (upper == "DOUBLE")
                                {
                                    scanType = MemoryScanner.SCAN_TYPE.DOUBLE;
                                }
                            }
                            else
                            {
                                scanType = MemoryScanner.SCAN_TYPE.FLOAT;
                            }
                        }
                        else
                        {
                            scanType = MemoryScanner.SCAN_TYPE.LONG;
                        }
                    }
                    else
                    {
                        scanType = MemoryScanner.SCAN_TYPE.INTEGER;
                    }
                }
                else
                {
                    scanType = MemoryScanner.SCAN_TYPE.SHORT;
                }
            }
            else
            {
                scanType = MemoryScanner.SCAN_TYPE.BYTE;
            }

            return(scanType);
        }
        private void NewScanButton_Click(object sender, EventArgs e)
        {
            this.TabControl.SelectedIndex = 2;
            this.ScanHistoryListBox.Items.Clear();
            this.ScanHistoryListBox.Items.Add((object)(this.ValueTextBox.Text + " " + this.ScanTypeComboBox.Text.ToLower()));
            this.ScanDataGridView.Rows.Clear();
            MemoryScanner.SCAN_TYPE type = MemoryScanner.StringToType(this.ScanTypeComboBox.Text);
            string str = MemoryScanner.TypeToString(type);

            byte[] numArray = (byte[])null;

            if (isSearchValueInvalid(type))
            {
                return;
            }

            Task.Factory.StartNew(() => searchMemeoryForValue(type, numArray, str));
        }
        public static Dictionary <ulong, byte[]> ScanMemory(
            ulong address,
            byte[] data,
            MemoryScanner.SCAN_TYPE type,
            byte[] value,
            MemoryScanner.CompareFunction cfunc)
        {
            uint typeLength = MemoryScanner.GetTypeLength(type);
            Dictionary <ulong, byte[]> resultsDictionary = new Dictionary <ulong, byte[]>();
            uint lastReadableMemoryAddress = (uint)data.Length - (typeLength + 1);  // Last memory address you can read out of this buffer without causing an exception.

            uint flooredSegmentLength = (uint)Math.Floor((decimal)data.Length / ThreadCount);
            bool useDefaultSearch     = flooredSegmentLength < typeLength;

            // Default search
            if (useDefaultSearch)
            {
                for (uint index = 0; index < (uint)data.Length - typeLength; ++index)
                {
                    byte[] v1 = new byte[(int)typeLength];
                    Array.Copy((Array)data, (long)index, (Array)v1, 0L, (long)typeLength);
                    if (cfunc(v1, value, type))
                    {
                        resultsDictionary.Add(address + (ulong)index, value);
                    }

                    DebugWatchForm.Singleton.ScanProgressBar.Invoke((p) => p.Increment(1));
                }
                return(resultsDictionary);
            }


            // If the memory address is too small, search synchronously.
            var myThreadCount = 0;

            void GetMatches(ref byte[] memorySection, uint startIndex, uint lastIndexToRead, int threadCount)
            {
                Debug.WriteLine($"Start Index: {startIndex}; Last Index: {lastIndexToRead}; Thread Count: {threadCount}; MemorySectionLength: {memorySection.LongLength}");
                Dictionary <ulong, byte[]> tempDictionary = new Dictionary <ulong, byte[]>();

                byte[] tempBuffer = new byte[(int)typeLength];
                for (uint currentIndex = startIndex; currentIndex <= lastIndexToRead - (long)typeLength; currentIndex++)
                {
                    Array.Clear(tempBuffer, 0, tempBuffer.Length); // Zero out array
                    Array.Copy((Array)memorySection, (long)currentIndex, (Array)tempBuffer, 0L, (long)typeLength);
                    if (cfunc(tempBuffer, value, type))
                    {
                        tempDictionary.Add(address + (ulong)currentIndex, value);
                    }
                }

                // Add matched results to the dictionary
                lock (resultsDictionary)
                {
                    foreach (var keyValuePair in tempDictionary)
                    {
                        resultsDictionary.Add(keyValuePair.Key, keyValuePair.Value);
                    }
                    // Update progress UI
                    DebugWatchForm.Singleton.ScanProgressBar.Invoke((p) => p.Increment(1));
                }
            }

            // Use multi-threading for search larger memory sections
            Task[] comparisonTasks = new Task[ThreadCount];
            for (int i = 0; i < ThreadCount - 1; i++)
            {
                uint startIndex = (uint)(i * flooredSegmentLength);
                uint lastIndex  = (uint)((i + 1) * flooredSegmentLength) - 1;
                Debug.WriteLine("Creating Task");
                comparisonTasks[i] = new Task(() => GetMatches(ref data, startIndex, lastIndex, myThreadCount++));
            }
            // Special case for the last thread
            uint lastStartIndex = (uint)((ThreadCount - 1) * flooredSegmentLength);

            Debug.WriteLine($"Last Start Index: {lastStartIndex}; Last Index: {data.Length}; Thread Count: {myThreadCount};");
            comparisonTasks[ThreadCount - 1] = new Task(() => GetMatches(ref data, lastStartIndex, lastReadableMemoryAddress, myThreadCount++));

            // Run all tasks
            foreach (var comparisonTask in comparisonTasks)
            {
                comparisonTask.Start();
            }
            Task.WaitAll(comparisonTasks);
            return(resultsDictionary);
        }
 public static bool CompareGreaterThan(byte[] v1, byte[] v2, MemoryScanner.SCAN_TYPE type)
 {
     return(((IEnumerable <byte>)v1).SequenceEqual <byte>((IEnumerable <byte>)v2));
 }
        private void recheckSavedValues()
        {
            List <string[]> strArrayList = new List <string[]>();

            this.ScanProgressBar.Invoke(s => s.Maximum = this.ScanDataGridView.Rows.Count);
            this.ScanProgressBar.Invoke(s => s.Value   = 0);

            foreach (DataGridViewRow row in (IEnumerable)this.ScanDataGridView.Rows)
            {
                ulong uint64 = Convert.ToUInt64(row.Cells[0].Value.ToString().Replace("0x", ""), 16);
                MemoryScanner.SCAN_TYPE type = MemoryScanner.StringToType(row.Cells[1].Value.ToString());
                bool flag = false;
                switch (type)
                {
                case MemoryScanner.SCAN_TYPE.BYTE:
                    if ((int)this.ps4.ReadMemory(this.attachpid, uint64, 1)[0] ==
                        (int)Convert.ToByte(this.ValueTextBox.Text))
                    {
                        flag = true;
                        break;
                    }

                    break;

                case MemoryScanner.SCAN_TYPE.SHORT:
                    if ((int)BitConverter.ToInt16(this.ps4.ReadMemory(this.attachpid, uint64, 2), 0) ==
                        (int)Convert.ToUInt16(this.ValueTextBox.Text))
                    {
                        flag = true;
                        break;
                    }

                    break;

                case MemoryScanner.SCAN_TYPE.INTEGER:
                    if ((int)BitConverter.ToInt32(this.ps4.ReadMemory(this.attachpid, uint64, 4), 0) ==
                        (int)Convert.ToUInt32(this.ValueTextBox.Text))
                    {
                        flag = true;
                        break;
                    }

                    break;

                case MemoryScanner.SCAN_TYPE.LONG:
                    if ((long)BitConverter.ToInt64(this.ps4.ReadMemory(this.attachpid, uint64, 8), 0) ==
                        (long)Convert.ToUInt64(this.ValueTextBox.Text))
                    {
                        flag = true;
                        break;
                    }

                    break;

                case MemoryScanner.SCAN_TYPE.FLOAT:
                    if (BitConverter.ToSingle(ps4.ReadMemory(this.attachpid, uint64, 4), 0) ==
                        (double)Convert.ToSingle(this.ValueTextBox.Text))
                    {
                        flag = true;
                        break;
                    }

                    break;

                case MemoryScanner.SCAN_TYPE.DOUBLE:
                    if (BitConverter.ToDouble(this.ps4.ReadMemory(this.attachpid, uint64, 8), 0) ==
                        Convert.ToDouble(this.ValueTextBox.Text))
                    {
                        flag = true;
                        break;
                    }

                    break;
                }

                if (flag)
                {
                    string[] strArray = new string[3]
                    {
                        row.Cells[0].Value.ToString(),
                        row.Cells[1].Value.ToString(),
                        this.ValueTextBox.Text
                    };
                    strArrayList.Add(strArray);
                }

                this.ScanProgressBar.Invoke(s => s.Increment(1));
            }

            this.ScanDataGridView.Invoke(s => s.Rows.Clear());
            foreach (string[] strArray in strArrayList)
            {
                this.ScanDataGridView.Invoke(s => s.Rows.Add((object)strArray[0], (object)strArray[1], (object)strArray[2]));
            }
            this.ScanProgressBar.Invoke(s => s.Value = 0);
            reEnableInterfaceAfterDoneSearching();
        }
        private bool isSearchValueInvalid(MemoryScanner.SCAN_TYPE type)
        {
            // Validate the text entered before we go any further
            // First, check the integer isn't too small for the type and make note of what type we're searching for
            UInt64 maxValueInt    = 0;
            double maxValueDouble = 0.0;
            bool   isIntType      = true;

            switch (type)
            {
            case MemoryScanner.SCAN_TYPE.BYTE:
                maxValueInt = Byte.MaxValue;
                break;

            case MemoryScanner.SCAN_TYPE.SHORT:
                maxValueInt = UInt16.MaxValue;
                break;

            case MemoryScanner.SCAN_TYPE.INTEGER:
                maxValueInt = UInt32.MaxValue;
                break;

            case MemoryScanner.SCAN_TYPE.LONG:
                maxValueInt = UInt64.MaxValue;
                break;

            case MemoryScanner.SCAN_TYPE.FLOAT:
                isIntType      = false;
                maxValueDouble = float.MaxValue;
                break;

            case MemoryScanner.SCAN_TYPE.DOUBLE:
                isIntType      = false;
                maxValueDouble = double.MaxValue;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            // Check if we can parse the value
            ulong searchValueAsInt    = 0;
            var   searchValueAsDouble = 0.0;

            if ((isIntType && !UInt64.TryParse(this.ValueTextBox.Text, out searchValueAsInt)) ||
                (!isIntType && !double.TryParse(this.ValueTextBox.Text, out searchValueAsDouble)))
            {
                MessageBox.Show("Value entered could not be parsed.", "Parse Error", MessageBoxButtons.OK,
                                MessageBoxIcon.Warning);
                return(true);
            }

            // Check the value isn't too big
            if (isIntType ? maxValueInt < searchValueAsInt : maxValueDouble < searchValueAsDouble)
            {
                MessageBox.Show("Value entered was too large for the specified type.", "Value Too Large", MessageBoxButtons.OK,
                                MessageBoxIcon.Warning);
                return(true);
            }

            return(false);
        }
        private void searchMemeoryForValue(MemoryScanner.SCAN_TYPE type, byte[] numArray, string str)
        {
            this.disableInterfaceWhileSearching();

            switch (type)
            {
            case MemoryScanner.SCAN_TYPE.BYTE:
                numArray = new byte[1]
                {
                    Convert.ToByte(this.ValueTextBox.Text)
                };
                break;

            case MemoryScanner.SCAN_TYPE.SHORT:
                numArray = BitConverter.GetBytes(Convert.ToUInt16(this.ValueTextBox.Text));
                break;

            case MemoryScanner.SCAN_TYPE.INTEGER:
                numArray = BitConverter.GetBytes(Convert.ToUInt32(this.ValueTextBox.Text));
                break;

            case MemoryScanner.SCAN_TYPE.LONG:
                numArray = BitConverter.GetBytes(Convert.ToUInt64(this.ValueTextBox.Text));
                break;

            case MemoryScanner.SCAN_TYPE.FLOAT:
                numArray = BitConverter.GetBytes(Convert.ToSingle(this.ValueTextBox.Text));
                break;

            case MemoryScanner.SCAN_TYPE.DOUBLE:
                numArray = BitConverter.GetBytes(Convert.ToDouble(this.ValueTextBox.Text));
                break;
            }

            var memoryEntriesToSearchThrough = this.mapview.GetSelectedEntries();

            this.ScanProgressBar.Invoke((p) => p.Minimum = 0);
            this.ScanProgressBar.Invoke((p) => p.Maximum = memoryEntriesToSearchThrough.Length);
            this.ScanProgressBar.Invoke((p) => p.Value   = 0);
            foreach (MemoryEntry selectedEntry in memoryEntriesToSearchThrough)
            {
                byte[] data = this.ps4.ReadMemory(this.attachpid,
                                                  selectedEntry.start,
                                                  (int)((long)selectedEntry.end - (long)selectedEntry.start));
                if (data != null && data.Length != 0)
                {
                    // Get the numeral value of the memory segment and returns it as a string.
                    string ConvertMemorySegmentToValue(byte[] memorySegment, MemoryScanner.SCAN_TYPE scanType)
                    {
                        switch (scanType)
                        {
                        case MemoryScanner.SCAN_TYPE.BYTE:
                            return(memorySegment[0].ToString());

                        case MemoryScanner.SCAN_TYPE.SHORT:
                            return(BitConverter.ToInt16(memorySegment, 0).ToString());

                        case MemoryScanner.SCAN_TYPE.INTEGER:
                            return(BitConverter.ToInt32(memorySegment, 0).ToString());

                        case MemoryScanner.SCAN_TYPE.LONG:
                            return(BitConverter.ToInt64(memorySegment, 0).ToString());

                        case MemoryScanner.SCAN_TYPE.FLOAT:
                            return(BitConverter.ToSingle(memorySegment, 0).ToString());

                        case MemoryScanner.SCAN_TYPE.DOUBLE:
                            return(BitConverter.ToDouble(memorySegment, 0).ToString());

                        default:
                            throw new ArgumentOutOfRangeException(nameof(scanType), scanType, null);
                        }
                    }

                    foreach (KeyValuePair <ulong, byte[]> keyValuePair in MemoryScanner.ScanMemory(selectedEntry.start, data, type, numArray, new MemoryScanner.CompareFunction(MemoryScanner.CompareEqual)))
                    {
                        this.ScanDataGridView.Invoke((gridview) => gridview.Rows.Add((object)("0x" + keyValuePair.Key.ToString("X")), (object)str,
                                                                                     ConvertMemorySegmentToValue(keyValuePair.Value, type)));
                    }

                    GC.Collect();
                }
            }

            this.reEnableInterfaceAfterDoneSearching();
            this.ScanProgressBar.Invoke((p) => p.Value  = 0);
            this.NextScanButton.Invoke((b) => b.Enabled = true);
        }