using System.Runtime.InteropServices; using static LightlessSync.Utils.PtrGuardMemory; namespace LightlessSync.Utils { public static partial class PtrGuard { private const ulong _aligmentPtr = 0x7UL; private static readonly nuint _minAppAddr = (nuint)GetMinAppAddr(); private static readonly nuint _maxAppAddr = (nuint)GetMaxAppAddr(); private static nint GetMinAppAddr() { GetSystemInfo(out var si); return si.lpMinimumApplicationAddress; } private static nint GetMaxAppAddr() { GetSystemInfo(out var si); return si.lpMaximumApplicationAddress; } public static bool LooksLikePtr(nint p) { if (p == 0) return false; nuint u = (nuint)p; if (u < _minAppAddr) return false; if (u > _maxAppAddr) return false; if ((u & _aligmentPtr) != 0) return false; if ((uint)u == 0x12345679u) 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; } } }