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.

Celmos
  • 25
  • 1
  • 1
  • 7
  • I'm afraid you need to open process using `OpenProcess` API - check [this](https://stackoverflow.com/questions/34467311/c-sharp-readprocessmemory-how-to-read-a-64-bit-memory-address). – vasek Sep 26 '17 at 17:05

1 Answers1

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

Xiaoy312
  • 14,292
  • 1
  • 32
  • 44
  • I edited my code and ran the application as an admin, but still I read 0. – Celmos Sep 26 '17 at 17:28
  • Is `ReadSuccess` true, if so your address is wrong. If not call [`GetLastError`](https://msdn.microsoft.com/en-ca/library/windows/desktop/ms679360(v=vs.85).aspx) and check the error code – Xiaoy312 Sep 26 '17 at 17:32
  • Ok ReadSuccess is true so that means my address is wrong? – Celmos Sep 26 '17 at 18:10
  • 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. – Xiaoy312 Sep 26 '17 at 18:24
  • the pointers definitly work in cheat and they are static, but the health pointer is just a one level pointer. – Celmos Sep 26 '17 at 18:46
  • I just copied the pointers and offsets I had in ce directly to visual studio. Is that wrong? – Celmos Sep 26 '17 at 18:48
  • Ok now I tried to use the address from cheat engine instead of the pointer and now I get an access violation exeption – Celmos Sep 26 '17 at 19:20
  • Ok I tried out your code and I got an error and it says that only a part of readprocessmemory was completed. – Celmos Sep 27 '17 at 18:00
  • Never seen that issue before. However, a quick google seems to suggest that it is related to process architecture, like accessing x64 process from x32 or vice versa. Try to build your project on the same architecture as the targeting process. – Xiaoy312 Sep 27 '17 at 18:41