internal ulong ReadPointerUnsafe(ulong addr) { int chunkIndex = _memoryChunks.GetChunkContainingAddress(addr); if (chunkIndex == -1) { return(0); } DumpPointer chunk = TranslateRVA(_memoryChunks.RVA((uint)chunkIndex)); ulong offset = addr - _memoryChunks.StartAddress((uint)chunkIndex); if (IntPtr.Size == 4) { return(chunk.Adjust(offset).GetDword()); } return(chunk.Adjust(offset).GetUlong()); }
public virtual int ReadPartialMemory(ulong targetRequestStart, byte[] destinationBuffer, int bytesRequested) { EnsureValid(); if (bytesRequested <= 0) { return(0); } if (bytesRequested > destinationBuffer.Length) { bytesRequested = destinationBuffer.Length; } int bytesRead = 0; do { int chunkIndex = _memoryChunks.GetChunkContainingAddress(targetRequestStart + (uint)bytesRead); if (chunkIndex == -1) { break; } DumpPointer pointerCurrentChunk = TranslateRVA(_memoryChunks.RVA((uint)chunkIndex)); ulong startAddr = targetRequestStart + (uint)bytesRead - _memoryChunks.StartAddress((uint)chunkIndex); ulong bytesAvailable = _memoryChunks.Size((uint)chunkIndex) - startAddr; Debug.Assert(bytesRequested >= bytesRead); int bytesToCopy = bytesRequested - bytesRead; if (bytesAvailable < (uint)bytesToCopy) { bytesToCopy = (int)bytesAvailable; } Debug.Assert(bytesToCopy > 0); if (bytesToCopy == 0) { break; } pointerCurrentChunk.Adjust(startAddr).Copy(destinationBuffer, bytesRead, bytesToCopy); bytesRead += bytesToCopy; } while (bytesRead < bytesRequested); return(bytesRead); }
/// <summary> /// Gets a MINIDUMP_STRING at the given DumpPointer as an System.String. /// </summary> /// <param name="ptr">DumpPointer to a MINIDUMP_STRING</param> /// <returns> /// System.String representing contents of MINIDUMP_STRING at the given location /// in the dump /// </returns> protected internal string GetString(DumpPointer ptr) { EnsureValid(); // Minidump string is defined as: // typedef struct _MINIDUMP_STRING { // ULONG32 Length; // Length in bytes of the string // WCHAR Buffer [0]; // Variable size buffer // } MINIDUMP_STRING, *PMINIDUMP_STRING; int lengthBytes = ptr.ReadInt32(); ptr = ptr.Adjust(4); // move past the Length field int lengthChars = lengthBytes / 2; string s = ptr.ReadAsUnicodeString(lengthChars); return(s); }
// Since a MemoryListStream makes no guarantees that there aren't duplicate, overlapping, or wholly contained // memory regions, we need to handle that. For the purposes of this code, we presume all memory regions // in the dump that cover a given VA have the correct (duplicate) contents. protected uint ReadPartialMemoryInternal( ulong targetRequestStart, IntPtr destinationBuffer, uint destinationBufferSizeInBytes, uint startIndex) { EnsureValid(); if (destinationBufferSizeInBytes == 0) { return(0); } uint bytesRead = 0; do { int chunkIndex = _memoryChunks.GetChunkContainingAddress(targetRequestStart + bytesRead); if (chunkIndex == -1) { break; } DumpPointer pointerCurrentChunk = TranslateRVA(_memoryChunks.RVA((uint)chunkIndex)); uint idxStart = (uint)(targetRequestStart + bytesRead - _memoryChunks.StartAddress((uint)chunkIndex)); uint bytesAvailable = (uint)_memoryChunks.Size((uint)chunkIndex) - idxStart; uint bytesNeeded = destinationBufferSizeInBytes - bytesRead; uint bytesToCopy = Math.Min(bytesAvailable, bytesNeeded); Debug.Assert(bytesToCopy > 0); if (bytesToCopy == 0) { break; } IntPtr dest = new IntPtr(destinationBuffer.ToInt64() + bytesRead); uint destSize = destinationBufferSizeInBytes - bytesRead; pointerCurrentChunk.Adjust(idxStart).Copy(dest, destSize, bytesToCopy); bytesRead += bytesToCopy; } while (bytesRead < destinationBufferSizeInBytes); return(bytesRead); }