I'm writing a memory scanner in C#. It's able to find strings, but not numerical values. How can I enhance it to find addresses with numbers in them?
Edit: I give my app a specific number or string to search for within the memory of a running process. I want开发者_JS百科 to use this to change those values later, but for now I'm just trying to figure out there the values are stored.
Edit 2: Looks like it only works on strings that are in the loaded files/modules' binaries; not values that have changed in-proc. Grrr.
public class Search
{
public Search(int pid, string value) {
SearchValues = new List<string>();
PossibleAddresses = new List<IntPtr>();
PID = pid;
DoSearch(value); }
public int PID { get; set; }
public Process getProcess { get { return Process.GetProcessById(PID); } }
public List<string> SearchValues { get; private set; }
public List<IntPtr> PossibleAddresses { get; private set; }
public bool hasLockedOn { get; set; }
private IntPtr processPointer { get; set; }
public void DoSearch(string value)
{
SearchValues.Add(value);
IntPtr baseAddress, lastAddress;
Process process = getProcess;
baseAddress = process.MainModule.BaseAddress;
lastAddress = baseAddress + process.MainModule.ModuleMemorySize;
processPointer = OpenProcess((uint)(0x0010), 1, (uint)PID);
int iVal;
double dVal;
int.TryParse(value, out iVal);
double.TryParse(value, out dVal);
if (SearchValues.Count == 1) // new searches
for (int addr = (int)baseAddress; addr + value.Length < (int)lastAddress; addr++)
{
// Match numbers
if (dVal > 0 && MemoryContainsNumber((IntPtr)addr, dVal, ((IntPtr)addr)))
PossibleAddresses.Add((IntPtr)addr);
else if (iVal > 0 && MemoryContainsNumber((IntPtr)addr, iVal, ((IntPtr)addr)))
PossibleAddresses.Add((IntPtr)addr);
// Match strings
else if (ReadMemory((IntPtr)addr, (uint)value.Length, (IntPtr)addr).Trim().ToLower() == value.Trim().ToLower())
PossibleAddresses.Add((IntPtr)addr);
}
else { // TODO: Existing searches
}
hasLockedOn = PossibleAddresses.Count == 1;
CloseHandle(processPointer);
}
private string ReadMemory(IntPtr memAddress, uint size, IntPtr BaseAddress)
{
byte[] buffer = new byte[size];
IntPtr bytesRead;
unsafe
{
ReadProcessMemory(processPointer, BaseAddress, buffer, size, out bytesRead);
return Encoding.Default.GetString(buffer);
//string result = "";
//foreach (string c in BitConverter.ToString(buffer).Split('-'))
// result += char.ConvertFromUtf32(Int32.Parse(c, System.Globalization.NumberStyles.HexNumber));
//return result;
}
}
private bool MemoryContainsNumber(IntPtr memAddress, int number, IntPtr BaseAddress)
{
byte[] numberBytes = BitConverter.GetBytes(number);
byte[] buffer = new byte[numberBytes.Length];
IntPtr bytesRead;
unsafe { ReadProcessMemory(processPointer, BaseAddress, buffer, (uint)numberBytes.Length, out bytesRead); }
for (int i = 0; i < buffer.Length; i++)
if (buffer[i] != numberBytes[i])
return false;
return true;
}
private bool MemoryContainsNumber(IntPtr memAddress, double number, IntPtr BaseAddress)
{
byte[] numberBytes = BitConverter.GetBytes(number);
byte[] buffer = new byte[numberBytes.Length];
IntPtr bytesRead;
unsafe { ReadProcessMemory(processPointer, BaseAddress, buffer, (uint)numberBytes.Length, out bytesRead); }
for (int i = 0; i < buffer.Length; i++)
if (buffer[i] != numberBytes[i])
return false;
return true;
}
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(UInt32 dwDesiredAccess, Int32 bInheritHandle, UInt32 dwProcessId);
[DllImport("kernel32.dll")]
public static extern Int32 CloseHandle(IntPtr hObject);
[DllImport("kernel32.dll")]
public static extern Int32 ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesRead);
[DllImport("kernel32.dll")]
public static extern Int32 WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesWritten);
}
Looks like it only works on strings that are in the loaded files/modules' binaries; not values that have changed in-proc. Grrr.
Therefore it's not a string vs numeric issue and this whole question is moot. Thanks for your help.
Next question in the series...
精彩评论