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