Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# ReadProcessMemory: How to read a 64 bit memory address?

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.

like image 506
KillerKode Avatar asked Dec 25 '15 23:12

KillerKode


1 Answers

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);
like image 184
bogza.anton Avatar answered Oct 02 '22 04:10

bogza.anton