Как получить адрес другой памяти программы, а затем прочитать его в моей программе

#c# #memory #reverse-engineering

#c# #память #обратный инжиниринг

Вопрос:

Я бы хотел найти адрес, где другая program ( other.exe ) хранит какое-то определенное значение

а затем прочитать его из моей программы (C #), но я не совсем понимаю, как я могу этого добиться

Я попытался найти его с помощью CheatEngine, и мне удалось найти это значение по двум адресам, например 0x048907B0

введите описание изображения здесь

Теперь я попытался добавить этот конкретный адрес к базовому адресу процесса, но возвращаемое значение — это просто хаос, ничто даже близко к моему значению

Что я здесь делаю не так?

Ранее я видел какой-то «проверенный» подход, в котором использовался «xor», в основном вам нужно было прочитать некоторое значение «xor» с известным «адресом xor», а затем, чтобы прочитать другие значения, формула была

 info.MyValue = BitConverter.ToInt32(buffer, 0) ^ xor;
  

Заранее спасибо!

Мой код:

 var process = Process.GetProcessesByName(processName).FirstOrDefault();

if (process == null)
{
    throw new Exception($"Process with name: '{processName}' is not running");
}

var mc = new MemoryContext(process);
  

 public class MemoryContext
{
    const int PROCESS_WM_READ = 0x0010;

    [DllImport("kernel32.dll")]
    public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);

    [DllImport("kernel32.dll")]
    public static extern bool ReadProcessMemory(int hProcess, int lpBaseAddress, byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesRead);

    private int baseAddress;
    private Process _process;
    private IntPtr handle;

    public MemoryContext(Process process)
    {
        _process = process;
        baseAddress = _process.MainModule.BaseAddress.ToInt32();
        handle = OpenProcess(PROCESS_WM_READ, false, _process.Id);
    }
    
    public ProcessDetails RefreshData()
    {
        var info = new ProcessDetails();

        int bytesRead = 0;
        byte[] buffer = new byte[4];

        // here I'm trying to read that value
        ReadProcessMemory((int)handle, 0x048907B0   baseAddress, buffer, buffer.Length, ref bytesRead);
        info.MyValue = BitConverter.ToInt32(buffer, 0);
        
        return info;
    }
}
  

Комментарии:

1. Это значение не нужно добавлять к базовому адресу; работает ли это иначе? Что касается поиска адреса каждый раз, если вы будете следовать руководствам Cheat Engine, он должен показать вам, как найти надежную цепочку указателей на адрес некоторых динамически распределяемых данных. Затем вам просто нужно выполнить логику указателя в вашей программе, чтобы получить конечный адрес.

2. @RandomDavis Мне удалось найти его в CE, но что вы на самом деле подразумеваете под «логикой указателей»?

3. О, я удалил baseAddress и получил значение, спасибо!

4. Под «логикой указателя» я подразумеваю весь процесс, начиная со статического адреса, который является указателем, затем следуя некоторой цепочке указателей и смещений, чтобы получить конечный адрес. Если это все для вас ново, тогда обязательно ознакомьтесь с руководством и еще немного изучите указатели. Таким образом, вам не придется каждый раз запускать Cheat Engine, чтобы получить адреса.

Ответ №1:

Я опубликовал это как комментарий, но поскольку это сработало, я опубликую его в качестве ответа.

Когда вы находите адрес своих данных в Cheat Engine, адрес, который он вам дает, уже правильный. Итак, чтобы прочитать правильный адрес, вместо 0x048907B0 baseAddress этого вы можете просто ввести, 0x048907B0 и он должен работать.