55 lines
1.8 KiB
C#
55 lines
1.8 KiB
C#
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<MEMORY_BASIC_INFORMATION>()) == 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;
|
|
}
|
|
}
|
|
} |