1

So I have been trying to read variables with ReadProcessMemory and finding the adresses in cheat engine worked perfectly, but as soon as I got to programming I encountered some problems. I searched for the ammo and health addresses in cheat engine and the health was a one level pointer and the ammo was a three level pointer. I tried reading the health, but everytime I read it, it returns 0.

namespace AssaultCubeTrainer

{

public partial class MainWindow : Window
{

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern bool ReadProcessMemory(IntPtr pHandle, IntPtr Address, byte[] Buffer, int Size, IntPtr NumberofBytesRead);

    public static Process myProc;

    public static Player p1;

    public MainWindow()
    {
        InitializeComponent();

        p1  = new Player();

        MessageBox.Show("Please press the attach button as soon as the game has started", " Information",MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK);



    }

    private void AttachProcButton_Click(object sender, RoutedEventArgs e)
    {

        try
        {
            myProc = Process.GetProcessesByName("ac_client")[0];


            if (myProc.Handle != null)
            {
                MessageBox.Show("Process successfully attached", "Success", MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK);
            }
        }

        catch
        {
            MessageBox.Show("The process was not found","Error", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
        }

    }

    private void ButtonTest_Click(object sender, RoutedEventArgs e)
    {

            lbHealthInfo.Content = p1.GetHealthInfo();

    }
}

}

namespace AssaultCubeTrainer
{
    public class Player
{

    private byte[] buffer;

    public bool ReadSuccess;

    public int HealthAddress;
    public int HealthOffset;

    public int AmmoAddress;
    public int AmmoOffset;

    public int Health;
    public int Ammo;

    public IntPtr bytesRead;

    public Player()
    {
        HealthAddress = 0x00509B74;
        HealthOffset = 0xF8;

        AmmoAddress = 0x00509B74;
        AmmoOffset = 0x374;

        Health = HealthAddress + HealthOffset;
        Ammo = AmmoAddress + AmmoOffset;

    }


//Here I have the problem when reading variable
public int GetHealthInfo()
        {
            **buffer = new byte[4];
            ReadSuccess = MainWindow.ReadProcessMemory(MainWindow.myProc.Handle, (IntPtr)Health, buffer, buffer.Length, bytesRead);
            return BitConverter.ToInt32(buffer, 0);**


    }
}

}

Heres the links to the addresses in cheat engine Couldnt upload them here :P

http://prntscr.com/gp1ko0

http://prntscr.com/gp1ksu

How do I use pointers and offsets from cheat engine properly in my code and how do I implement multi-level pointers into my code? Please excuse my shitty english.

1
  • I'm afraid you need to open process using OpenProcess API - check this. Commented Sep 26, 2017 at 17:05

1 Answer 1

2

ReadProcessMemory(MainWindow.myProc.Handle, ...)

hProcess [in]
A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process.

To get this handle, you need to use OpenProcess:

[DllImport("kernel32", SetLastError = true)]
public static extern IntPtr OpenProcess(
            int dwDesiredAccess,
            IntPtr bInheritHandle,
            IntPtr dwProcessId
            );
public const int PROCESS_VM_READ = 0x10;

var handle = OpenProcess(PROCESS_VM_READ, IntPtr.Zero, new IntPtr(MainWindow.myProc.Id)); // note: use the id
ReadProcessMemory(handle, ...);

EDIT: Also make sure your application runs on elevated privileges, which means you should start VStudio or your application with Run as Admin.

EDIT2: You should use ref for the lpBuffer to avoid stepping into unsafe territory:

    [DllImport("kernel32", SetLastError = true)]
    public static extern int ReadProcessMemory(
        IntPtr hProcess,
        int lpBase,
        ref int lpBuffer,
        int nSize,
        int lpNumberOfBytesRead
        );

As for multi-level pointers, you read the value of base address, and add the offset and read again and again.

ReadProcessMemory(handle, BaseAddress, ref value, sizeof(int), 0);
ReadProcessMemory(handle, value + 0x508, ref value, sizeof(int), 0);
ReadProcessMemory(handle, value + 0xF8, ref value, sizeof(int), 0);

Or, you could use my Pointer class in Xy.DataAnalysis. Usage example can be found in Xy.PerfectWorld.Models: https://github.com/Xiaoy312/Xy.PerfectWorld/tree/master/Xy.DataAnalysis

Sign up to request clarification or add additional context in comments.

9 Comments

I edited my code and ran the application as an admin, but still I read 0.
Is ReadSuccess true, if so your address is wrong. If not call GetLastError and check the error code
Ok ReadSuccess is true so that means my address is wrong?
Yes, test the address that you are actually reading in CE and check if it is 0. Unless you are using a multi-pointer with a static base address, every time the game restart or even when the match restarts, map changes, the address will change.
the pointers definitly work in cheat and they are static, but the health pointer is just a one level pointer.
|