71 lines
2.2 KiB
C#
71 lines
2.2 KiB
C#
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<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;
|
|
}
|
|
}
|
|
} |