private void ScanDataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            DataGridView dataGridView = (DataGridView)sender;

            if (!(dataGridView.Columns[e.ColumnIndex] is DataGridViewButtonColumn) || e.RowIndex < 0)
            {
                return;
            }
            ulong uint64 = Convert.ToUInt64(dataGridView.Rows[e.RowIndex].Cells[0].Value.ToString().Trim().Replace("0x", ""),
                                            16);
            ulong typeLength =
                (ulong)MemoryScanner.GetTypeLength(dataGridView.Rows[e.RowIndex].Cells[1].ToString().Trim());

            PS4DBG.WATCHPT_LENGTH watchptLength = PS4DBG.WATCHPT_LENGTH.DBREG_DR7_LEN_1;
            switch ((long)typeLength - 1L)
            {
            case 0:
                watchptLength = PS4DBG.WATCHPT_LENGTH.DBREG_DR7_LEN_1;
                goto case 2;

            case 1:
                watchptLength = PS4DBG.WATCHPT_LENGTH.DBREG_DR7_LEN_2;
                goto case 2;

            case 2:
                this.ps4.ChangeWatchpoint((int)this.WatchpointNumericUpDown.Value, true, watchptLength,
                                          PS4DBG.WATCHPT_BREAKTYPE.DBREG_DR7_WRONLY, uint64);
                break;

            case 3:
                watchptLength = PS4DBG.WATCHPT_LENGTH.DBREG_DR7_LEN_4;
                goto case 2;

            default:
                if (typeLength == 8UL)
                {
                    watchptLength = PS4DBG.WATCHPT_LENGTH.DBREG_DR7_LEN_8;
                    goto case 2;
                }
                else
                {
                    goto case 2;
                }
            }
        }
        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 uint GetTypeLength(string type)
 {
     return(MemoryScanner.GetTypeLength(MemoryScanner.StringToType(type)));
 }
        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 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);
        }