protected override void UnsafeReadBytesCore(MemoryAddress address, byte[] buffer, int offset, int count) { var pageFrom = GetPageIndex(address); var pageTo = GetPageIndex(address + (ulong)count); if (pageFrom == pageTo) { _fileStream.Position = (long)_pages[pageFrom].TranslateToRva(address); _fileStream.Read(buffer, offset, count); } else { var read = 0; var remaining = count - read; for (int i = pageFrom; i <= pageTo; i++) { _fileStream.Position = (long)_pages[i].TranslateToRva(address); read += _fileStream.Read(buffer, read, Math.Min(remaining, (int)_pages[i].DataSize)); remaining = count - read; address += _pages[i].DataSize; } if (remaining != 0) { throw new InvalidDataException("Pages did not contain all bytes."); } } }
public static MemoryObject Create(Type type, IMemory memory, MemoryAddress address) { if (type == null) { throw new ArgumentNullException("type"); } if (memory == null) { throw new ArgumentNullException("memory"); } if (memory.Reader == null) { throw new ArgumentException("memory"); } if (!memory.Reader.IsValidAddress(address)) { throw new ArgumentOutOfRangeException("address"); } if (!memory.Reader.IsValidAddress(address + type.SizeOf())) { throw new ArgumentOutOfRangeException(); } return(UnsafeCreate(type, memory, address)); }
public T Read <T>(MemoryAddress address) { if (!IsValidAddress(address)) { throw new ArgumentOutOfRangeException(); } if (!IsValidAddress(address + TypeHelper <T> .SizeOf)) { throw new ArgumentException("address"); } if (TypeHelper <T> .HasKnownStructLayout) { byte[] buffer = GetBuffer(TypeHelper <T> .SizeOf); UnsafeReadBytes(address, buffer, 0, TypeHelper <T> .SizeOf); return(StructHelper <T> .UnsafeRead(buffer, 0)); } else if (TypeHelper <T> .IsMemoryObjectType) { return((T)(object)MemoryObjectFactory.UnsafeCreate(typeof(T), Memory, address)); } else if (TypeHelper <T> .IsMemoryPointerType) { return((T)(object)MemoryPointerFactory.UnsafeCreate <T>(Memory, ReadMemoryAddress(address))); } else if (TypeHelper <T> .IsMemoryAddressType) { return((T)(object)ReadMemoryAddress(address)); } else { throw new NotSupportedException(); } }
public ProcessMemoryReader(Process process) { if (process == null) { throw new ArgumentNullException("process"); } if (process.HasExited) { throw new ArgumentException("process"); } _process = process; _minValidAddress = 0x00010000; if (process.Is64BitProcess()) { _maxValidAddress = process.IsLargeAddressAware() ? ((8UL << 40) - 1) : // 8TB - 1 byte ((2UL << 30) - 1); // 2GB - 1 byte _pointerSize = 8; } else { _maxValidAddress = process.IsLargeAddressAware() ? 0xBFFF0000 : 0x7FFEFFFF; _pointerSize = 4; } }
public ProcessMemoryReader(Process process) { if (process == null) { throw new ArgumentNullException("process"); } if (process.HasExited) { throw new ArgumentException("process"); } _process = process; _minValidAddress = 0x00010000; if (process.Is64BitProcess()) { //// It appears these limits are only max addressable size, but memory can be //// scattered around at both high and low addresses. //_maxValidAddress = process.IsLargeAddressAware() ? // ((8UL << 40) - 1) : // 8TB - 1 byte // ((2UL << 30) - 1); // 2GB - 1 byte _maxValidAddress = ulong.MaxValue; _pointerSize = 8; } else { _maxValidAddress = process.IsLargeAddressAware() ? 0xBFFF0000 : 0x7FFEFFFF; _pointerSize = 4; } ImageBase = _process.MainModule.BaseAddress; }
public void ReadBytes(MemoryAddress address, byte[] buffer, int offset, int count) { if (!IsValidAddress(address)) { throw new ArgumentOutOfRangeException("address"); } if (buffer == null) { throw new ArgumentNullException("buffer"); } if (offset < 0) { throw new ArgumentOutOfRangeException("offset"); } if (offset > buffer.Length) { throw new ArgumentOutOfRangeException("offset"); } if (count < 0) { throw new ArgumentOutOfRangeException("count"); } if (offset + count > buffer.Length) { throw new ArgumentException(); } if (!IsValidAddress(address + buffer.Length)) { throw new ArgumentException(); } UnsafeReadBytes(address, buffer, offset, count); }
public static T Create <T>(IMemory memory, MemoryAddress address) where T : MemoryObject { if (memory == null) { throw new ArgumentNullException("memory"); } if (memory.Reader == null) { throw new ArgumentException("memory"); } if (!memory.Reader.IsValid) { throw new ArgumentException("memory"); } if (!memory.Reader.IsValidAddress(address)) { throw new ArgumentOutOfRangeException("address"); } if (!memory.Reader.IsValidAddress(address + TypeHelper <T> .SizeOf)) { throw new ArgumentOutOfRangeException("address"); } return((T)UnsafeCreate(typeof(T), memory, address)); }
private bool TryGetPageIndex(MemoryAddress address, out int index) { index = _pageStarts.BinarySearch(address); if (index < 0) { int closest = ~index - 1; if (_pages[closest].Contains(address)) { index = closest; return(true); } else { if (closest + 1 < _pages.Count && _pages[closest + 1].Contains(address)) { index = closest + 1; return(true); } else { return(false); } } } return(true); }
public byte[] ReadBytes(MemoryAddress address, int count) { if (!IsValidAddress(address)) { throw new ArgumentOutOfRangeException("address"); } if (count < 0) { throw new ArgumentOutOfRangeException("count"); } if (!IsValidAddress(address + count)) { throw new ArgumentException(); } // NOTE: Do NOT allocate buffer with "GetBuffer" as a small buffer could be modified // by other reads. byte[] buffer = new byte[count]; if (count == 0) { return(buffer); // Cannot read anything into an empty buffer, would get exception. } UnsafeReadBytes(address, buffer, 0, count); return(buffer); }
private int GetPageIndex(MemoryAddress address) { int index = _pageStarts.BinarySearch(address); if (index < 0) { int closest = ~index - 1; if (_pages[closest].Contains(address)) { return(closest); } else { if (closest + 1 < _pages.Count && _pages[closest + 1].Contains(address)) { return(closest + 1); } else { throw new ArgumentException("address"); } } } return(index); }
public T[] Read <T>(MemoryAddress address, int count) { var snapshotAddress = ToSnapshotAddress(address); if (TypeHelper <T> .IsMemoryObjectType) { var array = BaseMemory.Reader.Read <T>(address, count); var itemOffset = snapshotAddress; for (int i = 0; i < count; i++) { (array[i] as MemoryObject).SetSnapshot( SnapshotReader.Segment.Array, SnapshotReader.Segment.Offset + itemOffset, SnapshotReader.Segment.Array.Length - (SnapshotReader.Segment.Offset + itemOffset)); itemOffset += TypeHelper <T> .SizeOf; } return(array); } else if (TypeHelper <T> .IsMemoryPointerType) { // It is important that a pointer doesn't get a snapshot as context! var array = new T[count]; for (int i = 0; i < count; i++) { array[i] = (T)MemoryPointerFactory.Create <T>(BaseMemory, SnapshotReader.ReadMemoryAddress(snapshotAddress + i * BaseMemory.Reader.PointerSize)); } return(array); } return(SnapshotReader.Read <T>(snapshotAddress, count)); }
public MiniDumpMemoryReader(string path) { if (string.IsNullOrWhiteSpace(path)) { throw new ArgumentNullException("path"); } _fileStream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read); var mem = new FileMemoryReader(path); var header = mem.Read <MiniDump.Header>(0x00); var dirs = mem.Read <MiniDump.Directory>(header.StreamDirectoryRva, (int)header.NumberOfStreams); var moduleList = dirs.SingleOrDefault(a => a.StreamType == MiniDump.StreamType.ModuleListStream); if (moduleList.StreamType != MiniDump.StreamType.ModuleListStream) { throw new InvalidOperationException("The minidump file does not contain a module list."); } var modules = mem.Read <MiniDump.List <MiniDump.Module> >(moduleList.Location.Rva).Items; var mainModule = modules.FirstOrDefault(a => a.VersionInfo.FileType == 1); var mainModuleNameLength = mem.Read <int>(mainModule.ModuleNameRva); var mainModuleNameBuffer = mem.ReadBytes(mainModule.ModuleNameRva + sizeof(int), mainModuleNameLength); var mainModuleName = Encoding.Unicode.GetString(mainModuleNameBuffer); MainModuleName = System.IO.Path.GetFileNameWithoutExtension(mainModuleName); MainModuleVersion = mainModule.VersionInfo.FileVersion; ImageBase = mainModule.BaseOfImage; var memory64ListDir = dirs.SingleOrDefault(a => a.StreamType == MiniDump.StreamType.Memory64ListStream); if (memory64ListDir.StreamType != MiniDump.StreamType.Memory64ListStream) { throw new InvalidOperationException("The minidump file does not contain a full memory dump."); } var memory64List = mem.Read <MiniDump.Memory64List>(memory64ListDir.Location.Rva); var rva = memory64List.BaseRva; var ranges = memory64List.MemoryRanges; var pages = new List <Page>(); for (int i = 0; i < ranges.Length; i++) { pages.Add(new Page { StartOfMemoryRange = (uint)ranges[i].StartOfMemoryRange, DataSize = (uint)ranges[i].DataSize, Rva = (uint)rva }); rva += ranges[i].DataSize; } _pages = pages; _pageStarts = _pages.Select(a => a.StartOfMemoryRange).ToList(); _minValidAddress = _pages[0].StartOfMemoryRange; _maxValidAddress = _pages[_pages.Count - 1].StartOfMemoryRange + _pages[_pages.Count - 1].DataSize; _pointerSize = 4; // TODO: Get 32-bit vs 64-bit info from the minidump somewhere.. }
public unsafe override void UnsafeReadBytes(MemoryAddress address, byte[] buffer, int offset, int count) { fixed (byte* pBuffer = &buffer[offset]) { if (!Win32.ReadProcessMemory(_process.Handle, address, pBuffer, count, IntPtr.Zero)) throw new Win32Exception(); } }
public static object Create <T>(IMemory memory, MemoryAddress value) { if (!TypeHelper <T> .IsMemoryPointerType) { throw new NotSupportedException(); } return(UnsafeCreate <T>(memory, value)); }
public T[] Read <T>(MemoryAddress address, int count) { if (!IsValidAddress(address)) { throw new ArgumentOutOfRangeException("address"); } if (count < 0) { throw new ArgumentOutOfRangeException("count"); } if (!IsValidAddress(address + TypeHelper <T> .SizeOf * count)) { throw new ArgumentException(); } T[] array = new T[count]; if (TypeHelper <T> .HasKnownStructLayout) { int bufferSize = TypeHelper <T> .SizeOf * count; byte[] buffer = GetBuffer(bufferSize); UnsafeReadBytes(address, buffer, 0, bufferSize); StructHelper <T> .CopyFromBuffer(buffer, 0, array, 0, count); } else if (TypeHelper <T> .IsMemoryObjectType) { for (int i = 0; i < count; i++) { array[i] = (T)(object)MemoryObjectFactory.UnsafeCreate(typeof(T), Memory, address + i * TypeHelper <T> .SizeOf); } } else if (TypeHelper <T> .IsMemoryPointerType) { var buffer = new byte[count * PointerSize]; UnsafeReadBytes(address, buffer, 0, buffer.Length); var bufferReader = new BufferMemoryReader(buffer, 0, buffer.Length, PointerSize); for (int i = 0; i < count; i++) { array[i] = (T)(object)MemoryPointerFactory.UnsafeCreate <T>(Memory, bufferReader.ReadMemoryAddress(i * PointerSize)); } } else if (TypeHelper <T> .IsMemoryAddressType) { for (int i = 0; i < count; i++) { array[i] = (T)(object)ReadMemoryAddress(address + i * PointerSize); } } else { throw new NotSupportedException(); } return(array); }
public void UnsafeReadBytes(MemoryAddress address, byte[] buffer, int offset, int count) { _sw.Restart(); UnsafeReadBytesCore(address, buffer, offset, count); _sw.Stop(); TotalReadCount++; TotalReadSize += (ulong)count; TotalReadTime = TotalReadTime.Add(_sw.Elapsed); }
protected unsafe override void UnsafeReadBytesCore(MemoryAddress address, byte[] buffer, int offset, int count) { fixed(byte *pBuffer = &buffer[offset]) { if (!Win32.ReadProcessMemory(_process.Handle, address, pBuffer, count, IntPtr.Zero)) { throw new Win32Exception(); } } }
public ProcessMemoryReader(Process process) { if (process == null) throw new ArgumentNullException("process"); if (process.HasExited) throw new ArgumentException("process"); _process = process; _minValidAddress = 0x00010000; _maxValidAddress = process.IsLargeAddressAware() ? 0xBFFF0000 : 0x7FFEFFFF; _pointerSize = process.Is64BitProcess() ? 8 : 4; }
public bool TryReadByte(MemoryAddress address, out byte b) { int page; if (TryGetPageIndex(address, out page)) { _fileStream.Position = (long)_pages[page].TranslateToRva(address); b = (byte)_fileStream.ReadByte(); return(true); } b = 0; return(false); }
public static MemoryObject Create(Type type, MemoryReader reader, MemoryAddress address) { if (reader == null) { throw new ArgumentNullException("reader"); } if (reader.Memory == null) { throw new ArgumentException("reader"); } return(Create(type, reader.Memory, address)); }
public static T Create <T>(MemoryReader reader, MemoryAddress address) where T : MemoryObject { if (reader == null) { throw new ArgumentNullException("reader"); } if (reader.Memory == null) { throw new ArgumentException("reader"); } return(Create <T>(reader.Memory, address)); }
protected internal virtual MemoryAddress ReadMemoryAddress(MemoryAddress address) { if (PointerSize == 4) { return(Read <int>(address)); } else if (PointerSize == 8) { return(Read <long>(address)); } else { throw new NotSupportedException(); } }
public StringPointer(IMemory memory, MemoryAddress value, int maxLength, Encoding encoding) : base(memory, value) { if (maxLength < 0) { throw new ArgumentOutOfRangeException("maxLength"); } if (encoding == null) { throw new ArgumentNullException("encoding"); } MaxLength = maxLength; Encoding = encoding; }
public string ReadString(MemoryAddress address, int maxLength, Encoding encoding) { if (encoding == null) { throw new ArgumentNullException("encoding"); } var buffer = ReadBytes(address, maxLength); int count = 0; // Get the index of NULL-terminator, or use maxLength if none is found. while (count < maxLength && buffer[count] != 0) { count++; } return(encoding.GetString(buffer, 0, count)); }
public ProcessMemoryReader(Process process) { if (process == null) { throw new ArgumentNullException("process"); } if (process.HasExited) { throw new ArgumentException("process"); } _process = process; _minValidAddress = 0x00010000; _maxValidAddress = process.IsLargeAddressAware() ? 0xBFFF0000 : 0x7FFEFFFF; _pointerSize = process.Is64BitProcess() ? 8 : 4; }
public void ReadBytes(MemoryAddress address, byte[] buffer) { if (!IsValidAddress(address)) { throw new ArgumentOutOfRangeException("address"); } if (buffer == null) { throw new ArgumentNullException("buffer"); } if (!IsValidAddress(address + buffer.Length)) { throw new ArgumentException(); } UnsafeReadBytes(address, buffer, 0, buffer.Length); }
public override void UnsafeReadBytes(MemoryAddress address, byte[] buffer, int offset, int count) { var pageFrom = GetPageIndex(address); var pageTo = GetPageIndex(address + count); if (pageFrom == pageTo) { _fileStream.Position = _pages[pageFrom].TranslateToRva(address); _fileStream.Read(buffer, offset, count); } else { // Have never found data contained in multiple pages, so not implemented yet. // TODO: Determine if this would be an error or not, implement if not. throw new NotImplementedException(); } }
public static object UnsafeCreate <T>(IMemory memory, MemoryAddress value) { if (TypeHelper <T> .IsVoidMemoryPointerType) { return(new Ptr(memory, value)); } else if (TypeHelper <T> .IsStringPointerType) { return(new StringPointer(memory, value)); } else if (TypeHelper <T> .IsGenericType) { return(MemoryPointerActivatorCache <T> .Activator.Invoke(memory, value)); } else { throw new NotSupportedException(); } }
public T Read <T>(MemoryAddress address) { var snapshotAddress = ToSnapshotAddress(address); if (TypeHelper <T> .IsMemoryObjectType) { var value = BaseMemory.Reader.Read <T>(address); (value as MemoryObject).SetSnapshot( SnapshotReader.Segment.Array, SnapshotReader.Segment.Offset + snapshotAddress, SnapshotReader.Segment.Array.Length - (SnapshotReader.Segment.Offset + snapshotAddress)); return(value); } else if (TypeHelper <T> .IsMemoryPointerType) { // It is important that a pointer doesn't get a snapshot as context! return((T)MemoryPointerFactory.Create <T>(BaseMemory, SnapshotReader.ReadMemoryAddress(snapshotAddress))); } return(SnapshotReader.Read <T>(snapshotAddress)); }
public static T UnsafeCreate <T>(IMemory memory, MemoryAddress address) where T : MemoryObject { return((T)MemoryObjectActivatorCache <T> .Activator.Invoke(memory, address)); }
public static T UnsafeCreate <T>(MemoryReader reader, MemoryAddress address) where T : MemoryObject { return((T)MemoryObjectActivatorCache <T> .Activator.Invoke(reader.Memory, address)); }
public static MemoryObject UnsafeCreate(Type type, IMemory memory, MemoryAddress address) { return(GetOrCreateActivator(type).Invoke(memory, address)); }
public override void UnsafeReadBytes(MemoryAddress address, byte[] buffer, int offset, int count) { _fileStream.Position = address; _fileStream.Read(buffer, offset, count); }
public override void UnsafeReadBytes(MemoryAddress address, byte[] buffer, int offset, int count) { Buffer.BlockCopy(Segment.Array, Segment.Offset + address, buffer, offset, count); }