Search code examples
c#memoryoffsetradixreadprocessmemory

Calculate memory address c#


How do I find the new memory address in C# using my static address and offset.

base: 0x1023469C

offset: 1E8

I tried just adding the offset to the base inside of the readprocessmemory function but that didn't work at all :( I am trying to read memory from this address as I am programming a little tool which will play a sound if my health in justcause 2 gets to low. thanks for your help in advance :D

This is what I got so far:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace WindowsFormsApplication4
{
public partial class Form1 : Form
{
    //variabeln JC2
    //Pointer
    const int Offset = 0x1E8; // offset
    const int Base = 0x1023469C; // base
    const string Game = "The Game you don't know"; //Name

   

    //permission to read process memory
    const int PROCESS_WM_READ = 0x0010; //needed for reading memory


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

    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool ReadProcessMemory(
    IntPtr hProcess,
    IntPtr lpBaseAddress,
    [Out] byte[] lpBuffer,
    int dwSize,
    out int lpNumberOfBytesRead);


    public Form1()
    {
        InitializeComponent();
    }

    private void BTcheck_Click(object sender, EventArgs e)
    {
        if (Process.GetProcessesByName(Game).Length > 0)
        {
            Process process = Process.GetProcessesByName(Game)[0];
            IntPtr procHandle = OpenProcess(PROCESS_WM_READ, false, process.Id);

            IntPtr baseAddress = new IntPtr(Base); //whatever address you wish
            int offset = Offset; //whatever offset you wish
            baseAddress += offset;
            byte[] buffer = new byte[sizeof(int)]; //select a proper buffer size
            int read = -1;

            ReadProcessMemory(procHandle, baseAddress, buffer, buffer.Length, out read); 

                            if (read == buffer.Length)
            {
                int value = BitConverter.ToInt32(buffer, 0);
                //do something with it
                
                LBcurrent.Text = Convert.ToString(value); //display the value
            }
        }

        else
        { LBcurrent.Text = "Error!"; }
    }
}
}

Solution

  • Here's how you do it (tested):

    For the function import:

    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool ReadProcessMemory(
    IntPtr hProcess,
    IntPtr lpBaseAddress,
    [Out] byte[] lpBuffer,
    int dwSize,
    out int lpNumberOfBytesRead);
    

    For using it:

    IntPtr procHandle = Process.GetCurrentProcess().Handle;
    IntPtr baseAddress = new IntPtr(0x027EF131); //whatever address you wish
    int offset = 0x100; //whatever offset you wish
    baseAddress += offset;
    byte[] buffer = new byte[sizeof(int)];
    int read = -1;
    
    ReadProcessMemory(procHandle, baseAddress, buffer, buffer.Length, out read);
    
    if (read == buffer.Length)
    {
        int value = BitConverter.ToInt32(buffer, 0);
        //do something with it
    }
    

    EDIT: I've assumed you were trying to read from the current process memory, hence the procHandle = Process.GetCurrentProcess().Handle; part. Feel free to change that handle to whatever process handle you require and have permissions to.

    EDIT: I've edited the answer for reading 32-bit integet values. For 64 bit, use sizeof(long) for the buffer size and BitConverter.ToInt64.