private static byte[] ReadMemory(ulong address, ulong size) { var data = new byte[size]; _runtime.ReadMemory(address, data, (int)size, out var _); return(data); }
public int ReadVirtual(ulong addr, byte[] buffer, int requested, out int pRead) { int read; bool success = m_runtime.ReadMemory(addr, buffer, requested, out read); pRead = (int)read; return(success ? 0 : -1); }
private byte[] ReadBytes(ulong methodPtr, [NotNull] ClrRuntime runtime, int countToRead) { Assert.ArgumentNotNull(runtime, "runtime"); // TODO: AddOrMerge buffer reuse; var bytes = new byte[countToRead]; int readCount; runtime.ReadMemory(methodPtr, bytes, countToRead, out readCount); return(bytes); }
private List <byte[]> ReadHandles(ulong startAddress, uint count) { List <byte[]> result = new List <byte[]>(); for (uint i = 0; i < count; i++) { byte[] buffer = new byte[IntPtr.Size]; int bytesRead; if (_runtime.ReadMemory(startAddress, buffer, IntPtr.Size, out bytesRead) && bytesRead == IntPtr.Size) { result.Add(buffer); } else { throw new Exception($"Error reading memory at {startAddress}"); } startAddress += (ulong)IntPtr.Size; } return(result); }
/// <summary> /// Read data out of the target process. /// </summary> /// <param name="address">The address to start the read from.</param> /// <param name="buffer">The buffer to write memory to.</param> /// <param name="bytesRequested">How many bytes to read (must be less than/equal to buffer.Length)</param> /// <param name="bytesRead"> /// The number of bytes actually read out of the process. This will be less than /// bytes requested if the request falls off the end of an allocation. /// </param> /// <returns>False if the memory is not readable (free or no read permission), true if *some* memory was read.</returns> /// <inheritdoc /> public bool ReadMemory(ulong address, byte[] buffer, int bytesRequested, out int bytesRead) => Runtime.ReadMemory(address, buffer, bytesRequested, out bytesRead);
// Sample based on https://github.com/Microsoft/dotnetsamples/blob/master/Microsoft.Diagnostics.Runtime/CLRMD/docs/MachineCode.md // All the common code was copied from the MemStats project "dotnetsamples-master\Microsoft.Diagnostics.Runtime\CLRMD\MemStats\Program.cs" static void Main(string[] args) { string dump, dac; if (!TryParseArgs(args, out dump, out dac)) { Usage(); Environment.Exit(1); } try { // Create a ClrRuntime instance from the dump and dac location. The ClrRuntime // object represents a version of CLR loaded in the process. It contains data // such as the managed threads in the process, the AppDomains in the process, // the managed heap, and so on. //ClrRuntime runtime = CreateRuntime(dump, dac); // 1. Get the ClrType object for the type the method is on // 2. Get the ClrMethod object for the method // 3. Get the offset of the native code // 4. Compute the end address by mapping the IL instruction to addresses // 5. Disassemble the native code contained in that range (not provided by CLRMD) using (DataTarget dt = DataTarget.LoadCrashDump(dump)) { // Boilerplate. //ClrRuntime runtime = dt.CreateRuntime(dt.ClrVersions.Single().TryDownloadDac()); var version = dt.ClrVersions.Single(); //{v4.0.30319.18444} //version.Version = new VersionInfo { Major = 4, Minor = 0, Patch = 30319, Revision = 18444 }; Console.WriteLine("CLR Version: {0} ({1}), Dac: {2}", version.Version, version.Flavor, version.DacInfo); var dacFileName = version.TryDownloadDac(); Console.WriteLine("DacFile: " + Path.GetFileName(dacFileName)); Console.WriteLine("DacPath: " + Path.GetDirectoryName(dacFileName)); ClrRuntime runtime = dt.CreateRuntime(dacFileName); ClrHeap heap = runtime.GetHeap(); PrintDiagnosticInfo(dt, runtime, heap); Console.WriteLine(); // Note heap.GetTypeByName doesn't always get you the type, even if it exists, due to // limitations in the dac private apis that ClrMD is written on. If you have the ClrType // already via other means (heap walking, stack walking, etc), then that's better than // using GetTypeByName: var classNameWithNamespace = "JITterOptimisations.Program"; ClrType @class = heap.GetTypeByName(classNameWithNamespace); // Get the method you are looking for. var signature = "JITterOptimisations.Program.Log(System.ConsoleColor, System.String)"; ClrMethod @method = @class.Methods.Single(m => m.GetFullSignature() == signature); // This is the first instruction of the JIT'ed (or NGEN'ed) machine code. ulong startAddress = @method.NativeCode; // Unfortunately there's not a great way to get the size of the code, or the end address. // This is partly due to the fact that we don't *have* to put all the JIT'ed code into one // contiguous chunk, though I think an implementation detail is that we actually do. // You are supposed to do code flow analysis like "uf" in windbg to find the size, but // in practice you can use the IL to native mapping: ulong endAddress = @method.ILOffsetMap.Select(entry => entry.EndAddress).Max(); var lines = File.ReadAllLines( @"C:\Users\warma11\Documents\Visual Studio 2013\Projects\JITterOptimisations\JITterOptimisations\Program.cs"); PrintILToNativeOffsetAlternative(method, lines); // This doesn't seem to work as expected, using alternative method (above) //PrintILToNativeOffsets(method, startAddress, lines); // So the assembly code for the function is is in the range [startAddress, endAddress] inclusive. var count = (int)endAddress + runtime.PointerSize - (int)startAddress; Console.WriteLine("\nCode startAddress 0x{0:X} -> endAddress 0x{1:X} (inclusive), will read {2} bytes", startAddress, endAddress, count); var bytes = new byte[count]; int bytesRead; runtime.ReadMemory(startAddress, bytes, count, out bytesRead); if (count != bytesRead) { Console.WriteLine("Expected to read {0} bytes, but only read {1}\n", count, bytesRead); } else { Console.WriteLine("Read read {0} bytes, as expected\n", bytesRead); } var fileName = string.Format("result-{0}bit.bin", runtime.PointerSize == 8 ? 64 : 32); if (File.Exists(fileName)) { File.Delete(fileName); } File.WriteAllBytes(fileName, bytes); var filename = @"C:\Users\warma11\Downloads\__GitHub__\dotnetsamples\Microsoft.Diagnostics.Runtime\CLRMD\MachineCode\nasm-2.11.05-win32\ndisasm.exe"; var currentFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); var arguments = "-b32 " + Path.Combine(currentFolder, fileName); // +" -o " + startAddress; var disassembly = Disassembler.GetDisassembly(filename, arguments, timeoutMsecs: 250); var assemblyData = Disassembler.ProcessDisassembly(disassembly); } } catch (Exception ex) { Console.WriteLine("Unhandled exception:"); Console.WriteLine(ex); } }