6

I am getting into reading application memory. I am using CheatEngine to get a memory address and then trying to return it's value. However, CheatEngine seems to be returning 64 bit memory addresses and so my ReadProcessMemory function keeps on telling me that it cannot convert a 'long' to 'int' whenever I enter in the address. All the tutorials I have found seem to be based on memory addresses that are like 00AB5678 but the ones I am getting are more like D3569227FC.

So my question is, how do I use ReadProcessMemory with much larger memory addresses?

Here is my code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class Program
    {
        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);

        static void Main(string[] args)
        {
            Process process = Process.GetProcessesByName("MyProgram")[0]; 
            IntPtr processHandle = OpenProcess(PROCESS_WM_READ, false, process.Id); 

            int bytesRead = 0;
            byte[] buffer = new byte[24]; //To read a 24 byte unicode string

            ReadProcessMemory((int)processHandle, 0xD5369227FC, buffer, buffer.Length, ref bytesRead);

            Console.WriteLine(Encoding.Unicode.GetString(buffer) + 
                  " (" + bytesRead.ToString() + "bytes)");
            Console.ReadLine();
        }
    }
}

Edit: I have converted my C# application to a 64 bit application by going into VS2012-->Project-->ApplicationName Properties-->Build-->Platform Target-->Change to "x64", now I just need to know how to change my code to read 64 bit addresses.

KillerKode
  • 957
  • 1
  • 12
  • 31
  • 1
    is which line are you getting the error? If it's in ReadProcessMemory function then try changing the int cast to lons cast.... @user1928362 – khaled4vokalz Dec 25 '15 at 23:43
  • 1
    The error is at the ReadProcessMemory function indeed, it reads exactly as: "The best overloaded method match for ConsoleApplication1.Program.ReadProcessMemory(int, int, byte[], int, ref int)' has some invalid arguments" then followed by "Argument 2: cannot convert from 'long' to 'int'". The problem is not with the first argument, it is the second argument. It works fine if I change the address to something like 0x00AFBCD7 but it won't accept the address CheatEngine gave me. – KillerKode Dec 25 '15 at 23:48

1 Answers1

17

You can path lpBaseAddress as Int64. Try replace your

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

to

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

But most correct implementation:

[DllImport("kernel32.dll")]
static extern bool ReadProcessMemory(IntPtr hProcess,
    IntPtr lpBaseAddress, [Out] byte[] lpBuffer, int dwSize, out IntPtr lpNumberOfBytesRead);
bogza.anton
  • 606
  • 11
  • 21