Смещение указателя C# › 255 — ProcessMemoryReader

Я знаю, что существует множество руководств, в которых показано, как использовать функции "ProcessMemoryReader". Но эти проблемы кажутся уникальными или еще не решенными.

Довольно долго я копался в чужом коде, чтобы найти способ использовать несколько смещений. И я думал, что использование нескольких смещений было проблемой для меня, но я думаю, что это проблема с тем фактом, что мое значение смещения больше 255.

Игра, из которой я пытаюсь получить значения памяти, называется Assault Cube. Поскольку я не был уверен, что получил правильные значения смещения, я погуглил, где другие результаты. Они кажутся абсолютно одинаковыми: http://cheatengine.org/tables/moreinfo.php?tid=1142 (Вы можете просмотреть файл .ct с помощью блокнота, если у вас не установлен чит-движок.)

Вот мой код, использующий ProcessMemoryReader.cs.

private void timer1_Tick(object sender, EventArgs e)
{
int bytesread;
int pointerbase;
byte[] memory;
Process[] myprocess = Process.GetProcessesByName("ac_client");
if (myprocess.Length != 0)
{
preader.ReadProcess = myprocess[0];
preader.OpenProcess();

//Ammo
memory = preader.ReadProcessMemory((IntPtr)0x4DF73C, 4, out bytesread);
pointerbase = BitConverter.ToInt32(memory, 0);
pointerbase += 0x00; //0 // 14 // 378

byte[] memory1 = preader.ReadProcessMemory((IntPtr)pointerbase, 4, out bytesread);
int pointerbase1 = BitConverter.ToInt32(memory1, 0);
pointerbase1 += 0x14; //0 // 14 // 378

byte[] memory2 = preader.ReadProcessMemory((IntPtr)pointerbase1, 4, out bytesread);
int pointerbase2 = BitConverter.ToInt32(memory2, 0);
pointerbase2 += 0x378; //00 // 14 // 378

byte[] memory3 = preader.ReadProcessMemory((IntPtr)pointerbase2, 4, out bytesread);
int valueis = BitConverter.ToInt32(memory3, 0);
label1.Text = valueis.ToString();
}

Хотя с одним указателем процесс работает нормально, например:

 //HP
 memory = preader.ReadProcessMemory((IntPtr)0x4DF73C, 4, out bytesread);
 pointerbase = BitConverter.ToInt32(memory, 0);
 pointerbase += 0xf4;

 byte[] memory1 = preader.ReadProcessMemory((IntPtr)pointerbase, 4, out bytesread);
 int valueis = BitConverter.ToInt32(memory1, 0);
 label2.Text = valueis.ToString();

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


person Arndroid    schedule 16.04.2013    source источник
comment
ReadProcessMemory() не имеет такого ограничения. Во втором фрагменте вы читаете указатель на целое число. Это довольно просто. В 1-м фрагменте вы читаете указатель на указатель на указатель на целое число. Это не так просто. Одна маленькая ошибка, и вы будете читать мусор.   -  person Hans Passant    schedule 17.04.2013


Ответы (2)


Я не знаком с CheatEngine и его форматом таблицы, но у меня не сложилось впечатление, что он указывает на адреса памяти, которые вы используете.

Вы читаете 4 байта по адресу 0x4DF73C, который используется как новый адрес памяти для следующего чтения. Это повторяется несколько раз. По сути, вы читаете информацию с указателя на указатель на указатель. Вы уверены, что это то, что задумано?

Нет никакой причины, по которой значение смещения больше 255 может быть проблемой.

person Thorarin    schedule 18.04.2013

Используйте FindDMAAddy, чтобы пройти цепочку указателей за вас, вот рабочий пример, убедитесь, что вы работаете от имени администратора:

public static IntPtr FindDMAAddy(IntPtr hProc, IntPtr ptr, int[] offsets)
{
    var buffer = new byte[IntPtr.Size];

    foreach (int i in offsets)
    {
        ReadProcessMemory(hProc, ptr, buffer, buffer.Length, out
        var read);
        ptr = (IntPtr.Size == 4) ? IntPtr.Add(new IntPtr(BitConverter.ToInt32(buffer, 0)), i) : ptr = IntPtr.Add(new IntPtr(BitConverter.ToInt64(buffer, 0)), i);
    }
    return ptr;
}

var modBase = GetModuleBaseAddress(proc.Id, "ac_client.exe");

var ammoAddr = FindDMAAddy(hProc, (IntPtr)(modBase + 0x10f4f4), new int[] { 0x374, 0x14, 0 });

Console.WriteLine("Ammo address " + "0x" + ammoAddr.ToString("X"));

int newAmmo = 1337;

byte[] buffer = new byte[4];

ReadProcessMemory(proc.Handle, ammoAddr, buffer, 4, out _);

Console.WriteLine("Ammo value " + BitConverter.ToInt32(buffer, 0).ToString());

WriteProcessMemory(hProc, ammoAddr, newAmmo, 4, out _);
person GuidedHacking    schedule 20.04.2020