public Protect(SafeProcessHandle handle, VirtualQueryInfo info, int protect) { this.handle = handle; this.info = info; this.protect = protect; if (protect == info.Protect) return; int oldProtect; if (!Win32.VirtualProtectEx(handle.DangerousGetHandle(), (IntPtr)info.StartAddress, (IntPtr)info.RegionSize, protect, out oldProtect)) throw new Win32Exception(); }
Protect SetProtect(VirtualQueryInfo info, bool write) { var protect = info.Protect; if (!info.Mapped) // Can't change protection on mapped memory { if ((protect & Win32.PAGE_GUARD) != 0) protect ^= Win32.PAGE_GUARD; var extra = protect & ~(Win32.PAGE_GUARD - 1); if (write) { if ((protect & (Win32.PAGE_EXECUTE | Win32.PAGE_EXECUTE_READ | Win32.PAGE_EXECUTE_WRITECOPY)) != 0) protect = Win32.PAGE_EXECUTE_READWRITE; if ((protect & (Win32.PAGE_NOACCESS | Win32.PAGE_READONLY | Win32.PAGE_WRITECOPY)) != 0) protect = Win32.PAGE_READWRITE; } else { if ((protect & Win32.PAGE_NOACCESS) != 0) protect = Win32.PAGE_READONLY; } protect |= extra; } return new Protect(handle, info, protect); }
VirtualQueryInfo VirtualQuery(long index) { var max = UIntPtr.Size == 4 ? uint.MaxValue : ulong.MaxValue; if ((ulong)index >= max) return null; Win32.MEMORY_BASIC_INFORMATION memInfo; if (Win32.VirtualQueryEx(handle.DangerousGetHandle(), (IntPtr)index, out memInfo, Win32.MEMORY_BASIC_INFORMATION.Size) == 0) { if (Win32.LastError != Win32.ERROR_INVALID_PARAMETER) throw new Win32Exception(); return null; } var info = new VirtualQueryInfo(); info.Committed = (memInfo.State & Win32.MEM_COMMIT) != 0; info.Mapped = (memInfo.Type & Win32.MEM_MAPPED) != 0; info.NoAccess = (memInfo.Protect & Win32.PAGE_NOACCESS) != 0; info.StartAddress = memInfo.BaseAddress.ToInt64(); info.RegionSize = (long)Math.Min((ulong)memInfo.RegionSize.ToInt64(), max - (ulong)memInfo.BaseAddress.ToInt64()); info.EndAddress = memInfo.BaseAddress.ToInt64() + info.RegionSize; info.Protect = memInfo.Protect; return info; }