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)); }
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); }