Esempio n. 1
0
    private static byte[] ReadMemory(ulong address, ulong size)
    {
        var data = new byte[size];

        _runtime.ReadMemory(address, data, (int)size, out var _);
        return(data);
    }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        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);
        }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
 /// <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);
Esempio n. 6
0
        // 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);
            }
        }