Этот сканер памяти работает только со строками. Как я могу найти номера? - PullRequest
3 голосов
/ 05 июня 2011

Я пишу сканер памяти в C #. Он может найти строки, но не числовые значения. Как я могу улучшить его, чтобы найти адреса с номерами в них?

Редактировать: Я даю своему приложению определенный номер или строку для поиска в памяти запущенного процесса. Я хочу использовать это для изменения этих значений позже, но сейчас я просто пытаюсь выяснить, где эти значения хранятся.

Редактировать 2: Похоже, он работает только со строками, которые находятся в двоичных файлах загруженных файлов / модулей; не значения, которые изменились в-proc. Хмм.

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

1 Ответ

0 голосов
/ 05 июня 2011

Похоже, что он работает только со строками, которые находятся в двоичных файлах загруженных файлов / модулей;не значения, которые изменились в-proc.Grrr.

Следовательно, это не строка против числовой проблемы, и весь этот вопрос является спорным.Спасибо за вашу помощь.

Следующий вопрос из серии ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...