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; } } }
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))); }