private MetadataRegion FindRegion(ulong address)
        {
            if (!_regionInitialized)
            {
                // Need to set this before enumerating the runtimes to prevent reentrancy
                _regionInitialized = true;

                var runtimes = RuntimeService.EnumerateRuntimes();
                if (runtimes.Any())
                {
                    foreach (IRuntime runtime in runtimes)
                    {
                        Trace.TraceInformation($"FindRegion: initializing regions for runtime #{runtime.Id}");
                        ClrRuntime clrRuntime = runtime.Services.GetService <ClrRuntime>();
                        if (clrRuntime != null)
                        {
                            Trace.TraceInformation($"FindRegion: initializing regions for CLR runtime #{runtime.Id}");
                            _regions = clrRuntime.EnumerateModules()
                                       .Where((module) => module.MetadataAddress != 0 && module.IsPEFile && !module.IsDynamic)
                                       .Select((module) => new MetadataRegion(this, module))
                                       .ToImmutableArray()
                                       .Sort();
                        }
                    }
                }
                else
                {
                    // If there are no runtimes, try again next time around
                    _regionInitialized = false;
                }
            }

            if (_regions != null)
            {
                int min = 0, max = _regions.Length - 1;
                while (min <= max)
                {
                    int            mid    = (min + max) / 2;
                    MetadataRegion region = _regions[mid];

                    if (address >= region.StartAddress && address < region.EndAddress)
                    {
                        return(region);
                    }

                    if (region.StartAddress < address)
                    {
                        min = mid + 1;
                    }
                    else
                    {
                        max = mid - 1;
                    }
                }
            }

            return(null);
        }
 /// <summary>
 /// Read memory out of the target process.
 /// </summary>
 /// <param name="address">The address of memory to read</param>
 /// <param name="buffer">The buffer to read memory into</param>
 /// <param name="bytesRead">The number of bytes actually read out of the target process</param>
 /// <returns>true if any bytes were read at all, false if the read failed (and no bytes were read)</returns>
 public bool ReadMemory(ulong address, Span <byte> buffer, out int bytesRead)
 {
     Debug.Assert((address & ~_memoryService.SignExtensionMask()) == 0);
     if (buffer.Length > 0)
     {
         MetadataRegion region = FindRegion(address);
         if (region != null)
         {
             if (region.ReadMetaData(address, buffer, out bytesRead))
             {
                 return(true);
             }
         }
     }
     return(_memoryService.ReadMemory(address, buffer, out bytesRead));
 }
Beispiel #3
0
        private MetadataRegion FindRegion(ulong address)
        {
            if (!_regionInitialized)
            {
                _regionInitialized = true;

                Trace.TraceInformation($"FindRegion: initializing regions for runtime #{_runtime.Id}");
                ClrRuntime clrruntime = _runtime.Services.GetService <ClrRuntime>();
                if (clrruntime != null)
                {
                    _regions = clrruntime.EnumerateModules()
                               .Where((module) => module.MetadataAddress != 0 && module.IsPEFile && !module.IsDynamic)
                               .Select((module) => new MetadataRegion(this, module))
                               .ToImmutableArray()
                               .Sort();
                }
            }

            if (_regions != null)
            {
                int min = 0, max = _regions.Length - 1;
                while (min <= max)
                {
                    int            mid    = (min + max) / 2;
                    MetadataRegion region = _regions[mid];

                    if (address >= region.StartAddress && address < region.EndAddress)
                    {
                        return(region);
                    }

                    if (region.StartAddress < address)
                    {
                        min = mid + 1;
                    }
                    else
                    {
                        max = mid - 1;
                    }
                }
            }

            return(null);
        }