/// <exception cref="InvalidOperationException">snapshot already taken, <see cref="MemoryBlockBase.Active"/> is <see langword="false"/>, or failed to make memory read-only</exception> public override void SaveXorSnapshot() { if (_snapshot != null) { throw new InvalidOperationException("Snapshot already taken"); } if (!Active) { throw new InvalidOperationException("Not active"); } // temporarily switch the entire block to `R`: in case some areas are unreadable, we don't want // that to complicate things Kernel32.MemoryProtection old; if (!Kernel32.VirtualProtect(Z.UU(AddressRange.Start), Z.UU(Size), Kernel32.MemoryProtection.READONLY, out old)) { throw new InvalidOperationException($"{nameof(Kernel32.VirtualProtect)}() returned FALSE!"); } _snapshot = new byte[Size]; var ds = new MemoryStream(_snapshot, true); var ss = GetStream(AddressRange.Start, Size, false); ss.CopyTo(ds); XorHash = WaterboxUtils.Hash(_snapshot); ProtectAll(); }
/// <summary>take a snapshot of the entire memory block's contents, for use in <see cref="GetXorStream"/></summary> /// <exception cref="InvalidOperationException"> /// snapshot already taken, <see cref="MemoryBlock.Active"/> is <see langword="false"/>, or failed to make memory read-only /// </exception> public void SaveXorSnapshot() { // note: The snapshot only holds up to the current committed size. We compensate for that in xorstream if (_snapshot != null) { throw new InvalidOperationException("Snapshot already taken"); } if (!Active) { throw new InvalidOperationException("Not active"); } // temporarily switch the entire committed area to `R`: in case some areas are unreadable, we don't want // that to complicate things if (CommittedSize > 0) { _pal.Protect(Start, CommittedSize, Protection.R); } _snapshot = new byte[CommittedSize]; var ds = new MemoryStream(_snapshot, true); var ss = GetStream(Start, CommittedSize, false); ss.CopyTo(ds); XorHash = WaterboxUtils.Hash(_snapshot); ProtectAll(); }
/// <summary> /// take a hash of the current full contents of the block, including unreadable areas /// but not uncommitted areas /// </summary> /// <exception cref="InvalidOperationException"> /// <see cref="MemoryBlock.Active"/> is <see langword="false"/> or failed to make memory read-only /// </exception> public byte[] FullHash() { if (!Active) { throw new InvalidOperationException("Not active"); } // temporarily switch the committed parts to `R` so we can read them if (CommittedSize > 0) { _pal.Protect(Start, CommittedSize, Protection.R); } var ret = WaterboxUtils.Hash(GetStream(Start, CommittedSize, false)); ProtectAll(); return(ret); }
/// <exception cref="InvalidOperationException"><see cref="MemoryBlockBase.Active"/> is <see langword="false"/> or failed to make memory read-only</exception> public override byte[] FullHash() { if (!Active) { throw new InvalidOperationException("Not active"); } // temporarily switch the entire block to `R` Kernel32.MemoryProtection old; if (!Kernel32.VirtualProtect(Z.UU(AddressRange.Start), Z.UU(Size), Kernel32.MemoryProtection.READONLY, out old)) { throw new InvalidOperationException($"{nameof(Kernel32.VirtualProtect)}() returned FALSE!"); } var ret = WaterboxUtils.Hash(GetStream(AddressRange.Start, Size, false)); ProtectAll(); return(ret); }
public void Seal() { EnsureActive(); if (_sealed) { throw new InvalidOperationException("Already sealed"); } _snapshot = new byte[CommittedSize]; if (CommittedSize > 0) { // temporarily switch the committed parts to `R` so we can read them _pal.Protect(Start, CommittedSize, Protection.R); Marshal.Copy(Z.US(Start), _snapshot, 0, (int)CommittedSize); } _hash = WaterboxUtils.Hash(_snapshot); _sealed = true; ProtectAll(); _pal.SetWriteStatus(_dirtydata); }
/// <exception cref="InvalidOperationException"><see cref="MemoryBlockBase.Active"/> is <see langword="false"/> or failed to make memory read-only</exception> public override byte[] FullHash() { if (!Active) { throw new InvalidOperationException("Not active"); } // temporarily switch the entire block to `R` var exitCode = mprotect(Z.US(AddressRange.Start), Z.UU(Size), MemoryProtection.Read); if (exitCode != 0) { throw new InvalidOperationException($"{nameof(mprotect)}() returned {exitCode}!"); } var ret = WaterboxUtils.Hash(GetStream(AddressRange.Start, Size, false)); ProtectAll(); return(ret); }
/// <exception cref="InvalidOperationException">snapshot already taken, <see cref="MemoryBlockBase.Active"/> is <see langword="false"/>, or failed to make memory read-only</exception> public override void SaveXorSnapshot() { if (_snapshot != null) { throw new InvalidOperationException("Snapshot already taken"); } if (!Active) { throw new InvalidOperationException("Not active"); } // temporarily switch the entire block to `R`: in case some areas are unreadable, we don't want that to complicate things var exitCode = mprotect(Z.US(AddressRange.Start), Z.UU(Size), MemoryProtection.Read); if (exitCode != 0) { throw new InvalidOperationException($"{nameof(mprotect)}() returned {exitCode}!"); } _snapshot = new byte[Size]; GetStream(AddressRange.Start, Size, false).CopyTo(new MemoryStream(_snapshot, true)); XorHash = WaterboxUtils.Hash(_snapshot); ProtectAll(); }