예제 #1
0
        public int GetChunkContainingAddress(ulong address)
        {
            MinidumpMemoryChunk targetChunk = new MinidumpMemoryChunk {
                TargetStartAddress = address
            };
            int index = Array.BinarySearch(_chunks, targetChunk);

            if (index >= 0)
            {
                Debug.Assert(_chunks[index].TargetStartAddress == address);
                return(index); // exact match will contain the address
            }

            if (~index != 0)
            {
                int possibleIndex = Math.Min(_chunks.Length, ~index) - 1;
                if (_chunks[possibleIndex].TargetStartAddress <= address &&
                    _chunks[possibleIndex].TargetEndAddress > address)
                {
                    return(possibleIndex);
                }
            }

            return(-1);
        }
예제 #2
0
        public void InitFromMemoryList()
        {
            _memoryList = new MinidumpMemoryList(_dumpStream);
            uint count = _memoryList.Count;

            MINIDUMP_MEMORY_DESCRIPTOR tempMD;
            List <MinidumpMemoryChunk> chunks = new List <MinidumpMemoryChunk>();

            for (ulong i = 0; i < count; i++)
            {
                MinidumpMemoryChunk chunk = new MinidumpMemoryChunk();
                tempMD = _memoryList.GetElement((uint)i);
                if (tempMD.Memory.DataSize > 0)
                {
                    chunk.Size = tempMD.Memory.DataSize;
                    chunk.TargetStartAddress = tempMD.StartOfMemoryRange;
                    chunk.TargetEndAddress   = tempMD.StartOfMemoryRange + tempMD.Memory.DataSize;
                    chunk.RVA = tempMD.Memory.Rva.Value;
                    chunks.Add(chunk);
                }
            }

            chunks.Sort();
            SplitAndMergeChunks(chunks);
            _chunks = chunks.ToArray();
            Count   = (ulong)chunks.Count;

            ValidateChunks();
        }
예제 #3
0
        private void InitFromMemory64List()
        {
            _memory64List = new MinidumpMemory64List(_dumpStream);

            RVA64 currentRVA = _memory64List.BaseRva;
            ulong count      = _memory64List.Count;

            // Initialize all chunks.
            MINIDUMP_MEMORY_DESCRIPTOR64 tempMD;
            List <MinidumpMemoryChunk>   chunks = new List <MinidumpMemoryChunk>();

            for (ulong i = 0; i < count; i++)
            {
                tempMD = _memory64List.GetElement((uint)i);
                MinidumpMemoryChunk chunk = new MinidumpMemoryChunk
                {
                    Size = tempMD.DataSize,
                    TargetStartAddress = tempMD.StartOfMemoryRange,
                    TargetEndAddress   = tempMD.StartOfMemoryRange + tempMD.DataSize,
                    RVA = currentRVA.Value
                };

                currentRVA.Value += tempMD.DataSize;
                chunks.Add(chunk);
            }

            chunks.Sort();
            SplitAndMergeChunks(chunks);
            _chunks = chunks.ToArray();
            Count   = (ulong)chunks.Count;

            ValidateChunks();
        }
예제 #4
0
        private void SplitAndMergeChunks(List <MinidumpMemoryChunk> chunks)
        {
            for (int i = 1; i < chunks.Count; i++)
            {
                MinidumpMemoryChunk prevChunk = chunks[i - 1];
                MinidumpMemoryChunk curChunk  = chunks[i];

                // we already sorted
                Debug.Assert(prevChunk.TargetStartAddress <= curChunk.TargetStartAddress);

                // there is some overlap
                if (prevChunk.TargetEndAddress > curChunk.TargetStartAddress)
                {
                    // the previous chunk completely covers this chunk rendering it useless
                    if (prevChunk.TargetEndAddress >= curChunk.TargetEndAddress)
                    {
                        chunks.RemoveAt(i);
                        i--;
                    }
                    // previous chunk partially covers this one so we will remove the front
                    // of this chunk and resort it if needed
                    else
                    {
                        ulong overlap = prevChunk.TargetEndAddress - curChunk.TargetStartAddress;
                        curChunk.TargetStartAddress += overlap;
                        curChunk.RVA  += overlap;
                        curChunk.Size -= overlap;

                        // now that we changes the start address it might not be sorted anymore
                        // find the correct index
                        int newIndex = i;
                        for (; newIndex < chunks.Count - 1; newIndex++)
                        {
                            if (curChunk.TargetStartAddress <= chunks[newIndex + 1].TargetStartAddress)
                            {
                                break;
                            }
                        }

                        if (newIndex != i)
                        {
                            chunks.RemoveAt(i);
                            chunks.Insert(newIndex - 1, curChunk);
                            i--;
                        }
                    }
                }
            }
        }