using System.Runtime.InteropServices; using static LightlessSync.Utils.PtrGuardMemory; namespace LightlessSync.Utils { public static partial class PtrGuard { private const ulong _minLikelyPtr = 0x0000_0001_0000_0000UL; private const ulong _maxUserPtr = 0x0000_7FFF_FFFF_FFFFUL; private const ulong _aligmentPtr = 0x7UL; public static bool LooksLikePtr(nint p) { if (p == 0) return false; var u = (ulong)p; if (u < _minLikelyPtr) return false; if (u > _maxUserPtr) return false; if ((u & _aligmentPtr) != 0) return false; return true; } public static bool TryReadIntPtr(nint addr, out nint value) { value = 0; if (!LooksLikePtr(addr)) return false; return ReadProcessMemory(GetCurrentProcess(), addr, out value, (nuint)IntPtr.Size, out nuint bytesRead) && bytesRead == (nuint)IntPtr.Size; } public static bool IsReadable(nint addr, nuint size) { if (addr == 0 || size == 0) return false; if (VirtualQuery(addr, out var mbi, (nuint)Marshal.SizeOf()) == 0) return false; const uint Commit = 0x1000; const uint NoAccess = 0x01; const uint PageGuard = 0x100; if (mbi.State != Commit) return false; if ((mbi.Protect & PageGuard) != 0) return false; if (mbi.Protect == NoAccess) return false; ulong start = (ulong)addr; ulong end = start + size - 1; ulong r0 = (ulong)mbi.BaseAddress; ulong r1 = r0 + mbi.RegionSize - 1; return start >= r0 && end <= r1; } } }