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.");
                }
            }
        }
Example #2
0
        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));
        }
Example #3
0
        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;
            }
        }
Example #5
0
        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;
        }
Example #6
0
        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);
        }
Example #7
0
        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);
 }
Example #9
0
        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);
        }
Example #11
0
        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));
        }
Example #15
0
        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);
        }
Example #16
0
        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();
         }
     }
 }
Example #18
0
        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);
        }
Example #20
0
        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));
        }
Example #21
0
        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));
        }
Example #22
0
 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();
     }
 }
Example #23
0
        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;
        }
Example #24
0
        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));
        }
Example #25
0
        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;
        }
Example #26
0
        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);
        }
Example #27
0
        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();
     }
 }
Example #29
0
        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));
        }
Example #30
0
 public static T UnsafeCreate <T>(IMemory memory, MemoryAddress address) where T : MemoryObject
 {
     return((T)MemoryObjectActivatorCache <T> .Activator.Invoke(memory, address));
 }
Example #31
0
 public static T UnsafeCreate <T>(MemoryReader reader, MemoryAddress address) where T : MemoryObject
 {
     return((T)MemoryObjectActivatorCache <T> .Activator.Invoke(reader.Memory, address));
 }
Example #32
0
 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);
		}
Example #34
0
 public override void UnsafeReadBytes(MemoryAddress address, byte[] buffer, int offset, int count)
 {
     Buffer.BlockCopy(Segment.Array, Segment.Offset + address, buffer, offset, count);
 }