Files
EonaCat.MemoryManager/EonaCat.MemoryManager/MemoryManager.cs
T
2025-06-29 20:34:36 +02:00

174 lines
5.6 KiB
C#

using EonaCat.Win32Api.WindowsAPI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace EonaCat.MemoryManager
{
public class MemoryManager
{
private readonly IntPtr _processHandle;
public MemoryManager(IntPtr processHandle)
{
_processHandle = processHandle;
}
public byte[] ReadBytes(IntPtr address, int size)
{
byte[] buffer = new byte[size];
ApiKernel32.ReadProcessMemory(_processHandle, address, buffer, size, out _);
return buffer;
}
public void WriteBytes(IntPtr address, byte[] data)
{
ApiKernel32.WriteProcessMemory(_processHandle, address, data, data.Length, out _);
}
public IntPtr ReadPointer(IntPtr baseAddress, int[] offsets)
{
IntPtr address = baseAddress;
byte[] buffer = new byte[IntPtr.Size];
for (int i = 0; i < offsets.Length; i++)
{
ApiKernel32.ReadProcessMemory(_processHandle, address, buffer, buffer.Length, out _);
address = (IntPtr)(IntPtr.Size == 4 ? BitConverter.ToInt32(buffer, 0) : BitConverter.ToInt64(buffer, 0));
address = IntPtr.Add(address, offsets[i]);
}
return address;
}
public T ReadValue<T>(IntPtr address) where T : unmanaged
{
int size = Marshal.SizeOf<T>();
byte[] buffer = ReadBytes(address, size);
unsafe
{
fixed (byte* ptr = buffer)
{
return *(T*)ptr;
}
}
}
public void WriteValue<T>(IntPtr address, T value) where T : unmanaged
{
int size = Marshal.SizeOf<T>();
byte[] buffer = new byte[size];
unsafe
{
fixed (byte* ptr = buffer)
{
*(T*)ptr = value;
}
}
WriteBytes(address, buffer);
}
public T ReadStruct<T>(IntPtr address) where T : class
{
int size = Marshal.SizeOf<T>();
byte[] buffer = ReadBytes(address, size);
GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
T value = Marshal.PtrToStructure<T>(handle.AddrOfPinnedObject());
handle.Free();
return value;
}
public void WriteStruct<T>(IntPtr address, T value) where T : class
{
int size = Marshal.SizeOf<T>();
byte[] buffer = new byte[size];
IntPtr ptr = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(value, ptr, false);
Marshal.Copy(ptr, buffer, 0, size);
Marshal.FreeHGlobal(ptr);
WriteBytes(address, buffer);
}
public object ReadValue(IntPtr address, Type type)
{
int size = Marshal.SizeOf(type);
byte[] buffer = ReadBytes(address, size);
GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
object value = Marshal.PtrToStructure(handle.AddrOfPinnedObject(), type);
handle.Free();
return value;
}
public void WriteValue(IntPtr address, object value, Type type)
{
int size = Marshal.SizeOf(type);
byte[] buffer = new byte[size];
IntPtr ptr = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(value, ptr, false);
Marshal.Copy(ptr, buffer, 0, size);
Marshal.FreeHGlobal(ptr);
WriteBytes(address, buffer);
}
public string ReadStringAscii(IntPtr address, int maxLength)
{
byte[] buffer = ReadBytes(address, maxLength);
int length = Array.IndexOf<byte>(buffer, 0);
if (length < 0) length = maxLength;
return System.Text.Encoding.ASCII.GetString(buffer, 0, length);
}
public string ReadStringUnicode(IntPtr address, int maxLength)
{
byte[] buffer = ReadBytes(address, maxLength * 2);
int length = 0;
for (int i = 0; i < maxLength; i++)
{
if (buffer[i * 2] == 0 && buffer[i * 2 + 1] == 0)
{
length = i;
break;
}
}
if (length == 0) length = maxLength;
return System.Text.Encoding.Unicode.GetString(buffer, 0, length * 2);
}
public void WriteStringAscii(IntPtr address, string value)
{
byte[] buffer = System.Text.Encoding.ASCII.GetBytes(value + '\0');
WriteBytes(address, buffer);
}
public void WriteStringUnicode(IntPtr address, string value)
{
byte[] buffer = System.Text.Encoding.Unicode.GetBytes(value + '\0');
WriteBytes(address, buffer);
}
public T[] ReadArray<T>(IntPtr address, int count) where T : unmanaged
{
int size = Marshal.SizeOf<T>() * count;
byte[] buffer = ReadBytes(address, size);
T[] result = new T[count];
Buffer.BlockCopy(buffer, 0, result, 0, size);
return result;
}
public void WriteArray<T>(IntPtr address, T[] array) where T : unmanaged
{
int size = Marshal.SizeOf<T>() * array.Length;
byte[] buffer = new byte[size];
Buffer.BlockCopy(array, 0, buffer, 0, size);
WriteBytes(address, buffer);
}
}
}