开发者

This memory scanner only work on strings. How can I find numbers?

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...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜