using System.Diagnostics; using System.Runtime.InteropServices; using WhiteMagic.Native; namespace WhiteMagic; /// /// In-process memory reader that accesses the owning process's memory through /// direct pointer dereference (unsafe). Use this reader from within a /// managed DLL injected into the target process. /// public sealed class InProcessReader : MemoryBase { private readonly SafeMemoryHandle _handle; private readonly IntPtr _imageBase; private bool _disposed; /// /// Creates an in-process reader for the current process. /// public InProcessReader() { Process current = Process.GetCurrentProcess(); _handle = NativeMethods.OpenProcess( ProcessAccess.VmRead | ProcessAccess.VmWrite | ProcessAccess.VmOperation | ProcessAccess.QueryInformation, false, current.Id); _imageBase = current.MainModule?.BaseAddress ?? IntPtr.Zero; } /// public override IntPtr ImageBase => _imageBase; /// public override SafeMemoryHandle Handle => _handle; /// public override unsafe byte[] ReadBytes(IntPtr address, int count, bool isRelative = false) { if (isRelative) address = GetAbsolute(address); byte[] buffer = new byte[count]; fixed (byte* ptr = buffer) { Buffer.MemoryCopy((void*)address, ptr, count, count); } return buffer; } /// public override unsafe int WriteBytes(IntPtr address, ReadOnlySpan bytes, bool isRelative = false) { if (isRelative) address = GetAbsolute(address); fixed (byte* ptr = bytes) { Buffer.MemoryCopy(ptr, (void*)address, bytes.Length, bytes.Length); } return bytes.Length; } /// public override void Dispose() { if (!_disposed) { _disposed = true; _handle.Dispose(); } } }