Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Windows.Forms;
namespace MemoryAPI
{
public class MemoryEditor
{
public Process[] _TargetProcess;
public int _ProcessId;
public IntPtr _ProcessHandle;
public void GetTargetProcess(string process_name)
{
try
{
_TargetProcess = Process.GetProcessesByName(process_name);
_ProcessId = _TargetProcess[0].Id;
}
catch (Exception)
{
MessageBox.Show(null, "Sorry, target process " + process_name + " Could not be found. Please make sure desired application is running",
"Target Process Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
public void OpenProcess()
{
try
{
_ProcessHandle = OpenProcess((uint)RequiredAccess.All, false, _ProcessId);
}
catch (Exception)
{
MessageBox.Show(null, "failed to open target process", "Target Process Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
public void CloseProcess()
{
if (_ProcessHandle != null)
{
CloseHandle(_ProcessHandle);
}
}
public byte[] ReadMemoryWithOffsets(int[] offsets)
{
byte[] value = new byte[20];
byte[] tmpAddressBuffer = new byte[4];
IntPtr tmpAddress = IntPtr.Zero;
int count = offsets.Length - 1;
OpenProcess();
if (count == 0)//Only 1 Offset
{
ReadProcessMemory(_ProcessHandle, IntPtr.Add(_TargetProcess[0].MainModule.BaseAddress, offsets[0]), value, 20, 0);
CloseProcess();
return value;
}
for (int i = 0; i <= count; i++)
{
if (i == count)
{
ReadProcessMemory(_ProcessHandle, IntPtr.Add(tmpAddress, offsets[offsets.Length - 1]), value, 20, 0);
tmpAddress = IntPtr.Add(tmpAddress, offsets[i]);
CloseProcess();
return value;
}
else if (i == 0)
{
ReadProcessMemory(_ProcessHandle, IntPtr.Add(_TargetProcess[0].MainModule.BaseAddress, offsets[i]), tmpAddressBuffer, 4, 0);
tmpAddress = (IntPtr)BitConverter.ToInt32(tmpAddressBuffer, 0);
}
else
{
ReadProcessMemory(_ProcessHandle, IntPtr.Add(tmpAddress, offsets[i]), tmpAddressBuffer, 4, 0);
tmpAddress = (IntPtr)BitConverter.ToInt32(tmpAddressBuffer, 0);
}
}
CloseProcess();
return value;
}
public void WriteMemoryWithOffsets(int[] offsets, byte[] bytesToWrite)
{
byte[] value = new byte[20];
byte[] tmpAddressBuffer = new byte[4];
IntPtr tmpAddress = IntPtr.Zero;
int count = offsets.Length - 1;
OpenProcess();
if (count == 0)
{
ReadProcessMemory(_ProcessHandle, IntPtr.Add(_TargetProcess[0].MainModule.BaseAddress, offsets[0]), tmpAddressBuffer, 4, 0);
}
for (int i = 0; i <= count; i++)
{
if (i == count)
{
WriteProcessMemory(_ProcessHandle, IntPtr.Add(_TargetProcess[0].MainModule.BaseAddress, offsets[i]), bytesToWrite, bytesToWrite.Length, 0);
}
else if (i == 0)
{
ReadProcessMemory(_ProcessHandle, IntPtr.Add(_TargetProcess[0].MainModule.BaseAddress, offsets[i]), tmpAddressBuffer, 4, 0);
tmpAddress = (IntPtr)BitConverter.ToInt32(tmpAddressBuffer, 0);
}
else
{
ReadProcessMemory(_ProcessHandle, IntPtr.Add(tmpAddress, offsets[i]), tmpAddressBuffer, 4, 0);
tmpAddress = (IntPtr)BitConverter.ToInt32(tmpAddressBuffer, 0);
}
}
CloseProcess();
}
//Access Flags
[Flags]
public enum RequiredAccess : uint
{
All = 0x001F0FFF,
Terminate = 0x00000001,
CreateThread = 0x00000002,
VMOperation = 0x00000008,
VMRead = 0x00000010,
VMWrite = 0x00000020,
DupHandle = 0x00000040,
SetInformation = 0x00000200,
QueryInformation = 0x00000400,
Synchronize = 0x00100000,
}
//DLL IMPORTS
[DllImport("kernel32.dll")]
public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] buffer, int size, int lpNumberOfBytesRead);
[DllImport("kernel32.dll")]
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] buffer, int size, int lpNumberOfBytesWritten);
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, int dwProcessId);
[DllImport("kernel32.dll")]
public static extern Int32 CloseHandle(IntPtr hProcess);
}
}