Пример #1
0
        /// <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();
        }
Пример #2
0
        /// <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();
        }
Пример #3
0
        /// <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);
        }
Пример #4
0
        /// <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);
        }
Пример #5
0
 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);
 }
Пример #6
0
        /// <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);
        }
Пример #7
0
        /// <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();
        }