public unsafe override HexPosition Write(HexPosition position, byte[] source, long sourceIndex, long length) { if (isReadOnly) { return(0); } if (position >= Span.End) { return(0); } int bytesToWrite = (int)Math.Min(length, int.MaxValue); uint oldProtect; bool restoreOldProtect = NativeMethods.VirtualProtectEx(hProcess, new IntPtr((void *)position.ToUInt64()), new IntPtr(bytesToWrite), NativeMethods.PAGE_EXECUTE_READWRITE, out oldProtect); IntPtr sizeWritten; bool b; fixed(void *p = &source[sourceIndex]) b = NativeMethods.WriteProcessMemory(hProcess, new IntPtr((void *)position.ToUInt64()), new IntPtr(p), new IntPtr(bytesToWrite), out sizeWritten); if (restoreOldProtect) { NativeMethods.VirtualProtectEx(hProcess, new IntPtr((void *)position.ToUInt64()), new IntPtr(bytesToWrite), oldProtect, out oldProtect); } return(!b ? 0 : (int)sizeWritten.ToInt64()); }
CachedPage GetCachedPage_NoLock(HexPosition position) { ulong pageOffset = position.ToUInt64() & ~pageSizeMask; for (int i = 0; i < cachedPages.Length; i++) { var cp = cachedPages[(i + lastHitIndex) % cachedPages.Length]; if (cp.IsInitialized && cp.Offset == pageOffset) { return(cp); } } CachedPage foundCp = null; for (int i = 0; i < cachedPages.Length; i++) { var cp = cachedPages[(i + lastHitIndex) % cachedPages.Length]; if (!cp.IsInitialized) { foundCp = cp; break; } } if (foundCp == null) { foundCp = cachedPages[(lastHitIndex + 1) % cachedPages.Length]; } lastHitIndex = foundCp.Index; Initialize_NoLock(foundCp, pageOffset); return(foundCp); }
public override uint ReadUInt32(HexPosition position) { Debug.Assert(position < HexPosition.MaxEndPosition); var pos = position.ToUInt64(); var d = data; if (pos + 3 < pos) { return(0); } if (pos + 3 >= (ulong)d.LongLength) { int res = 0; if (pos < (ulong)d.LongLength) { res = d[pos]; } if (pos + 1 < (ulong)d.LongLength) { res |= d[pos + 1] << 8; } if (pos + 2 < (ulong)d.LongLength) { res |= d[pos + 2] << 16; } return((uint)res); } return((uint)(d[pos] | (d[pos + 1] << 8) | (d[pos + 2] << 16) | (d[pos + 3] << 24))); }
HexPosition GetEndPosition(HexPosition origPos, HexPosition startPos, HexPosition pos, PositionKind positionKind, SelectPositionLengthKind selectPosKind) { switch (selectPosKind) { case SelectPositionLengthKind.Position: switch (positionKind) { case PositionKind.Absolute: case PositionKind.File: case PositionKind.RVA: return(ToBufferPosition(origPos, pos.ToUInt64(), positionKind)); case PositionKind.CurrentPosition: return((origPos + pos).ToUInt64()); default: throw new InvalidOperationException(); } case SelectPositionLengthKind.Length: if (pos == HexPosition.Zero) { return(startPos); } return((startPos + pos - 1).ToUInt64()); default: throw new InvalidOperationException(); } }
public override HexBytes ReadHexBytes(HexPosition position, long length) { Debug.Assert(position < HexPosition.MaxEndPosition); if (length == 0) return HexBytes.Empty; var pos = position.ToUInt64(); var d = data; if (pos >= (ulong)d.LongLength) return new HexBytes(new byte[length], allValid: false); var ary = new byte[length]; if (pos + (ulong)length > (ulong)d.LongLength) { var bitArray = new BitArray(length > int.MaxValue ? int.MaxValue : (int)length); long len = d.LongLength - (long)pos; Array.Copy(d, (long)pos, ary, 0, len); long bits = len > int.MaxValue ? int.MaxValue : len; for (long i = 0; i < bits; i++) bitArray.Set((int)i, true); return new HexBytes(ary, bitArray); } Array.Copy(d, (long)pos, ary, 0, length); return new HexBytes(ary); }
public override ulong ReadUInt64BigEndian(HexPosition position) { Debug.Assert(position < HexPosition.MaxEndPosition); var pos = position.ToUInt64(); var d = data; if (pos + 7 < pos) return 0; if (pos + 7 >= (ulong)d.LongLength) { ulong res = 0; if (pos < (ulong)d.LongLength) res = (ulong)d[pos] << 56; if (pos + 1 < (ulong)d.LongLength) res |= (ulong)d[pos + 1] << 48; if (pos + 2 < (ulong)d.LongLength) res |= (ulong)d[pos + 2] << 40; if (pos + 3 < (ulong)d.LongLength) res |= (ulong)d[pos + 3] << 32; if (pos + 4 < (ulong)d.LongLength) res |= (ulong)d[pos + 4] << 24; if (pos + 5 < (ulong)d.LongLength) res |= (ulong)d[pos + 5] << 16; if (pos + 6 < (ulong)d.LongLength) res |= (ulong)d[pos + 6] << 8; return res; } return d[pos + 7] | ((ulong)d[pos + 6] << 8) | ((ulong)d[pos + 5] << 16) | ((ulong)d[pos + 4] << 24) | ((ulong)d[pos + 3] << 32) | ((ulong)d[pos + 2] << 40) | ((ulong)d[pos + 1] << 48) | ((ulong)d[pos] << 56); }
public override sbyte ReadSByte(HexPosition position) { Debug.Assert(position < HexPosition.MaxEndPosition); var pos = position.ToUInt64(); var d = data; if (pos >= (ulong)d.LongLength) return 0; return (sbyte)d[pos]; }
public override HexBufferPoint GetBufferPositionFromLineNumber(HexPosition lineNumber) { if (lineNumber >= LineCount) { throw new ArgumentOutOfRangeException(nameof(lineNumber)); } return(new HexBufferPoint(Buffer, startPosition + checked (lineNumber.ToUInt64() * bytesPerLine))); }
public override int TryReadByte(HexPosition position) { Debug.Assert(position < HexPosition.MaxEndPosition); var pos = position.ToUInt64(); var d = data; if (pos >= (ulong)d.LongLength) return -1; return d[pos]; }
public override ushort ReadUInt16(HexPosition position) { Debug.Assert(position < HexPosition.MaxEndPosition); var pos = position.ToUInt64(); var d = data; if (pos + 1 < pos || pos + 1 >= (ulong)d.LongLength) return pos < (ulong)d.LongLength ? d[pos] : (ushort)0; return (ushort)(d[pos] | (d[pos + 1] << 8)); }
public override short ReadInt16(HexPosition position) { Debug.Assert(position < HexPosition.MaxEndPosition); var pos = position.ToUInt64(); var d = data; if (pos + 1 < pos || pos + 1 >= (ulong)d.LongLength) return pos < (ulong)d.LongLength ? d[pos] : (short)0; return (short)(d[pos] | (d[pos + 1] << 8)); }
public override void Write(HexPosition position, byte[] source, long sourceIndex, long length) { Debug.Assert(position < HexPosition.MaxEndPosition); var pos = position.ToUInt64(); var d = data; if (pos >= (ulong)d.LongLength) return; long bytesLeft = d.LongLength - (long)pos; long validBytes = length <= bytesLeft ? length : bytesLeft; Array.Copy(source, sourceIndex, d, (long)pos, validBytes); }
public void FormatOffset(StringBuilder dest, HexPosition position) { var offset = position.ToUInt64() << (64 - bitSize); dest.Append(prefix); for (int i = 0; i < bitSize; i += 4, offset <<= 4) { var nibble = (offset >> 60) & 0x0F; if (nibble < 10) dest.Append((char)('0' + nibble)); else dest.Append((char)((lowerCaseHex ? 'a' : 'A') + nibble - 10)); } dest.Append(suffix); }
public override ulong ReadUInt64(HexPosition position) { Debug.Assert(position < HexPosition.MaxEndPosition); var pos = position.ToUInt64(); var d = data; if (pos + 7 < pos) { return(0); } if (pos + 7 >= (ulong)d.LongLength) { ulong res = 0; if (pos < (ulong)d.LongLength) { res = d[pos]; } if (pos + 1 < (ulong)d.LongLength) { res |= (ulong)d[pos + 1] << 8; } if (pos + 2 < (ulong)d.LongLength) { res |= (ulong)d[pos + 2] << 16; } if (pos + 3 < (ulong)d.LongLength) { res |= (ulong)d[pos + 3] << 24; } if (pos + 4 < (ulong)d.LongLength) { res |= (ulong)d[pos + 4] << 32; } if (pos + 5 < (ulong)d.LongLength) { res |= (ulong)d[pos + 5] << 40; } if (pos + 6 < (ulong)d.LongLength) { res |= (ulong)d[pos + 6] << 48; } return(res); } return(d[pos] | ((ulong)d[pos + 1] << 8) | ((ulong)d[pos + 2] << 16) | ((ulong)d[pos + 3] << 24) | ((ulong)d[pos + 4] << 32) | ((ulong)d[pos + 5] << 40) | ((ulong)d[pos + 6] << 48) | ((ulong)d[pos + 7] << 56)); }
public override byte ReadByte(HexPosition position) { Debug.Assert(position < HexPosition.MaxEndPosition); var pos = position.ToUInt64(); var d = data; if (pos >= (ulong)d.LongLength) { return(0); } return(d[pos]); }
public unsafe override HexSpanInfo GetSpanInfo(HexPosition position) { if (position >= HexPosition.MaxEndPosition) throw new ArgumentOutOfRangeException(nameof(position)); if (position >= endAddress) return new HexSpanInfo(HexSpan.FromBounds(endAddress, HexPosition.MaxEndPosition), HexSpanInfoFlags.None); ulong baseAddress, regionSize; uint state, protect; int res; if (IntPtr.Size == 4) { NativeMethods.MEMORY_BASIC_INFORMATION32 info; res = NativeMethods.VirtualQueryEx32(hProcess, new IntPtr((void*)position.ToUInt64()), out info, NativeMethods.MEMORY_BASIC_INFORMATION32_SIZE); baseAddress = info.BaseAddress; regionSize = info.RegionSize; state = info.State; protect = info.Protect; Debug.Assert(res == 0 || res == NativeMethods.MEMORY_BASIC_INFORMATION32_SIZE); } else { NativeMethods.MEMORY_BASIC_INFORMATION64 info; res = NativeMethods.VirtualQueryEx64(hProcess, new IntPtr((void*)position.ToUInt64()), out info, NativeMethods.MEMORY_BASIC_INFORMATION64_SIZE); baseAddress = info.BaseAddress; regionSize = info.RegionSize; state = info.State; protect = info.Protect; Debug.Assert(res == 0 || res == NativeMethods.MEMORY_BASIC_INFORMATION64_SIZE); } // Could fail if eg. the process has exited if (res == 0) return new HexSpanInfo(HexSpan.FromBounds(HexPosition.Zero, endAddress), HexSpanInfoFlags.None); var flags = HexSpanInfoFlags.None; if (state == NativeMethods.MEM_COMMIT) { uint access = protect & 0xFF; if (access != NativeMethods.PAGE_NOACCESS && (protect & NativeMethods.PAGE_GUARD) == 0) flags |= HexSpanInfoFlags.HasData; } return new HexSpanInfo(new HexSpan(baseAddress, regionSize), flags); }
public override ushort ReadUInt16BigEndian(HexPosition position) { Debug.Assert(position < HexPosition.MaxEndPosition); var pos = position.ToUInt64(); var d = data; if (pos + 1 < pos || pos + 1 >= (ulong)d.LongLength) { return(pos < (ulong)d.LongLength ? (ushort)(d[pos] << 8) : (ushort)0); } return((ushort)(d[pos + 1] | (d[pos] << 8))); }
public override sbyte ReadSByte(HexPosition position) { Debug.Assert(position < HexPosition.MaxEndPosition); int index = (int)(position.ToUInt64() & pageSizeMask); lock (lockObj) { var cp = GetCachedPage_NoLock(position); if (index >= cp.DataSize) { return(0); } return((sbyte)cp.Data[index]); } }
public override uint ReadUInt32(HexPosition position) { Debug.Assert(position < HexPosition.MaxEndPosition); int index = (int)(position.ToUInt64() & pageSizeMask); lock (lockObj) { var cp = GetCachedPage_NoLock(position); var data = cp.Data; if (index + 3 < data.Length) { return((uint)(data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24))); } return(BitConverter.ToUInt32(ReadSlow(position, 4), 0)); } }
public override short ReadInt16(HexPosition position) { Debug.Assert(position < HexPosition.MaxEndPosition); int index = (int)(position.ToUInt64() & pageSizeMask); lock (lockObj) { var cp = GetCachedPage_NoLock(position); var data = cp.Data; if (index + 1 < data.Length) { return((short)(data[0] | (data[1] << 8))); } return(BitConverter.ToInt16(ReadSlow(position, 2), 0)); } }
public unsafe override HexPosition Read(HexPosition position, byte[] destination, long destinationIndex, long length) { if (position >= Span.End) { return(0); } int bytesToRead = (int)Math.Min(length, int.MaxValue); IntPtr sizeRead; bool b; fixed(void *p = &destination[destinationIndex]) b = NativeMethods.ReadProcessMemory(hProcess, new IntPtr((void *)position.ToUInt64()), new IntPtr(p), new IntPtr(bytesToRead), out sizeRead); return(!b ? 0 : sizeRead.ToInt64()); }
public override uint ReadUInt32BigEndian(HexPosition position) { Debug.Assert(position < HexPosition.MaxEndPosition); int index = (int)(position.ToUInt64() & pageSizeMask); lock (lockObj) { var cp = GetCachedPage_NoLock(position); var data = cp.Data; if (index + 3 >= data.Length) { data = ReadSlow(position, 4); index = 0; } return((uint)(data[index + 3] | (data[index + 2] << 8) | (data[index + 1] << 16) | (data[index] << 24))); } }
public override ulong ReadUInt64(HexPosition position) { Debug.Assert(position < HexPosition.MaxEndPosition); int index = (int)(position.ToUInt64() & pageSizeMask); lock (lockObj) { var cp = GetCachedPage_NoLock(position); var data = cp.Data; if (index + 7 < data.Length) { return((ulong)data[0] | ((ulong)data[1] << 8) | ((ulong)data[2] << 16) | ((ulong)data[3] << 24) | ((ulong)data[4] << 32) | ((ulong)data[5] << 40) | ((ulong)data[6] << 48) | ((ulong)data[7] << 56)); } return(BitConverter.ToUInt64(ReadSlow(position, 8), 0)); } }
public override void ReadBytes(HexPosition position, byte[] destination, long destinationIndex, long length) { Debug.Assert(position < HexPosition.MaxEndPosition); var pos = position.ToUInt64(); var d = data; if (pos >= (ulong)d.LongLength) { Clear(destination, destinationIndex, length); return; } long bytesLeft = d.LongLength - (long)pos; long validBytes = length <= bytesLeft ? length : bytesLeft; Array.Copy(d, (long)pos, destination, destinationIndex, validBytes); length -= validBytes; if (length > 0) Clear(destination, destinationIndex + validBytes, length); }
public override short ReadInt16BigEndian(HexPosition position) { Debug.Assert(position < HexPosition.MaxEndPosition); int index = (int)(position.ToUInt64() & pageSizeMask); lock (lockObj) { var cp = GetCachedPage_NoLock(position); var data = cp.Data; if (index + 1 >= data.Length) { data = ReadSlow(position, 2); index = 0; } return((short)(data[index + 1] | (data[index] << 8))); } }
public override ulong ReadUInt64BigEndian(HexPosition position) { Debug.Assert(position < HexPosition.MaxEndPosition); int index = (int)(position.ToUInt64() & pageSizeMask); lock (lockObj) { var cp = GetCachedPage_NoLock(position); var data = cp.Data; if (index + 7 >= data.Length) { data = ReadSlow(position, 8); index = 0; } return((ulong)data[index + 7] | ((ulong)data[index + 6] << 8) | ((ulong)data[index + 5] << 16) | ((ulong)data[index + 4] << 24) | ((ulong)data[index + 3] << 32) | ((ulong)data[index + 2] << 40) | ((ulong)data[index + 1] << 48) | ((ulong)data[index] << 56)); } }
public void FormatOffset(StringBuilder dest, HexPosition position) { var offset = position.ToUInt64() << (64 - bitSize); dest.Append(prefix); for (int i = 0; i < bitSize; i += 4, offset <<= 4) { var nibble = (offset >> 60) & 0x0F; if (nibble < 10) { dest.Append((char)('0' + nibble)); } else { dest.Append((char)((lowerCaseHex ? 'a' : 'A') + nibble - 10)); } } dest.Append(suffix); }
public override void ReadBytes(HexPosition position, byte[] destination, long destinationIndex, long length) { Debug.Assert(position < HexPosition.MaxEndPosition); lock (lockObj) { while (length > 0) { var cp = GetCachedPage_NoLock(position); long srcIndex = (long)(position.ToUInt64() - cp.Offset); int partSize = (int)(pageSize - (ulong)srcIndex); if (partSize > length) { partSize = (int)length; } Array.Copy(cp.Data, srcIndex, destination, destinationIndex, partSize); position += (ulong)partSize; length -= partSize; destinationIndex += partSize; } } }
public override int ReadInt32(HexPosition position) { Debug.Assert(position < HexPosition.MaxEndPosition); var pos = position.ToUInt64(); var d = data; if (pos + 3 < pos) return 0; if (pos + 3 >= (ulong)d.LongLength) { int res = 0; if (pos < (ulong)d.LongLength) res = d[pos]; if (pos + 1 < (ulong)d.LongLength) res |= d[pos + 1] << 8; if (pos + 2 < (ulong)d.LongLength) res |= d[pos + 2] << 16; return res; } return d[pos] | (d[pos + 1] << 8) | (d[pos + 2] << 16) | (d[pos + 3] << 24); }
CachedPage GetCachedPage(HexPosition position) { ulong pageOffset = position.ToUInt64() & ~pageSizeMask; for (int i = 0; i < cachedPages.Length; i++) { var cp = cachedPages[(i + lastHitIndex) % cachedPages.Length]; if (cp.IsInitialized && cp.Offset == pageOffset) return cp; } CachedPage foundCp = null; for (int i = 0; i < cachedPages.Length; i++) { var cp = cachedPages[(i + lastHitIndex) % cachedPages.Length]; if (!cp.IsInitialized) { foundCp = cp; break; } } if (foundCp == null) foundCp = cachedPages[(lastHitIndex + 1) % cachedPages.Length]; lastHitIndex = foundCp.Index; Initialize(foundCp, pageOffset); return foundCp; }
public override void ReadBytes(HexPosition position, byte[] destination, long destinationIndex, long length) { Debug.Assert(position < HexPosition.MaxEndPosition); while (length > 0) { var cp = GetCachedPage(position); long srcIndex = (long)(position.ToUInt64() - cp.Offset); int partSize = (int)(pageSize - (ulong)srcIndex); if (partSize > length) partSize = (int)length; Array.Copy(cp.Data, srcIndex, destination, destinationIndex, partSize); position += (ulong)partSize; length -= partSize; destinationIndex += partSize; } }
public unsafe override HexPosition Read(HexPosition position, byte[] destination, long destinationIndex, long length) { if (position >= Span.End) return 0; int bytesToRead = (int)Math.Min(length, int.MaxValue); IntPtr sizeRead; bool b; fixed (void* p = &destination[destinationIndex]) b = NativeMethods.ReadProcessMemory(hProcess, new IntPtr((void*)position.ToUInt64()), new IntPtr(p), new IntPtr(bytesToRead), out sizeRead); return !b ? 0 : sizeRead.ToInt64(); }
public override uint ReadUInt32(HexPosition position) { Debug.Assert(position < HexPosition.MaxEndPosition); int index = (int)(position.ToUInt64() & pageSizeMask); var cp = GetCachedPage(position); if (index + 3 < cp.Data.Length) return (uint)(cp.Data[0] | (cp.Data[1] << 8) | (cp.Data[2] << 16) | (cp.Data[3] << 24)); return BitConverter.ToUInt32(ReadSlow(position, 4), 0); }
public override ulong ReadUInt64(HexPosition position) { Debug.Assert(position < HexPosition.MaxEndPosition); int index = (int)(position.ToUInt64() & pageSizeMask); var cp = GetCachedPage(position); if (index + 7 < cp.Data.Length) { return ((ulong)cp.Data[0] | ((ulong)cp.Data[1] << 8) | ((ulong)cp.Data[2] << 16) | ((ulong)cp.Data[3] << 24) | ((ulong)cp.Data[4] << 32) | ((ulong)cp.Data[5] << 40) | ((ulong)cp.Data[6] << 48) | ((ulong)cp.Data[7] << 56)); } return BitConverter.ToUInt64(ReadSlow(position, 8), 0); }
public override sbyte ReadSByte(HexPosition position) { Debug.Assert(position < HexPosition.MaxEndPosition); int index = (int)(position.ToUInt64() & pageSizeMask); var cp = GetCachedPage(position); if (index >= cp.DataSize) return 0; return (sbyte)cp.Data[index]; }
public override ushort ReadUInt16(HexPosition position) { Debug.Assert(position < HexPosition.MaxEndPosition); int index = (int)(position.ToUInt64() & pageSizeMask); var cp = GetCachedPage(position); if (index + 1 < cp.Data.Length) return (ushort)(cp.Data[0] | (cp.Data[1] << 8)); return BitConverter.ToUInt16(ReadSlow(position, 2), 0); }
public override ulong ReadUInt64(HexPosition position) { Debug.Assert(position < HexPosition.MaxEndPosition); var pos = position.ToUInt64(); var d = data; if (pos + 7 < pos) return 0; if (pos + 7 >= (ulong)d.LongLength) { ulong res = 0; if (pos < (ulong)d.LongLength) res = d[pos]; if (pos + 1 < (ulong)d.LongLength) res |= (ulong)d[pos + 1] << 8; if (pos + 2 < (ulong)d.LongLength) res |= (ulong)d[pos + 2] << 16; if (pos + 3 < (ulong)d.LongLength) res |= (ulong)d[pos + 3] << 24; if (pos + 4 < (ulong)d.LongLength) res |= (ulong)d[pos + 4] << 32; if (pos + 5 < (ulong)d.LongLength) res |= (ulong)d[pos + 5] << 40; if (pos + 6 < (ulong)d.LongLength) res |= (ulong)d[pos + 6] << 48; return res; } return d[pos] | ((ulong)d[pos + 1] << 8) | ((ulong)d[pos + 2] << 16) | ((ulong)d[pos + 3] << 24) | ((ulong)d[pos + 4] << 32) | ((ulong)d[pos + 5] << 40) | ((ulong)d[pos + 6] << 48) | ((ulong)d[pos + 7] << 56); }
public override HexBufferLine GetLineFromLineNumber(HexPosition lineNumber) { if (lineNumber >= LineCount) throw new ArgumentOutOfRangeException(nameof(lineNumber)); var position = startPosition + checked(lineNumber.ToUInt64() * bytesPerLine); return GetLineFromPosition(new HexBufferPoint(Buffer, position)); }
public override int ReadInt32(HexPosition position) { Debug.Assert(position < HexPosition.MaxEndPosition); int index = (int)(position.ToUInt64() & pageSizeMask); lock (lockObj) { var cp = GetCachedPage_NoLock(position); var data = cp.Data; if (index + 3 < data.Length) return data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); return BitConverter.ToInt32(ReadSlow(position, 4), 0); } }
public override short ReadInt16(HexPosition position) { Debug.Assert(position < HexPosition.MaxEndPosition); int index = (int)(position.ToUInt64() & pageSizeMask); lock (lockObj) { var cp = GetCachedPage_NoLock(position); var data = cp.Data; if (index + 1 < data.Length) return (short)(data[0] | (data[1] << 8)); return BitConverter.ToInt16(ReadSlow(position, 2), 0); } }
public override byte ReadByte(HexPosition position) { Debug.Assert(position < HexPosition.MaxEndPosition); int index = (int)(position.ToUInt64() & pageSizeMask); lock (lockObj) { var cp = GetCachedPage_NoLock(position); if (index >= cp.DataSize) return 0; return cp.Data[index]; } }
public unsafe override HexPosition Write(HexPosition position, byte[] source, long sourceIndex, long length) { if (isReadOnly) return 0; if (position >= Span.End) return 0; int bytesToWrite = (int)Math.Min(length, int.MaxValue); uint oldProtect; bool restoreOldProtect = NativeMethods.VirtualProtectEx(hProcess, new IntPtr((void*)position.ToUInt64()), new IntPtr(bytesToWrite), NativeMethods.PAGE_EXECUTE_READWRITE, out oldProtect); IntPtr sizeWritten; bool b; fixed (void* p = &source[sourceIndex]) b = NativeMethods.WriteProcessMemory(hProcess, new IntPtr((void*)position.ToUInt64()), new IntPtr(p), new IntPtr(bytesToWrite), out sizeWritten); if (restoreOldProtect) NativeMethods.VirtualProtectEx(hProcess, new IntPtr((void*)position.ToUInt64()), new IntPtr(bytesToWrite), oldProtect, out oldProtect); return !b ? 0 : (int)sizeWritten.ToInt64(); }
public unsafe override HexSpanInfo GetSpanInfo(HexPosition position) { if (position >= HexPosition.MaxEndPosition) { throw new ArgumentOutOfRangeException(nameof(position)); } if (position >= endAddress) { return(new HexSpanInfo(HexSpan.FromBounds(endAddress, HexPosition.MaxEndPosition), HexSpanInfoFlags.None)); } ulong baseAddress, regionSize; uint state, protect; int res; if (IntPtr.Size == 4) { res = NativeMethods.VirtualQueryEx32(hProcess, new IntPtr((void *)position.ToUInt64()), out var info, NativeMethods.MEMORY_BASIC_INFORMATION32_SIZE); baseAddress = info.BaseAddress; regionSize = info.RegionSize; state = info.State; protect = info.Protect; Debug.Assert(res == 0 || res == NativeMethods.MEMORY_BASIC_INFORMATION32_SIZE); } else { res = NativeMethods.VirtualQueryEx64(hProcess, new IntPtr((void *)position.ToUInt64()), out var info, NativeMethods.MEMORY_BASIC_INFORMATION64_SIZE); baseAddress = info.BaseAddress; regionSize = info.RegionSize; state = info.State; protect = info.Protect; Debug.Assert(res == 0 || res == NativeMethods.MEMORY_BASIC_INFORMATION64_SIZE); } // Could fail if eg. the process has exited if (res == 0) { return(new HexSpanInfo(HexSpan.FromBounds(HexPosition.Zero, endAddress), HexSpanInfoFlags.None)); } var flags = HexSpanInfoFlags.None; if (state == NativeMethods.MEM_COMMIT) { uint access = protect & 0xFF; if (access != NativeMethods.PAGE_NOACCESS && (protect & NativeMethods.PAGE_GUARD) == 0) { flags |= HexSpanInfoFlags.HasData; } } return(new HexSpanInfo(new HexSpan(baseAddress, regionSize), flags)); }