Skip to content

Instantly share code, notes, and snippets.

@sappho192
Last active July 24, 2024 05:35
Show Gist options
  • Save sappho192/8d9cb988d1853ba4c6227c3423dc1e38 to your computer and use it in GitHub Desktop.
Save sappho192/8d9cb988d1853ba4c6227c3423dc1e38 to your computer and use it in GitHub Desktop.
ProcessMemoryApi.dll
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
#nullable disable
namespace ProcessMemoryApi
{
public class ProcessMemoryReader
{
public IntPtr pBytesRead = IntPtr.Zero;
public IntPtr pBytesWritten = IntPtr.Zero;
public IntPtr handle;
public IntPtr pBaseAddress;
private IntPtr pEndAddress;
private long ModuleSize;
public Process process { get; set; }
public ProcessMemoryReader(int Pid)
{
this.process = Process.GetProcessById(Pid);
if (this.process == null)
throw new ArgumentNullException("Process Not Found ");
this.OpenProcess();
}
public ProcessMemoryReader(string pName)
{
this.process = ((IEnumerable<Process>) Process.GetProcessesByName(pName)).ToList<Process>().FirstOrDefault<Process>();
if (this.process == null)
throw new ArgumentNullException("Process Not Found");
this.OpenProcess();
}
public bool FindProcess(string name)
{
this.process = ((IEnumerable<Process>) Process.GetProcessesByName(name)).ToList<Process>().FirstOrDefault<Process>();
return this.process != null;
}
private void OpenProcess()
{
this.handle = Win32MemoryApi.OpenProcess(1080U, 1, (uint) this.process.Id);
this.pBaseAddress = this.process.MainModule.BaseAddress;
this.pEndAddress = IntPtr.Add(this.pBaseAddress, this.process.MainModule.ModuleMemorySize);
this.ModuleSize = (long) this.pEndAddress - (long) this.pBaseAddress;
}
public void CloseHandle()
{
if (Win32MemoryApi.CloseHandle(this.handle) == 0)
throw new Exception("Closing handle failed.");
}
public long ReadPtr_x64(long[] PointerChain)
{
bool flag = true;
byte[] buffer = new byte[8];
long num1 = 0;
IntPtr lpNumberOfBytesRead;
foreach (long num2 in PointerChain)
{
if (flag)
{
Win32MemoryApi.ReadProcessMemory(this.handle, (IntPtr) ((long) this.process.Modules[0].BaseAddress + num2), buffer, 8U, out lpNumberOfBytesRead);
num1 = BitConverter.ToInt64(buffer, 0);
flag = false;
}
else
{
Win32MemoryApi.ReadProcessMemory(this.handle, (IntPtr) (num1 + num2), buffer, 8U, out lpNumberOfBytesRead);
num1 = BitConverter.ToInt64(buffer, 0);
}
}
return num1;
}
public byte ReadByte(IntPtr memoryAddress)
{
byte[] buffer = new byte[1];
Win32MemoryApi.ReadProcessMemory(this.handle, memoryAddress, buffer, 1U, out this.pBytesRead);
return buffer[0];
}
public byte[] ReadByteArray(IntPtr memoryAddress, uint length)
{
byte[] buffer = new byte[(int) length];
Win32MemoryApi.ReadProcessMemory(this.handle, memoryAddress, buffer, length, out this.pBytesRead);
return buffer;
}
public int ReadInt16(IntPtr memoryAddress)
{
byte[] buffer = new byte[2];
Win32MemoryApi.ReadProcessMemory(this.handle, memoryAddress, buffer, 2U, out this.pBytesRead);
return (int) BitConverter.ToInt16(buffer, 0);
}
public int ReadInt32(IntPtr memoryAddress)
{
byte[] buffer = new byte[4];
Win32MemoryApi.ReadProcessMemory(this.handle, memoryAddress, buffer, 4U, out this.pBytesRead);
return BitConverter.ToInt32(buffer, 0);
}
public long ReadInt64(IntPtr memoryAddress)
{
byte[] buffer = new byte[8];
Win32MemoryApi.ReadProcessMemory(this.handle, memoryAddress, buffer, 8U, out this.pBytesRead);
return BitConverter.ToInt64(buffer, 0);
}
public float ReadSingle(IntPtr memoryAddress)
{
byte[] buffer = new byte[4];
Win32MemoryApi.ReadProcessMemory(this.handle, memoryAddress, buffer, 4U, out this.pBytesRead);
return BitConverter.ToSingle(buffer, 0);
}
public double ReadDouble(IntPtr memoryAddress)
{
byte[] buffer = new byte[8];
Win32MemoryApi.ReadProcessMemory(this.handle, memoryAddress, buffer, 8U, out this.pBytesRead);
return BitConverter.ToDouble(buffer, 0);
}
public void WriteToPtr_x64(long[] PointerChain, byte[] Data)
{
byte[] buffer = new byte[8];
bool flag = true;
long lpBaseAddress = 0;
IntPtr lpNumberOfBytesRead;
foreach (long num in PointerChain)
{
if (flag)
{
Win32MemoryApi.ReadProcessMemory(this.handle, (IntPtr) ((long) this.process.Modules[0].BaseAddress + num), buffer, 8U, out lpNumberOfBytesRead);
lpBaseAddress = BitConverter.ToInt64(buffer, 0);
flag = false;
}
else
{
Win32MemoryApi.ReadProcessMemory(this.handle, (IntPtr) (lpBaseAddress + num), buffer, 8U, out lpNumberOfBytesRead);
lpBaseAddress = BitConverter.ToInt64(buffer, 0);
}
}
Win32MemoryApi.WriteProcessMemory(this.handle, (IntPtr) lpBaseAddress, Data, (uint) Data.Length, out IntPtr _);
}
public void WriteByte(IntPtr memoryAddress, byte byteToWrite)
{
byte[] buffer = new byte[1]{ byteToWrite };
this.pBytesWritten = IntPtr.Zero;
Win32MemoryApi.WriteProcessMemory(this.handle, memoryAddress, buffer, 1U, out this.pBytesWritten);
}
public void WriteByteArray(IntPtr memoryAddress, byte[] bytesToWrite)
{
this.pBytesWritten = IntPtr.Zero;
Win32MemoryApi.WriteProcessMemory(this.handle, memoryAddress, bytesToWrite, (uint) bytesToWrite.Length, out this.pBytesWritten);
}
public void WriteInt16(IntPtr memoryAddress, short i)
{
this.pBytesWritten = IntPtr.Zero;
byte[] bytes = BitConverter.GetBytes(i);
Win32MemoryApi.WriteProcessMemory(this.handle, memoryAddress, bytes, 2U, out this.pBytesWritten);
}
public void WriteInt32(IntPtr memoryAddress, int i)
{
this.pBytesWritten = IntPtr.Zero;
byte[] bytes = BitConverter.GetBytes(i);
Win32MemoryApi.WriteProcessMemory(this.handle, memoryAddress, bytes, 4U, out this.pBytesWritten);
}
public void WriteInt64(IntPtr memoryAddress, long i)
{
this.pBytesWritten = IntPtr.Zero;
byte[] bytes = BitConverter.GetBytes(i);
Win32MemoryApi.WriteProcessMemory(this.handle, memoryAddress, bytes, 8U, out this.pBytesWritten);
}
public void WriteSingle(IntPtr memoryAddress, float i)
{
this.pBytesWritten = IntPtr.Zero;
byte[] bytes = BitConverter.GetBytes(i);
Win32MemoryApi.WriteProcessMemory(this.handle, memoryAddress, bytes, 4U, out this.pBytesWritten);
}
public void WriteDouble(IntPtr memoryAddress, double i)
{
this.pBytesWritten = IntPtr.Zero;
byte[] bytes = BitConverter.GetBytes(i);
Win32MemoryApi.WriteProcessMemory(this.handle, memoryAddress, bytes, 8U, out this.pBytesWritten);
}
public List<IntPtr> ScanPtrBySig(string pattern = "")
{
byte?[] nullableArray = pattern2SigArray(pattern);
List<IntPtr> numList = new List<IntPtr>();
if (pattern == null || pattern.Length % 2 != 0)
return new List<IntPtr>();
byte[] numArray = this.ReadByteArray(this.pBaseAddress, (uint) this.ModuleSize);
for (int index1 = 0; index1 < numArray.Length - nullableArray.Length - 4 + 1; ++index1)
{
int num1 = 0;
for (int index2 = 0; index2 < nullableArray.Length; ++index2)
{
if (!nullableArray[index2].HasValue)
++num1;
else if ((int) nullableArray[index2].Value == (int) numArray[index1 + index2])
++num1;
else
break;
}
if (num1 == nullableArray.Length)
{
IntPtr num2 = new IntPtr(BitConverter.ToInt32(numArray, index1 + nullableArray.Length));
num2 = new IntPtr(this.pBaseAddress.ToInt64() + (long) index1 + (long) nullableArray.Length + 4L + num2.ToInt64() - (long) this.process.MainModule.BaseAddress);
numList.Add(num2);
}
}
return numList;
static byte?[] pattern2SigArray(string HexString)
{
byte?[] nullableArray = new byte?[HexString.Length / 2];
for (int index = 0; index < HexString.Length / 2; ++index)
{
string str = HexString.Substring(index * 2, 2);
nullableArray[index] = !(str == "**") ? new byte?(Convert.ToByte(str, 16)) : new byte?();
}
return nullableArray;
}
}
}
}
using System;
using System.Runtime.InteropServices;
#nullable disable
namespace ProcessMemoryApi
{
public static class Win32MemoryApi
{
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(
uint dwDesiredAccess,
int bInheritHandle,
uint dwProcessId);
[DllImport("kernel32.dll")]
public static extern int CloseHandle(IntPtr hObject);
[DllImport("kernel32.dll")]
public static extern int ReadProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
[In, Out] byte[] buffer,
uint size,
out IntPtr lpNumberOfBytesRead);
[DllImport("kernel32.dll")]
public static extern int WriteProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
[In, Out] byte[] buffer,
uint size,
out IntPtr lpNumberOfBytesWritten);
[Flags]
public enum ProcessAccessType
{
PROCESS_TERMINATE = 1,
PROCESS_CREATE_THREAD = 2,
PROCESS_SET_SESSIONID = 4,
PROCESS_VM_OPERATION = 8,
PROCESS_VM_READ = 16, // 0x00000010
PROCESS_VM_WRITE = 32, // 0x00000020
PROCESS_DUP_HANDLE = 64, // 0x00000040
PROCESS_CREATE_PROCESS = 128, // 0x00000080
PROCESS_SET_QUOTA = 256, // 0x00000100
PROCESS_SET_INFORMATION = 512, // 0x00000200
PROCESS_QUERY_INFORMATION = 1024, // 0x00000400
PROCESS_QUERY_LIMITED_INFORMATION = 4096, // 0x00001000
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment