コード例 #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MemoryRegionFinder"/> class.
        /// </summary>
        /// <param name="regions">The memory regions.</param>
        public MemoryRegionFinder(IReadOnlyList <MemoryRegion> regions)
        {
            if (regions.Count > 0)
            {
                ulong minValue = regions[0].MemoryStart;
                ulong maxValue = regions[regions.Count - 1].MemoryEnd;

                triesStartBits = 64 - BucketSizeBits;
                triesStartMask = ((1UL << BucketSizeBits) - 1) << triesStartBits;
                while ((triesStartMask & (maxValue - 1)) == 0)
                {
                    triesStartMask >>= BucketSizeBits;
                    triesStartBits  -= BucketSizeBits;
                }

                Tuple <int, MemoryRegion>[] regionsTuple = new Tuple <int, MemoryRegion> [regions.Count];
                for (int i = 0; i < regionsTuple.Length; i++)
                {
                    regionsTuple[i] = Tuple.Create(i, regions[i]);
                }
                TriesElement element = new TriesElement(regionsTuple, triesStartMask, triesStartBits);

                buckets = element.buckets;
                if (buckets == null)
                {
                    buckets = new TriesElement[] { element };
                }
            }
            else
            {
                buckets = new TriesElement[0];
            }
        }
コード例 #2
0
        /// <summary>
        /// Finds the index of memory region where the specified address is located or -1 if not found.
        /// </summary>
        /// <param name="address">The address.</param>
        /// <returns>The index of memory region where the specified address is located or -1 if not found.</returns>
        public int Find(ulong address)
        {
            ulong mask        = triesStartMask;
            int   offset      = triesStartBits;
            ulong bucketIndex = (address & mask) >> offset;

            if (bucketIndex < (ulong)buckets.LongLength)
            {
                TriesElement bucket = buckets[bucketIndex];

                while (bucket != null && bucket.buckets != null)
                {
                    mask      >>= BucketSizeBits;
                    offset     -= BucketSizeBits;
                    bucketIndex = (address & mask) >> offset;
                    bucket      = bucket.buckets[bucketIndex];
                }

                if (bucket != null)
                {
                    return(bucket.location);
                }
            }

            return(-1);
        }
コード例 #3
0
ファイル: MemoryRegion.cs プロジェクト: leculver/WinDbgCs
            public TriesElement(IReadOnlyList <Tuple <int, MemoryRegion> > regions, ulong triesStartMask, int triesStartBits, ulong minValue = 0, ulong maxValue = ulong.MaxValue)
            {
                if (regions.Count > 1)
                {
                    var division = new List <Tuple <int, MemoryRegion> > [1 << BucketSizeBits];

                    foreach (var region in regions)
                    {
                        ulong bucketStart = (Math.Max(minValue, region.Item2.MemoryStart) & triesStartMask) >> triesStartBits;
                        ulong bucketEnd   = (Math.Min(maxValue, region.Item2.MemoryEnd - 1) & triesStartMask) >> triesStartBits;

                        for (ulong j = bucketStart; j <= bucketEnd; j++)
                        {
                            if (division[j] == null)
                            {
                                division[j] = new List <Tuple <int, MemoryRegion> >();
                            }
                            division[j].Add(region);
                        }
                    }

                    buckets = new TriesElement[1 << BucketSizeBits];
                    for (int i = 0; i < 1 << BucketSizeBits; i++)
                    {
                        if (division[i] != null)
                        {
                            buckets[i] = new TriesElement(division[i], triesStartMask >> BucketSizeBits, triesStartBits - BucketSizeBits, minValue | ((ulong)i << triesStartBits), minValue | (((ulong)i + 1) << triesStartBits) - 1);
                        }
                    }
                }
                else
                {
                    location = regions[0].Item1;
                }
            }
コード例 #4
0
            public TriesElement(IEnumerable <Tuple <int, MemoryLocation> > ranges, ulong triesStartMask, int triesStartBits, ulong minValue = 0, ulong maxValue = ulong.MaxValue)
            {
                if (ranges.Count() > 1)
                {
                    var division = new List <Tuple <int, MemoryLocation> > [1 << BucketSizeBits];

                    foreach (var range in ranges)
                    {
                        var bucketStart = (Math.Max(minValue, range.Item2.MemoryStart) & triesStartMask) >> triesStartBits;
                        var bucketEnd   = (Math.Min(maxValue, range.Item2.MemoryEnd - 1) & triesStartMask) >> triesStartBits;

                        for (var j = bucketStart; j <= bucketEnd; j++)
                        {
                            if (division[j] == null)
                            {
                                division[j] = new List <Tuple <int, MemoryLocation> >();
                            }
                            division[j].Add(range);
                        }
                    }

                    buckets = new TriesElement[1 << BucketSizeBits];
                    for (int i = 0; i < 1 << BucketSizeBits; i++)
                    {
                        if (division[i] != null)
                        {
                            buckets[i] = new TriesElement(division[i], triesStartMask >> BucketSizeBits, triesStartBits - BucketSizeBits, minValue | ((ulong)i << triesStartBits), minValue | (((ulong)i + 1) << triesStartBits) - 1);
                        }
                    }
                }
                else
                {
                    location = ranges.First().Item1;
                }
            }
コード例 #5
0
ファイル: MemoryRegion.cs プロジェクト: leculver/WinDbgCs
        /// <summary>
        /// Initializes a new instance of the <see cref="MemoryRegionFinder"/> class.
        /// </summary>
        /// <param name="regions">The memory regions.</param>
        public MemoryRegionFinder(MemoryRegion[] regions)
        {
            ulong minValue = regions[0].MemoryStart;
            ulong maxValue = regions[regions.Length - 1].MemoryEnd;

            triesStartBits = 64 - BucketSizeBits;
            triesStartMask = ((1UL << BucketSizeBits) - 1) << triesStartBits;
            while ((triesStartMask & (maxValue - 1)) == 0)
            {
                triesStartMask >>= BucketSizeBits;
                triesStartBits  -= BucketSizeBits;
            }

            Tuple <int, MemoryRegion>[] regionsTuple = new Tuple <int, MemoryRegion> [regions.Length];
            for (int i = 0; i < regionsTuple.Length; i++)
            {
                regionsTuple[i] = Tuple.Create(i, regions[i]);
            }
            TriesElement element = new TriesElement(regionsTuple, triesStartMask, triesStartBits);

            buckets = element.buckets;
        }
コード例 #6
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MemoryRegionFinder"/> class.
        /// </summary>
        /// <param name="regions">The memory regions.</param>
        public MemoryRegionFinder(MemoryRegion[] regions)
        {
            ulong minValue = regions[0].MemoryStart;
            ulong maxValue = regions[regions.Length - 1].MemoryEnd;

            triesStartBits = 64 - BucketSizeBits;
            triesStartMask = ((1UL << BucketSizeBits) - 1) << triesStartBits;
            while ((triesStartMask & (maxValue - 1)) == 0)
            {
                triesStartMask >>= BucketSizeBits;
                triesStartBits -= BucketSizeBits;
            }

            Tuple<int, MemoryRegion>[]regionsTuple = new Tuple<int, MemoryRegion>[regions.Length];
            for (int i = 0; i < regionsTuple.Length; i++)
                regionsTuple[i] = Tuple.Create(i, regions[i]);
            TriesElement element = new TriesElement(regionsTuple, triesStartMask, triesStartBits);

            buckets = element.buckets;
        }
コード例 #7
0
            public TriesElement(IReadOnlyList<Tuple<int, MemoryRegion>> regions, ulong triesStartMask, int triesStartBits, ulong minValue = 0, ulong maxValue = ulong.MaxValue)
            {
                if (regions.Count > 1)
                {
                    var division = new List<Tuple<int, MemoryRegion>>[1 << BucketSizeBits];

                    foreach (var region in regions)
                    {
                        ulong bucketStart = (Math.Max(minValue, region.Item2.MemoryStart) & triesStartMask) >> triesStartBits;
                        ulong bucketEnd = (Math.Min(maxValue, region.Item2.MemoryEnd - 1) & triesStartMask) >> triesStartBits;

                        for (ulong j = bucketStart; j <= bucketEnd; j++)
                        {
                            if (division[j] == null)
                                division[j] = new List<Tuple<int, MemoryRegion>>();
                            division[j].Add(region);
                        }
                    }

                    buckets = new TriesElement[1 << BucketSizeBits];
                    for (int i = 0; i < 1 << BucketSizeBits; i++)
                        if (division[i] != null)
                            buckets[i] = new TriesElement(division[i], triesStartMask >> BucketSizeBits, triesStartBits - BucketSizeBits, minValue | ((ulong)i << triesStartBits), minValue | (((ulong)i + 1) << triesStartBits) - 1);
                }
                else
                {
                    location = regions[0].Item1;
                }
            }
コード例 #8
0
        public DumpFileMemoryReader(string dumpFilePath)
        {
            bool                   dispose          = true;
            FileStream             fileStream       = null;
            MemoryMappedFile       memoryMappedFile = null;
            MemoryMappedViewStream stream           = null;

            try
            {
                fileStream       = new FileStream(dumpFilePath, FileMode.Open, FileAccess.Read);
                memoryMappedFile = MemoryMappedFile.CreateFromFile(fileStream, Guid.NewGuid().ToString(), fileStream.Length, MemoryMappedFileAccess.Read, new MemoryMappedFileSecurity(), HandleInheritability.Inheritable, false);
                stream           = memoryMappedFile.CreateViewStream(0, fileStream.Length, MemoryMappedFileAccess.Read);

                stream.SafeMemoryMappedViewHandle.AcquirePointer(ref basePointer);
                IntPtr             streamPointer = IntPtr.Zero;
                uint               streamSize    = 0;
                MINIDUMP_DIRECTORY directory     = new MINIDUMP_DIRECTORY();

                if (!MiniDumpReadDumpStream((IntPtr)basePointer, MINIDUMP_STREAM_TYPE.Memory64ListStream, ref directory, ref streamPointer, ref streamSize))
                {
                    throw new Exception("Unable to read mini dump stream");
                }

                var   data    = (MINIDUMP_MEMORY64_LIST)Marshal.PtrToStructure(streamPointer, typeof(MINIDUMP_MEMORY64_LIST));
                ulong lastEnd = data.BaseRva;

                ranges = new MemoryLocation[data.NumberOfMemoryRanges];
                for (int i = 0; i < ranges.Length; i++)
                {
                    var descriptor = (MINIDUMP_MEMORY_DESCRIPTOR64)Marshal.PtrToStructure(streamPointer + sizeof(MINIDUMP_MEMORY64_LIST) + i * sizeof(MINIDUMP_MEMORY_DESCRIPTOR64), typeof(MINIDUMP_MEMORY_DESCRIPTOR64));
                    ranges[i] = new MemoryLocation()
                    {
                        MemoryStart  = descriptor.StartOfMemoryRange,
                        MemoryEnd    = descriptor.StartOfMemoryRange + descriptor.DataSize,
                        FilePosition = lastEnd,
                    };
                    lastEnd += descriptor.DataSize;
                }

                int newEnd = 0;
                for (int i = 1; i < ranges.Length; i++)
                {
                    if (ranges[i].MemoryStart == ranges[newEnd].MemoryEnd)
                    {
                        ranges[newEnd].MemoryEnd = ranges[i].MemoryEnd;
                    }
                    else
                    {
                        ranges[++newEnd] = ranges[i];
                    }
                }
                newEnd++;
                Array.Resize(ref ranges, newEnd);
                var minValue = ranges[0].MemoryStart;
                var maxValue = ranges[ranges.Length - 1].MemoryEnd;

                triesStartBits = 64 - BucketSizeBits;
                triesStartMask = ((1UL << BucketSizeBits) - 1) << triesStartBits;
                while ((triesStartMask & (maxValue - 1)) == 0)
                {
                    triesStartMask >>= BucketSizeBits;
                    triesStartBits  -= BucketSizeBits;
                }

                var rangesTuple = new Tuple <int, MemoryLocation> [ranges.Length];
                for (int i = 0; i < rangesTuple.Length; i++)
                {
                    rangesTuple[i] = Tuple.Create(i, ranges[i]);
                }
                var element = new TriesElement(rangesTuple, triesStartMask, triesStartBits);

                buckets = element.buckets;
                dispose = false;
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex);
                throw;
            }
            finally
            {
                if (dispose)
                {
                    stream.SafeMemoryMappedViewHandle.ReleasePointer();
                    if (stream != null)
                    {
                        stream.Dispose();
                    }

                    if (memoryMappedFile != null)
                    {
                        memoryMappedFile.Dispose();
                    }

                    if (fileStream != null)
                    {
                        fileStream.Dispose();
                    }
                }
                else
                {
                    this.fileStream       = fileStream;
                    this.stream           = stream;
                    this.memoryMappedFile = memoryMappedFile;
                }
            }
        }