QuestionSolvedWriteProcessMemory in 64 bits

Posts 14 of 4 · Page 1 of 1
WriteProcessMemory in 64 bits
Hello guys,

I need your help today, I try to make a trainer for 64 bits games, I got two issues.

First issue :

I found the pointer base address for the same game in 32 bits, the base address works but in 64 bits, the pointer base address change everytimes, I don't know why.

You can take a look my pointer base address on this screen :

ttps://s24.postimg.org/rqd2fb1qr/baseaddress.png (I'm not allowed to post images / links sorry)

My second issue is my code directly, my trainer is working in 32 bits but not in 64 bits, I share my code, if you can tell me what is wrong, I will appreciate it (and sorry for my bad english I'm french).

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

namespace App1
{
    public partial class Form1 : Form
    {
   
        public Form1()
        {
            InitializeComponent();
        }

        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool ReadProcessMemory(IntPtr process, IntPtr baseAddress, [Out] byte[] buffer, int size,
            out IntPtr bytesRead);

        public static long ReadInt64(IntPtr process, IntPtr baseAddress)
        {
            var buffer = new byte[8];
            IntPtr bytesRead;
            ReadProcessMemory(process, baseAddress, buffer, 8, out bytesRead);
            return BitConverter.ToInt64(buffer, 0);
        }

        public static long GetRealAddress(IntPtr process, IntPtr baseAddress, int[] offsets)
        {
            var address = baseAddress.ToInt64();
            foreach (var offset in offsets)
            {
                address = ReadInt64(process, (IntPtr)address) + offset;
            }
            return address;
        }


        private void Form1_Load(object sender, EventArgs e)
        {
            int byteswritten;
            Process[] processes = Process.GetProcessesByName("supertux2");
            ProcessMemoryReader memoryReader = new ProcessMemoryReaderLib.ProcessMemoryReader();

            if (processes.Length != 0)
            {
                memoryReader.ReadProcess = processes[0];
                memoryReader.OpenProcess();

                IntPtr baseAddress = (IntPtr)0x0249CE0;
                var offsets = new[] { 0xD8, 0x00, 0x70, 0x90, 0x00 };
                var realAddress = GetRealAddress(processes[0].Handle, (IntPtr)baseAddress, offsets);

                memoryReader.WriteProcessMemory((IntPtr)realAddress, BitConverter.GetBytes(1337), out byteswritten); 
            }
            else
            {
                MessageBox.Show("ERROR : Game not launched.");
                Application.Exit();
            }
        }
    }
}
I tried to use my base pointer with the offsets but I don't know if my code is correct.

ProcessMemoryReader.cs :

Code:
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace ProcessMemoryReaderLib
{
	/// <summary>
	/// ProcessMemoryReader is a class that enables direct reading a process memory
	/// </summary>
	class ProcessMemoryReaderApi
	{
		// constants information can be found in <winnt.h>
		[Flags]
		public enum ProcessAccessType
		{
			PROCESS_TERMINATE			= (0x0001),
			PROCESS_CREATE_THREAD		= (0x0002), 
			PROCESS_SET_SESSIONID		= (0x0004), 
			PROCESS_VM_OPERATION		= (0x0008), 
			PROCESS_VM_READ				= (0x0010), 
			PROCESS_VM_WRITE			= (0x0020), 
			PROCESS_DUP_HANDLE			= (0x0040), 
			PROCESS_CREATE_PROCESS		= (0x0080), 
			PROCESS_SET_QUOTA			= (0x0100), 
			PROCESS_SET_INFORMATION		= (0x0200), 
			PROCESS_QUERY_INFORMATION	= (0x0400) 
		}
		
		// function declarations are found in the MSDN and in <winbase.h> 
		
		//		HANDLE OpenProcess(
		//			DWORD dwDesiredAccess,  // access flag
		//			BOOL bInheritHandle,    // handle inheritance option
		//			DWORD dwProcessId       // process identifier
		//			);
		[DllImport("kernel32.dll")]
		public static extern IntPtr OpenProcess(UInt32 dwDesiredAccess, Int32 bInheritHandle, UInt32 dwProcessId);

		//		BOOL CloseHandle(
		//			HANDLE hObject   // handle to object
		//			);
		[DllImport("kernel32.dll")]
		public static extern Int32 CloseHandle(IntPtr hObject);

		//		BOOL ReadProcessMemory(
		//			HANDLE hProcess,              // handle to the process
		//			LPCVOID lpBaseAddress,        // base of memory area
		//			LPVOID lpBuffer,              // data buffer
		//			SIZE_T nSize,                 // number of bytes to read
		//			SIZE_T * lpNumberOfBytesRead  // number of bytes read
		//			);
		[DllImport("kernel32.dll")]
		public static extern Int32 ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,[In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesRead);
	
		//		BOOL WriteProcessMemory(
		//			HANDLE hProcess,                // handle to process
		//			LPVOID lpBaseAddress,           // base of memory area
		//			LPCVOID lpBuffer,               // data buffer
		//			SIZE_T nSize,                   // count of bytes to write
		//			SIZE_T * lpNumberOfBytesWritten // count of bytes written
		//			);
		[DllImport("kernel32.dll")]
		public static extern Int32 WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,[In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesWritten);

	}

	public class ProcessMemoryReader
	{

		public ProcessMemoryReader()
		{
		}

        /// <summary>	
		/// Process from which to read		
		/// </summary>
		public Process ReadProcess
		{
			get
			{
				return m_ReadProcess;
			}
			set
			{
				m_ReadProcess = value;
			}
		}

		private Process m_ReadProcess = null;

		private IntPtr m_hProcess = IntPtr.Zero;

		public void OpenProcess()
		{
//			m_hProcess = ProcessMemoryReaderApi.OpenProcess(ProcessMemoryReaderApi.PROCESS_VM_READ, 1, (uint)m_ReadProcess.Id);
			ProcessMemoryReaderApi.ProcessAccessType access;
			access = ProcessMemoryReaderApi.ProcessAccessType.PROCESS_VM_READ 
				| ProcessMemoryReaderApi.ProcessAccessType.PROCESS_VM_WRITE 
				| ProcessMemoryReaderApi.ProcessAccessType.PROCESS_VM_OPERATION;
				m_hProcess = ProcessMemoryReaderApi.OpenProcess((uint)access, 1, (uint)m_ReadProcess.Id);
		}

		public void CloseHandle()
		{
			int iRetValue;
			iRetValue = ProcessMemoryReaderApi.CloseHandle(m_hProcess);
			if (iRetValue == 0)
				throw new Exception("CloseHandle failed");
		}

		public byte[] ReadProcessMemory(IntPtr MemoryAddress, uint bytesToRead, out int bytesRead)
		{
			byte[] buffer = new byte[bytesToRead];
			
			IntPtr ptrBytesRead;
			ProcessMemoryReaderApi.ReadProcessMemory(m_hProcess,MemoryAddress,buffer ,bytesToRead,out ptrBytesRead);
			
			bytesRead = ptrBytesRead.ToInt32();

			return buffer;
		}

		public void WriteProcessMemory(IntPtr MemoryAddress, byte[] bytesToWrite ,out int bytesWritten)
		{
			IntPtr ptrBytesWritten;
			ProcessMemoryReaderApi.WriteProcessMemory(m_hProcess,MemoryAddress,bytesToWrite,(uint)bytesToWrite.Length,out ptrBytesWritten);
			
			bytesWritten = ptrBytesWritten.ToInt32();
		}

		


	}
}
Thank you guys.
Got skype?
Problem solved, my code was correct but supertux2 use a custom memory addresses randomizer, don't try your tests on this game.

PS : Thank you d4ne for your help (best guy here)
Posts 14 of 4 · Page 1 of 1
This thread is closed for replies.

Similar Threads

Tags for this Thread

None

Need help?