I've seen many posts on MPGH and others sites/forums of people requesting help with C# WriteProcessMemory and ReadProcessMemory. Further digging on google and Found a lot of Classes made by others for this purpose. I tested a bunch of them and found them not functional or buggy. Most of them did not automatically add offsets. Granted i found a couple classes out there that actually worked, but there were pretty messy and was converting alot of variables from bytes to hex back hex to decs blah blah blah. So I gave up on the lazy route and made this one that more then suits what purposes i need it for. And since Ive never really tributed anything to MPGH here is a Memory Read/Write Class.
After looking over so many different examples I got alot of the ideas from them, but mostly take full credit of this.
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace PointerChecker
{
public class MemoryHandler
{
#region Properties
private string m_ProcessName;
private Process[] m_Processes;
private Process m_TargetProcess;
private int m_TProcessId;
private IntPtr m_TProcessAddress;
private IntPtr m_TProcessHandle;
public string ProcessName { get { return m_ProcessName; } set { m_ProcessName = value; } }
public Process[] Processes { get { return m_Processes; } set { m_Processes = value; } }
public Process TargetProcess { get { return m_TargetProcess; } set { m_TargetProcess = value; } }
public IntPtr TProcessAddress { get { return m_TProcessAddress; } set { m_TProcessAddress = value; } }
public IntPtr TProcessHandle { get { return m_TProcessHandle; } set { m_TProcessHandle = value; } }
public int TProcessId { get { return m_TProcessId; } set { m_TProcessId = value; } }
#endregion
public bool LoadMemory(String TProcessName)
{
Process[] tmpList;
tmpList = Process.GetProcessesByName(TProcessName);
if (tmpList.Length != 0)
{
m_ProcessName = TProcessName;
m_Processes = Process.GetProcesses();
m_TargetProcess = tmpList.FirstOrDefault();
m_TProcessAddress = m_TargetProcess.MainModule.BaseAddress;
m_TProcessId = m_TargetProces*****;
return true;
}
else
return false;
}
public byte[] ReadMemory(int[] offs)
{
byte[] OutSource = new byte[20];
byte[] addBuffer = new byte[4];
int readOut = 0;
int Count = offs.Length - 1;
IntPtr tmpAdd = IntPtr.Zero;
Open();
if (Count == 0)//If Only One Offset
{
ReadProcessMemory(m_TProcessHandle, IntPtr.Add(m_TProcessAddress, offs[0]), OutSource, 20, out readOut);
return OutSource;
}
for (int i = 0; i <= Count; i++)
{
if (i == Count)
{
ReadProcessMemory(m_TProcessHandle, IntPtr.Add(tmpAdd, offs[offs.Length - 1]), OutSource, 1064, out readOut);
tmpAdd = IntPtr.Add(tmpAdd, offs[i]);
Close();
return OutSource;
}
else if (i == 0)
{
ReadProcessMemory(m_TProcessHandle, IntPtr.Add(m_TProcessAddress, offs[i]), addBuffer, 4, out readOut);
tmpAdd = (IntPtr)BitConverter.ToInt32(addBuffer, 0);
}
else
{
ReadProcessMemory(m_TProcessHandle, IntPtr.Add(tmpAdd, offs[i]), addBuffer, 4, out readOut);
tmpAdd = (IntPtr)BitConverter.ToInt32(addBuffer, 0);
}
}
Close();
return OutSource;
}
public void WriteMemory(int[] offs, byte[] WriteBuffer)
{
int bytesWritten = 0;
int bytesRead = 0;
int Counter = offs.Length - 1;
IntPtr tmpAdd = IntPtr.Zero;
byte[] addBuffer = new byte[4];
byte[] ReadBuffer = new byte[30];
Open();
if (Counter == 0)
{
ReadProcessMemory(m_TProcessHandle, IntPtr.Add(m_TProcessAddress, offs[0]), addBuffer, 4, out bytesRead);
}
for (int i = 0; i <= Counter; i++)
{
if (i == Counter)
{
WriteProcessMemory(m_TProcessHandle, IntPtr.Add(tmpAdd, offs[i]), WriteBuffer, (uint)WriteBuffer.Length, out bytesWritten);
}
else if (i == 0)
{
ReadProcessMemory(m_TProcessHandle, IntPtr.Add(m_TProcessAddress, offs[i]), addBuffer, 4, out bytesRead);
tmpAdd = (IntPtr)BitConverter.ToInt32(addBuffer, 0);
}
else
{
ReadProcessMemory(m_TProcessHandle, IntPtr.Add(tmpAdd, offs[i]), addBuffer, 4, out bytesRead);
tmpAdd = (IntPtr)BitConverter.ToInt32(addBuffer, 0);
}
}
Close();
}
public void Open()
{
m_TProcessHandle = OpenProcess((uint)ProcessAccessType.PROCESS_ALL_ACCESS, 0, (uint)m_TProcessId);
}
public void Close()
{
CloseHandle(TProcessHandle);
}
[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),
PROCESS_ALL_ACCESS = PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION
}
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(UInt32 dwDesiredAccess, Int32 bInheritHandle, UInt32 dwProcessId);
[DllImport("kernel32.dll")]
public static extern Int32 CloseHandle(IntPtr hObject);
[DllImport("kernel32.dll")]
public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out int lpNumberOfBytesRead);
[DllImport("kernel32.dll")]
public static extern Int32 WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out int lpNumberOfBytesWritten);
}
}
I will be adding more to this class as I need, and will try my best to update it on here aswell.
HOPE YOU ENJOY THIS.