public NativeRuntime(ClrInfo info, DataTargetImpl dt, DacLibrary lib)
            : base(info, dt, lib)
        {
            byte[] tmp = new byte[sizeof(int)];

            if (!Request(DacRequests.VERSION, null, tmp))
                throw new ClrDiagnosticsException("Failed to request dac version.", ClrDiagnosticsException.HR.DacError);

            _dacRawVersion = BitConverter.ToInt32(tmp, 0);
            if (_dacRawVersion != 10 && _dacRawVersion != 11)
                throw new ClrDiagnosticsException("Unsupported dac version.", ClrDiagnosticsException.HR.DacError);
        }
Example #2
0
        public V45Runtime(ClrInfo info, DataTargetImpl dt, DacLibrary lib)
            : base(info, dt, lib)
        {
            if (!GetCommonMethodTables(ref _commonMTs))
                throw new ClrDiagnosticsException("Could not request common MethodTable list.", ClrDiagnosticsException.HR.DacError);

            // Ensure the version of the dac API matches the one we expect.  (Same for both
            // v2 and v4 rtm.)
            byte[] tmp = new byte[sizeof(int)];

            if (!Request(DacRequests.VERSION, null, tmp))
                throw new ClrDiagnosticsException("Failed to request dac version.", ClrDiagnosticsException.HR.DacError);

            int v = BitConverter.ToInt32(tmp, 0);
            if (v != 9)
                throw new ClrDiagnosticsException("Unsupported dac version.", ClrDiagnosticsException.HR.DacError);
        }
        private DiagnosticAnalyzer(DataTarget dataTarget, bool cacheObjects)
        {
            _dataTarget     = dataTarget;
            CacheAllObjects = cacheObjects;
            //_dataTarget.BinaryLocator.FindBinary()

            if (_dataTarget.ClrVersions.Length == 0)
            {
                throw new Exception("No compatible CLR has been found on this machine");
            }

            if (_dataTarget.ClrVersions.Length > 1)
            {
                Debug.WriteLine("Multiple compatible CLR have been found on this machine, picking the first of the following list");
                foreach (var version in _dataTarget.ClrVersions)
                {
                    var dacFilename = version.DacInfo.PlatformSpecificFileName;
                    var moduleInfo  = version.ModuleInfo;
                    Debug.WriteLine("CLR Version: " + version.Version);
                    Debug.WriteLine("Filesize:  {0:X}", moduleInfo.IndexFileSize);
                    Debug.WriteLine("Timestamp: {0:X}", moduleInfo.IndexTimeStamp);
                    Debug.WriteLine("Dac File:  {0}", dacFilename);
                    Debug.WriteLine("");
                }
            }

            _clrInfo = _dataTarget.ClrVersions[0];
            if (_clrInfo.DacInfo.LocalDacPath == null)
            {
                throw new Exception("The runtime used in the dump cannot be found on this installation");
            }

            _clrLocation = new FileInfo(_clrInfo.DacInfo.LocalDacPath);
            _clrRuntime  = _clrInfo.CreateRuntime();
            _dacInfo     = _clrInfo.DacInfo;

            PrepareGCRootCache();
        }
Example #4
0
        private static ClrRuntime CreateRuntime(string dump, string dac)
        {
            // Create the data target.  This tells us the versions of CLR loaded in the target process.
            DataTarget dataTarget = DataTarget.LoadCrashDump(dump);

            // Now check bitness of our program/target:
            bool isTarget64Bit = dataTarget.PointerSize == 8;

            if (Environment.Is64BitProcess != isTarget64Bit)
            {
                throw new Exception(string.Format("Architecture mismatch:  Process is {0} but target is {1}", Environment.Is64BitProcess ? "64 bit" : "32 bit", isTarget64Bit ? "64 bit" : "32 bit"));
            }

            // Note I just take the first version of CLR in the process.  You can loop over every loaded
            // CLR to handle the SxS case where both v2 and v4 are loaded in the process.
            ClrInfo version = dataTarget.ClrVersions[0];

            // Next, let's try to make sure we have the right Dac to load.  Note we are doing this manually for
            // illustration.  Simply calling version.CreateRuntime with no arguments does the same steps.
            if (dac != null && Directory.Exists(dac))
            {
                dac = Path.Combine(dac, version.DacInfo.FileName);
            }
            else if (dac == null || !File.Exists(dac))
            {
                dac = dataTarget.SymbolLocator.FindBinary(version.DacInfo);
            }

            // Finally, check to see if the dac exists.  If not, throw an exception.
            if (dac == null || !File.Exists(dac))
            {
                throw new FileNotFoundException("Could not find the specified dac.", dac);
            }

            // Now that we have the DataTarget, the version of CLR, and the right dac, we create and return a
            // ClrRuntime instance.
            return(version.CreateRuntime(dac));
        }
Example #5
0
        private static ClrRuntime CreateRuntime(int pid)
        {
            // Create the data target.  This tells us the versions of CLR loaded in the target process.
            DataTarget dataTarget = DataTarget.AttachToProcess(pid, 60000, AttachFlag.Passive);

            dataTarget.SymbolLocator.SymbolPath = Environment.GetEnvironmentVariable("_NT_SYMBOL_PATH");

            // Now check bitness of our program/target:
            bool isTarget64Bit = dataTarget.PointerSize == 8;

            if (Environment.Is64BitProcess != isTarget64Bit)
            {
                throw new Exception(string.Format("Architecture mismatch:  Process is {0} but target is {1}", Environment.Is64BitProcess ? "64 bit" : "32 bit", isTarget64Bit ? "64 bit" : "32 bit"));
            }

            // Note I just take the first version of CLR in the process.  You can loop over every loaded
            // CLR to handle the SxS case where both v2 and v4 are loaded in the process.
            ClrInfo version = dataTarget.ClrVersions[0];

            // Now that we have the DataTarget, the version of CLR, and the right dac, we create and return a
            // ClrRuntime instance.
            return(version.CreateRuntime());
        }
Example #6
0
        public static ClrRuntime Createruntime(string dac, string dump)
        {
            // Create the data target.  This tells us the versions of CLR loaded in the target process.
            DataTarget dataTarget = DataTarget.LoadCrashDump(dump);

            // Now check bitness of our program/target:
            //bool isTarget64Bit = dataTarget.PointerSize == 8;
            //if (Environment.Is64BitProcess != isTarget64Bit)
            //{
            //    // f.resultobox.Text = throw new Exception(string.Format("Architecture mismatch:  Process is {0} but target is {1}", Environment.Is64BitProcess ? "64 bit" : "32 bit", isTarget64Bit ? "64 bit" : "32 bit"));
            //    MessageBox.Show(string.Format("Architecture mismatch:  Process is {0} but target is {1},Please check your setting and try again ,Ok will restart the app", Environment.Is64BitProcess ? "64 bit" : "32 bit", isTarget64Bit ? "64 bit" : "32 bit"));
            //    // Note I just take the first version of CLR in the process.  You can loop over every loaded
            //    // CLR to handle the SxS case where both v2 and v4 are loaded in the process.
            //    //System.Diagnostics.Process.Start(Application.ExecutablePath);

            //}
            ClrInfo runtimeInfo = dataTarget.ClrVersions[0];

            foreach (ClrInfo version in dataTarget.ClrVersions)
            {
                //Console.WriteLine("Found CLR Version: " + version);
                Form1.r = new Form1();



                r.resultobox.Clear();
                r.resultobox.up("Found CLR Version: " + version);

                r.Dispose();
                // This is the data needed to request the dac from the symbol server:
                //ModuleInfo dacInfo = version.DacInfo;
                //Console.WriteLine("Filesize:  {0:X}", dacInfo.FileSize);
                //Console.WriteLine("Timestamp: {0:X}", dacInfo.TimeStamp);
                //Console.WriteLine("Dac File:  {0}", dacInfo.FileName);
            }
            return(runtimeInfo.CreateRuntime(dac));
        }
Example #7
0
        public ClrRuntime Runtime()
        {
            if (File.Exists(mscrdwaksloc))
            {
                Console.WriteLine("using {0} for dac loc", mscrdwaksloc);
                DataTarget dataTarget  = DataTarget.LoadCrashDump(path);
                ClrInfo    runtimeInfo = dataTarget.ClrVersions[0];
                ClrRuntime runtime     = runtimeInfo.CreateRuntime(mscrdwaksloc);
                return(runtime);
            }



            if (!File.Exists(mscrdwaksloc))
            {
                DataTarget dataTarget  = DataTarget.LoadCrashDump(path);
                ClrInfo    runtimeInfo = dataTarget.ClrVersions[0];
                ClrRuntime runtime     = runtimeInfo.CreateRuntime();
                return(runtime);
            }


            return(null);
        }
Example #8
0
        private static void DumpThreadInfo(DataTarget dataTarget, ClrInfo clrVersion, ClrRuntime runtime, ClrAppDomain appDomain)
        {
            // Dump thread info
            Console.WriteLine("## Threads");
            Console.WriteLine("Thread count:   {0}", runtime.Threads.Count);
            Console.WriteLine("");
            foreach (var thread in runtime.Threads)
            {
                Console.WriteLine("### Thread {0}", thread.OSThreadId);
                Console.WriteLine("Thread type: {0}", thread.IsBackground
                    ? "Background"
                    : thread.IsGC
                        ? "GC"
                        : "Foreground");

                Console.WriteLine("");
                Console.WriteLine("Stack trace:");
                foreach (var stackFrame in thread.EnumerateStackTrace())
                {
                    Console.WriteLine("* {0}", stackFrame.DisplayString);
                }
                Console.WriteLine("");
            }
        }
Example #9
0
        private void CreateManagedObjects()
        {
            if (Process == null)
            {
                return;
            }

            using (DataTarget dataTarget = DataTarget.AttachToProcess(Process.Id, dataTargetTimeOut, dataTargetAttachFlag))
            {
                ClrInfo    clrVersion = dataTarget.ClrVersions.First();
                ClrRuntime runtime    = clrVersion.CreateRuntime();
                Snapshot   snapshot   = new Snapshot()
                {
                    MemoryPrivateBytes = Process.PrivateMemorySize64, Date = DateTime.Now, Position = Snapshots.Count
                };
                Snapshots.Add(snapshot);
                snapshotPosition        = Snapshots.Count - 1;
                snapshot.Comment        = snapshotPosition + ". Snapshot: ";
                richTextBoxComment.Text = snapshot.Comment;
                CollectMemory(runtime, snapshot);
                snapshot.ManagedObjectDic = ListObjects(runtime);
                RefreshSnapshotGrid(snapshot);
            }
        }
        public bool Attach(Process process, string dacFile = null, uint attachTimeout = DefaultAttachTimeout)
        {
            if (process == null)
            {
                throw new ArgumentNullException("process");
            }
            _process = process;

            if (_dataTarget != null)
            {
                _output.Error(String.Format("Already attached to process PID={0} Name={1}",
                                            _process.Id, _process.ProcessName));
                return(false);
            }

            _output.Info(String.Format("Attaching to process PID={0}",
                                       process.Id));

            try
            {
                _dataTarget = DataTarget.AttachToProcess(process.Id, attachTimeout);

                //make sure we dont kill the process on exit
            }

            catch (Exception exception)
            {
                //TODO: Be more specific, dont catch all exceptions
                _output.Error("Could not attach to the process.");
                throw;
            }

            if (_dataTarget == null)
            {
                //TODO: Be more specific, what exactly does it mean?
                _output.Error("Could not attach to the process.");
                _process = null;
                return(false);
            }
            _dataTarget.DebuggerInterface.SetProcessOptions(DEBUG_PROCESS.DETACH_ON_EXIT);

            if (_dataTarget.ClrVersions.Count == 0)
            {
                var msg = String.Format(
                    "Process PID={0} Name={1} does not seem to have CLR loaded. Is it an unmanaged process?",
                    _process.Id, _process.ProcessName);
                _output.Error(msg);

                Detach();
                return(false);
            }
            if (_dataTarget.ClrVersions.Count > 1)
            {
                //TODO: multiple CLRs found present user with choice?
                var msg = String.Format("Multiple CLR versions loaded. Proceeding with first version.");
                _output.Warning(msg);
            }
            _clrInfo = _dataTarget.ClrVersions[0];

            _output.Info(String.Format("Using CLR Version={0} DACFileName={1}",
                                       _clrInfo.Version, _clrInfo.DacInfo.FileName));

            string dacLocation;

            if (String.IsNullOrWhiteSpace(dacFile))
            {
                dacLocation = _clrInfo.TryGetDacLocation();
            }
            else
            {
                dacLocation = dacFile;
                _output.Info(String.Format("Using DacFile={0}", dacFile));
            }
            if (String.IsNullOrWhiteSpace(dacLocation))
            {
                //TODO: Check filepath, display meaningful message
                _output.Error("Could not automatically locate Data Access Component (mscordacwks.dll). This may mean that bitness or CLR versions do not match. " +
                              "You may specify file location manually eg. ClrDiag.Attach(PID, @\"C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\mscordacwks.dll\"");
                Detach();
                return(false);
            }

            ClrRuntime runtime = _dataTarget.CreateRuntime(dacLocation);

            if (runtime == null)
            {
                //TODO: add more meaningful information
                _output.Error("Unable to get CLR information.");
                Detach();
            }
            _output.Success(String.Format("Succesfully attached to process PID={0} Name={1}",
                                          _process.Id, _process.ProcessName));
            Clr = runtime;
            return(true);
        }
        private static void Main(string[] args)
        {
            bool detailed = false;

            if (args.Length != 1)
            {
                Console.WriteLine("dotnet run dmp");
                return;
            }
            var strings = new Dictionary <string, ClrObject>();

            using (DataTarget dataTarget = DataTarget.LoadCrashDump(args[0]))
            {
                ClrInfo    runtimeInfo = dataTarget.ClrVersions[0];
                ClrRuntime runtime     = runtimeInfo.CreateRuntime();
                ClrHeap    heap        = runtime.Heap;
                ulong      gen2Size    = 0;

                long gen2StringCount     = 0;
                long gen2ScanStringCount = 0;
                long gen2DupStringCount  = 0;

                long gen2StringSize     = 0;
                long gen2ScanStringSize = 0;
                long gen2DupStringSize  = 0;
                foreach (ClrSegment segment in heap.Segments)
                {
                    gen2Size += segment.Gen2Length;
                }
                foreach (ClrObject obj in heap.EnumerateObjects())
                {
                    int?objGen = GenerationOf(heap, obj);
                    if (objGen == 2)
                    {
                        if (obj.Type.Name.Equals("System.String"))
                        {
                            // This are all the strings in gen2, they may or may not be live, they may or may not have a gen 2 reference.
                            // This should give an idea why strings are important
                            // My prediction is that this should be a significant percentage (otherwise why bother?)
                            gen2StringCount++;
                            gen2StringSize += obj.AsString().Length * 2;
                        }
                        foreach (ClrObject referencedObject in obj.EnumerateReferences())
                        {
                            int?refGen = GenerationOf(heap, referencedObject);
                            // This happen when we see a string referenced by a gen2 object
                            if (refGen == 2)
                            {
                                if (referencedObject.Type.Name.Equals("System.String"))
                                {
                                    if (detailed)
                                    {
                                        Console.WriteLine("A gen 2 object {0:X} is referencing a gen 2 string {1:X}", obj.Address, referencedObject.Address);
                                    }

                                    // This is a string the string deduplication algorithm would consider to put into the hash table
                                    // This should give an idea how much work we need to do to scan these strings
                                    // My assumption is that the majority of the work is the computing of the hash code, that why
                                    // the cost should be roughly corresponding to the total length of the strings
                                    string referencedObjectAsString = referencedObject.AsString();
                                    gen2ScanStringCount++;
                                    gen2ScanStringSize += referencedObjectAsString.Length * 2;
                                    // This happen when we see a gen2 string referenced by a gen2 object
                                    ClrObject existingObject;
                                    if (strings.TryGetValue(referencedObjectAsString, out existingObject))
                                    {
                                        // This happen when we see a gen2 string referenced by a gen2 object with a seen content
                                        if (referencedObject.Address != existingObject.Address)
                                        {
                                            if (detailed)
                                            {
                                                Console.WriteLine("And it is considered a duplicate with {0:X}", existingObject.Address);
                                            }
                                            // This happen when we see a different gen 2 string referenced by a gen2 object with a seen content
                                            // We do not know if deduplicating it will lead to its death (it depends on whether or not that string has any other references)
                                            // which would be expensive to compute, but this should give an upper bound on how much we could save.
                                            gen2DupStringCount++;
                                            gen2DupStringSize += referencedObjectAsString.Length * 2;
                                        }
                                    }
                                    else
                                    {
                                        // This happen when we see a gen 2 string referenced by a gen2 object that is not seen before
                                        strings.Add(referencedObjectAsString, referencedObject);
                                    }
                                }
                            }
                        }
                    }
                }
                Console.WriteLine("Gen 2 size         : " + gen2Size);
                Console.WriteLine("Gen 2 strings      : " + gen2StringSize + " bytes out of " + gen2StringCount + " strings");
                Console.WriteLine("Gen 2 scan string  : " + gen2ScanStringSize + " bytes out of " + gen2ScanStringCount + " strings");
                Console.WriteLine("Gen 2 dup string   : " + gen2DupStringSize + " bytes out of " + gen2DupStringCount + " strings");
                Console.WriteLine("{0},{1},{2},{3},{4},{5},{6}", gen2Size, gen2StringSize, gen2StringCount, gen2ScanStringSize, gen2ScanStringCount, gen2DupStringSize, gen2DupStringCount);
            }
        }
Example #12
0
        /// <summary>
        /// Retrieves the debug support files (DAC, SOS, CLR) from the Microsoft symbol server
        /// and returns the path to the temporary directory in which they were placed. If the <paramref name="storageLocation"/>
        /// parameter is not null/empty, the files will be stored in that location.
        /// </summary>
        /// <param name="clrInfo">The CLR version for which to load the support files.</param>
        public static string GetDebugSupportFiles(ClrInfo clrInfo, DataTarget target, string storageLocation = null)
        {
            IntPtr processHandle = Process.GetCurrentProcess().Handle;

            if (!SymInitialize(processHandle, null, false))
            {
                Console.WriteLine("*** Error initializing dbghelp.dll symbol support");
                return(null);
            }
            if (string.IsNullOrEmpty(storageLocation))
            {
                storageLocation = Path.Combine(Path.GetTempPath(), clrInfo.Version.ToString());
                if (!Directory.Exists(storageLocation))
                {
                    Directory.CreateDirectory(storageLocation);
                }
            }

            Console.WriteLine("CLR version: " + clrInfo.Version);
            string        clrModuleName = clrInfo.Version.Major == 2 ? "mscorwks" : "clr";
            StringBuilder loadedClrFile = new StringBuilder(2048);

            if (!SymFindFileInPath(processHandle, null, clrModuleName + ".dll", clrInfo.DacInfo.TimeStamp,
                                   clrInfo.DacInfo.FileSize, 0, 0x2, loadedClrFile, IntPtr.Zero, IntPtr.Zero))
            {
                Console.WriteLine("*** Error retrieving CLR from symbol server");
            }
            else
            {
                File.Copy(loadedClrFile.ToString(), Path.Combine(storageLocation, clrModuleName + ".dll"), true);
            }

            string      str         = (IntPtr.Size == 4) ? "x86" : "amd64";
            VersionInfo clrVersion  = clrInfo.Version;
            string      sosFileName = string.Format("sos_{0}_{1}_{2}.{3}.{4}.{5:D2}.dll",
                                                    str, target.Architecture, clrVersion.Major, clrVersion.Minor, clrVersion.Revision, clrVersion.Patch);
            StringBuilder loadedSOSFile = new StringBuilder(2048);

            if (!SymFindFileInPath(processHandle, null, sosFileName, clrInfo.DacInfo.TimeStamp,
                                   clrInfo.DacInfo.FileSize, 0, 0x2, loadedSOSFile, IntPtr.Zero, IntPtr.Zero))
            {
                Console.WriteLine("*** Error retrieving SOS from symbol server");
            }
            else
            {
                File.Copy(loadedSOSFile.ToString(), Path.Combine(storageLocation, "SOS.dll"), true);
            }

            StringBuilder loadedDacFile = new StringBuilder(2048);

            if (!SymFindFileInPath(processHandle, null, clrInfo.DacInfo.FileName, clrInfo.DacInfo.TimeStamp,
                                   clrInfo.DacInfo.FileSize, 0, 0x2 /*SSRVOPT_DWORD*/, loadedDacFile, IntPtr.Zero, IntPtr.Zero))
            {
                Console.WriteLine("*** Error retrieving DAC from symbol server");
            }
            else
            {
                File.Copy(loadedDacFile.ToString(), Path.Combine(storageLocation, "mscordacwks.dll"), true);
            }

            SymCleanup(processHandle);
            return(storageLocation);
        }
Example #13
0
 internal DesktopRuntimeBase(ClrInfo info, DataTargetImpl dt, DacLibrary lib)
     : base(info, dt, lib)
 {
 }
Example #14
0
    static void Main()
    {
        DataTarget dataTarget = DataTarget.LoadCrashDump(@"MyDump.dmp");

        ClrInfo    runtimeInfo = dataTarget.ClrVersions.Single(); // just using the first runtime
        string     dacFile     = @"mscordacwks_amd64_amd64_4.7.2117.00.dll";
        ClrRuntime runtime     = runtimeInfo.CreateRuntime(dacFile);

        if (!runtime.Heap.CanWalkHeap)
        {
            Console.WriteLine("Cannot walk heap");
            return;
        }

        ClrType connectionGroupType = runtime.Heap.GetTypeByName("System.Net.ConnectionGroup");

        foreach (ClrObject connectionGroup in runtime.Heap.EnumerateObjects().Where(o => o.Type == connectionGroupType))
        {
            Console.WriteLine($"Found {connectionGroup}");

            //connectionGroup.PrintFields();

            int connectionLimit = connectionGroup.GetField <int>("m_ConnectionLimit");
            Console.WriteLine($"ConnectionGroup 0x{connectionGroup.Address:x16} - m_ConnectionLimit: {connectionLimit}");

            List <ClrObject> connections = connectionGroup.GetObjectField("m_ConnectionList").GetObjectField("_items")
                                           .EnumerateObjectArrayItems().Where(o => !o.IsNull).ToList();
            Console.WriteLine($"    Connections: {connections.Count}");
            foreach (ClrObject c in connections)
            {
                Console.WriteLine(c);
            }

            List <ClrObject> connectionsStuck = connections.Where(c => c.GetField <bool>("m_NonKeepAliveRequestPipelined")).ToList();
            Console.WriteLine($"        m_NonKeepAliveRequestPipelined: true = {connectionsStuck.Count} / false = {connections.Count - connectionsStuck.Count}");
            Console.WriteLine($"            m_WriteDone: {connectionsStuck.Where(c => c.GetField<bool>("m_WriteDone")).Count()}");
            Console.WriteLine($"            m_ReadDone: {connectionsStuck.Where(c => c.GetField<bool>("m_ReadDone")).Count()}");
            Console.WriteLine($"            m_Free: {connectionsStuck.Where(c => c.GetField<bool>("m_Free")).Count()}");
            int connections_KeepAlive = connections.Where(c => c.GetField <bool>("m_KeepAlive")).Count();
            Console.WriteLine($"        m_KeepAlive: true = {connections_KeepAlive} / false = {connections.Count - connections_KeepAlive}");

            int connectionIndex = -1;
            foreach (ClrObject connection in connections)
            {
                connectionIndex++;
                //Debug.Assert(connection.Type.Name == "System.Net.Connection");
                //connection.PrintFields();
                bool             m_NonKeepAliveRequestPipelined = connection.GetField <bool>("m_NonKeepAliveRequestPipelined");
                List <ClrObject> writeList = connection.GetObjectField("m_WriteList").GetObjectField("_items").EnumerateObjectArrayItems().NonNull().ToList();
                List <ClrObject> waitList  = connection.GetObjectField("m_WaitList").GetObjectField("_items").EnumerateObjectArrayItems().NonNull().ToList();

                /*
                 * if (writeList.Count != 0 || waitList.Count != 0)
                 * {
                 *  continue;
                 * }
                 */
                /*
                 * if (writeList.Count + waitList.Count != 1)
                 * {
                 *  continue;
                 * }
                 */
                /*
                 * if (writeList.Count == 0 || writeList[0].GetField<bool>("m_KeepAlive"))
                 * {
                 *  continue;
                 * }
                 */

                Console.WriteLine($"    Connection[{connectionIndex++}] 0x{connection.Address:x16}");
                Console.WriteLine("        m_NonKeepAliveRequestPipelined = {0}", connection.GetField <bool>("m_NonKeepAliveRequestPipelined"));
                Console.WriteLine("        m_KeepAlive = {0}", connection.GetField <bool>("m_KeepAlive"));
                Console.WriteLine("        m_ReadDone = {0}", connection.GetField <bool>("m_ReadDone"));
                Console.WriteLine("        m_WriteDone = {0}", connection.GetField <bool>("m_WriteDone"));
                Console.WriteLine("        m_Free = {0}", connection.GetField <bool>("m_Free"));
                Console.WriteLine($"        m_WriteList ({writeList.Count})");
                int writeListIndex = 0;
                foreach (ClrObject httpWebRequest in writeList)
                {
                    Console.WriteLine($"            HWR[{writeListIndex++}] 0x{httpWebRequest.Address:x16}");
                    PrintHttpWebRequestFields(httpWebRequest, "                ");
                }
                Console.WriteLine($"        m_WaitList ({waitList.Count})");
            }
        }
    }
Example #15
0
 /// <summary>
 ///     Initializes a new instance of the <see cref="ClrInfoAdapter" /> class.
 /// </summary>
 /// <param name="info">The information.</param>
 /// <exception cref="ArgumentNullException">info</exception>
 /// <inheritdoc />
 public ClrInfoAdapter(IConverter converter, ClrInfo info) : base(converter)
 {
     Info             = info ?? throw new ArgumentNullException(nameof(info));
     LocalMatchingDac = Info.LocalMatchingDac;
 }
Example #16
0
        // Returns all the info about any Composite Keys stored in memory
        public static List <CompositeKeyInfo> GetCompositeKeyInfo(Process process)
        {
            List <CompositeKeyInfo> keyInfo = new List <CompositeKeyInfo>();
            DataTarget dt = null;
            string     databaseLocation = "";

            try
            {
                dt = DataTarget.AttachToProcess(process.Id, 50000);

                if (dt.ClrVersions.Count == 0)
                {
                    string err = "CLR is not loaded. Is it Keepass 1.x, perhaps?";
                    Logger.WriteLine(err);
                    throw new Exception(err);
                }

                if (dt.ClrVersions.Count > 1)
                {
                    Logger.WriteLine("*** Interesting... there are multiple .NET runtimes loaded in KeePass");
                }

                ClrInfo    Version = dt.ClrVersions[0];
                ClrRuntime Runtime = Version.CreateRuntime();
                ClrHeap    Heap    = Runtime.GetHeap();

                if (!Heap.CanWalkHeap)
                {
                    string err = "Error: Cannot walk the heap!";
                    Logger.WriteLine(err);
                    throw new Exception(err);
                }

                foreach (ulong obj in Heap.EnumerateObjectAddresses())
                {
                    ClrType type = Heap.GetObjectType(obj);

                    if (type == null || type.Name != "KeePassLib.PwDatabase")
                    {
                        continue;
                    }

                    Logger.WriteLine("************ Found a PwDatabase! **********");

                    List <ulong> referencedObjects = ClrMDHelper.GetReferencedObjects(Heap, obj);

                    // First walk the referenced objects to find the database path
                    foreach (ulong refObj in referencedObjects)
                    {
                        ClrType refObjType = Heap.GetObjectType(refObj);
                        if (refObjType.Name == "KeePassLib.Serialization.IOConnectionInfo")
                        {
                            ClrInstanceField UrlField     = refObjType.GetFieldByName("m_strUrl");
                            ulong            UrlFieldAddr = UrlField.GetAddress(refObj);
                            object           Url          = UrlField.GetValue(UrlFieldAddr, true);
                            databaseLocation = (string)Url;
                        }
                    }

                    if (databaseLocation != "")
                    {
                        Logger.WriteLine("*** PwDatabase location : " + databaseLocation);

                        referencedObjects = ClrMDHelper.GetReferencedObjects(Heap, obj);

                        // now walk the referenced objects looking for a master composite key
                        foreach (ulong refObj in referencedObjects)
                        {
                            ClrType refObjType = Heap.GetObjectType(refObj);
                            if (refObjType.Name == "KeePassLib.Keys.CompositeKey")
                            {
                                Logger.WriteLine("************ Found a CompositeKey! **********");
                                CompositeKeyInfo CompositeKey = new CompositeKeyInfo();

                                // Get all objects kept alive by the composite key.
                                // (A shortcut to get references to all Key types)
                                List <ulong> referencedObjects2 = ClrMDHelper.GetReferencedObjects(Heap, refObj);

                                foreach (ulong refObj2 in referencedObjects2)
                                {
                                    ClrType refObjType2 = Heap.GetObjectType(refObj2);

                                    if (refObjType2.Name == "KeePassLib.Keys.KcpPassword")
                                    {
                                        KcpPassword KcpPassword = GetKcpPasswordInfo(refObj2, refObjType2, Heap, databaseLocation);

                                        if (KcpPassword == null)
                                        {
                                            continue;
                                        }

                                        CompositeKey.AddUserKey(KcpPassword);
                                    }
                                    else if (refObjType2.Name == "KeePassLib.Keys.KcpKeyFile")
                                    {
                                        KcpKeyFile KcpKeyFile = GetKcpKeyFileInfo(refObj2, refObjType2, Heap, databaseLocation);

                                        if (KcpKeyFile == null)
                                        {
                                            continue;
                                        }

                                        CompositeKey.AddUserKey(KcpKeyFile);
                                    }
                                    else if (refObjType2.Name == "KeePassLib.Keys.KcpUserAccount")
                                    {
                                        KcpUserAccount KcpUserAccount = GetKcpUserAccountInfo(refObj2, refObjType2, Heap, databaseLocation);

                                        if (KcpUserAccount == null)
                                        {
                                            continue;
                                        }

                                        CompositeKey.AddUserKey(KcpUserAccount);
                                    }
                                }
                                if (CompositeKey.UserKeyCount > 0)
                                {
                                    keyInfo.Add(CompositeKey);
                                }
                            }
                        }
                    }
                }

                Logger.Write("\n");
            }
            catch (Exception e)
            {
                Logger.WriteLine(e.Message);
                throw;
            }
            finally
            {
                if (dt != null)
                {
                    dt.Dispose();
                }
            }

            return(keyInfo);
        }
Example #17
0
        static void handleException(Exception ex)
        {
            if (ex.Message == "Safe handle has been closed")
            {
                return;
            }

            if (MainV2.instance != null && MainV2.instance.IsDisposed)
            {
                return;
            }

            MissionPlanner.Utilities.Tracking.AddException(ex);

            log.Debug(ex.ToString());

            GetStackTrace(ex);

            // hyperlinks error
            if (ex.Message == "Requested registry access is not allowed." ||
                ex.ToString().Contains("System.Windows.Forms.LinkUtilities.GetIELinkBehavior"))
            {
                return;
            }
            if (ex.Message.Contains("The port is closed"))
            {
                CustomMessageBox.Show("Serial connection has been lost");
                return;
            }
            if (ex.Message.Contains("Array.Empty"))
            {
                CustomMessageBox.Show("Please install Microsoft Dot Net 4.6.2");
                Application.Exit();
                return;
            }
            if (ex.Message.Contains("A device attached to the system is not functioning"))
            {
                CustomMessageBox.Show("Serial connection has been lost");
                return;
            }
            if (ex.GetType() == typeof(MissingMethodException) || ex.GetType() == typeof(TypeLoadException))
            {
                CustomMessageBox.Show("Please Update - Some older library dlls are causing problems\n" + ex.Message);
                return;
            }
            if (ex.GetType() == typeof(ObjectDisposedException) || ex.GetType() == typeof(InvalidOperationException))
            // something is trying to update while the form, is closing.
            {
                log.Error(ex);
                return; // ignore
            }
            if (ex.GetType() == typeof(FileNotFoundException) || ex.GetType() == typeof(BadImageFormatException))
            // i get alot of error from people who click the exe from inside a zip file.
            {
                CustomMessageBox.Show(
                    "You are missing some DLL's. Please extract the zip file somewhere. OR Use the update feature from the menu " +
                    ex.ToString());
                // return;
            }
            // windows and mono
            if (ex.StackTrace != null && ex.StackTrace.Contains("System.IO.Ports.SerialStream.Dispose") ||
                ex.StackTrace != null && ex.StackTrace.Contains("System.IO.Ports.SerialPortStream.Dispose"))
            {
                log.Error(ex);
                return; // ignore
            }

            log.Info("Th Name " + Thread?.Name);

            var dr =
                CustomMessageBox.Show("An error has occurred\n" + ex.ToString() + "\n\nReport this Error???",
                                      "Send Error", MessageBoxButtons.YesNo);

            if ((int)DialogResult.Yes == dr)
            {
                try
                {
                    string data = "";
                    foreach (System.Collections.DictionaryEntry de in ex.Data)
                    {
                        data += String.Format("-> {0}: {1}", de.Key, de.Value);
                    }

                    string message = "";

                    try
                    {
                        Controls.InputBox.Show("Message", "Please enter a message about this error if you can.",
                                               ref message);
                    }
                    catch
                    {
                    }

                    string processinfo = "";

                    try
                    {
                        var result = new Dictionary <int, string[]>();

                        var pid = Process.GetCurrentProcess().Id;

                        using (var dataTarget = DataTarget.AttachToProcess(pid, 5000, AttachFlag.Passive))
                        {
                            ClrInfo runtimeInfo = dataTarget.ClrVersions[0];
                            var     runtime     = runtimeInfo.CreateRuntime();

                            foreach (var t in runtime.Threads)
                            {
                                result.Add(
                                    t.ManagedThreadId,
                                    t.StackTrace.Select(f =>
                                {
                                    if (f.Method != null)
                                    {
                                        return(f.Method.Type.Name + "." + f.Method.Name);
                                    }

                                    return(null);
                                }).ToArray()
                                    );
                            }
                        }

                        processinfo = result.ToJSON(Formatting.Indented); //;Process.GetCurrentProcess().Modules.ToJSON();
                    }
                    catch
                    {
                    }

                    string postData = "message=" + Environment.OSVersion.VersionString + " " +
                                      System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString()
                                      + " " + Application.ProductVersion
                                      + "\nException " + ex.ToString().Replace('&', ' ').Replace('=', ' ')
                                      + "\nStack: " + ex.StackTrace.ToString().Replace('&', ' ').Replace('=', ' ')
                                      + "\nTargetSite " + ex.TargetSite + " " + ex.TargetSite.DeclaringType
                                      + "\ndata " + data
                                      + "\nmessage " + message.Replace('&', ' ').Replace('=', ' ')
                                      + "\n\n" + processinfo;
                    Download.PostAsync("http://vps.oborne.me/mail.php", postData);
                }
                catch (Exception exp)
                {
                    Console.WriteLine(exp.ToString());
                    log.Error(exp);
                    CustomMessageBox.Show("Could not send report! Typically due to lack of internet connection.");
                }
            }
        }
Example #18
0
        private static void DumpRetention(DataTarget dataTarget, ClrInfo clrVersion, ClrRuntime runtime, ClrAppDomain appDomain, ClrHeap heap, string targetType)
        {
            var graph = new Graph();

            Console.WriteLine("## What's the retention path of the {0} object?", targetType);
            Console.WriteLine("");
            foreach (var ptr in heap.EnumerateObjectAddresses())
            {
                var type = heap.GetObjectType(ptr);
                if (type == null || type.Name != targetType)
                {
                    continue;
                }

                // Enumerate roots and try to find the current object
                var stack = new Stack <ulong>();
                foreach (var root in heap.EnumerateRoots())
                {
                    stack.Clear();
                    stack.Push(root.Object);
                    if (GetPathToObject(heap, ptr, stack, new HashSet <ulong>()))
                    {
                        // Print retention path
                        var depth           = 0;
                        var previousAddress = (ulong)0;
                        foreach (var address in stack)
                        {
                            var t = heap.GetObjectType(address);
                            if (t == null)
                            {
                                continue;
                            }

                            Console.WriteLine("{0} {1} - {2} - {3} bytes", new string('+', depth++), address, t.Name, t.GetSize(address));

                            graph.AddNode(address.ToString()).LabelText = $"{t.Name} ({address})";
                            if (previousAddress > 0 && !graph.Edges.Any(e => e.Source == previousAddress.ToString() && e.Target == address.ToString()))
                            {
                                graph.AddEdge(previousAddress.ToString(), address.ToString());
                            }
                            previousAddress = address;
                        }

                        Console.WriteLine();
                    }
                }
            }

            Console.ReadLine();

            // Render graph
            var width    = 1600;
            var renderer = new GraphRenderer(graph);

            renderer.CalculateLayout();
            var bitmap = new Bitmap(width, (int)(graph.Height * (width / graph.Width)), PixelFormat.Format32bppRgb);

            renderer.Render(bitmap);
            bitmap.Save("test.png");
            Process.Start("test.png");
        }
Example #19
0
        private static KeyValuePair <bool, string> Enumerate()
        {
            //Attach to target process
            DataTarget dt = null;

            try
            {
                dt = DataTarget.AttachToProcess(targetPID, 10000, AttachFlag.NonInvasive);
            }
            catch (Exception e)
            {
                return(new KeyValuePair <bool, string>(false, e.ToString()));
            }

            //If no ClrVersions, return
            if (dt.ClrVersions.Count == 0)
            {
                return(new KeyValuePair <bool, string>(false, "[!] No Clr Versions detected"));
            }

#if DEBUG
            foreach (var ver in dt.ClrVersions)
            {
                Console.WriteLine("Clr Runtime Version Found: " + ver.Version.ToString());
            }
#endif

            ClrInfo ClrVersion = dt.ClrVersions[0];


            try
            {
                cRun = ClrVersion.CreateRuntime();
#if DEBUG
                Console.WriteLine("[+] Created Runtime");
#endif
            }
            catch (Exception e)
            {
#if DEBUG
                Console.WriteLine("[!] Failed to create runtime");
#endif
                return(new KeyValuePair <bool, string>(false, e.ToString()));
            }


            ClrHeap Heap = cRun.GetHeap();

            //if we can't walk the heap, return
            if (!Heap.CanWalkHeap)
            {
                return(new KeyValuePair <bool, string>(false, "[!] Unable to walk the heap"));
            }

            Console.WriteLine("[+] Walking the heap....");
            string m  = WildCardToRegWithQM("System.*");
            string m1 = WildCardToRegWithQM("_*");
            string m2 = WildCardToRegWithQM("Microsoft.*");
            foreach (ulong obj in Heap.EnumerateObjectAddresses())
            {
                //Grab each object, check if it has a simple value, if so, display it
                ClrType type = Heap.GetObjectType(obj);

                if (type == null || Regex.IsMatch(type.Name, m) || Regex.IsMatch(type.Name, m1) || Regex.IsMatch(type.Name, m2) || type.Name == "Free")
                {
                    continue;
                }

                if (!type.IsPrimitive)
                {
#if DEBUG
                    Console.WriteLine("[+] Enumerating type: " + type.Name);
#endif
                    //if the type has a simple value, add the type and its value to the results
                    resultOutput.Append("\r\nType: " + type.Name + "\r\n\r\n");
                    //Enumerate all of the instance fields for the given type
                    if (showFields)
                    {
                        if (type.Fields != null)
                        {
                            GetInstanceFields(type.Fields, obj);
                        }
                    }


                    if (showstaticFields)
                    {
                        if (type.StaticFields != null)
                        {
                            GetStaticFields(type.StaticFields, cRun.AppDomains[0]);
                        }
                    }

                    if (showMethods)
                    {
                        if (type.Methods != null)
                        {
                            GetMethods(type.Methods);
                        }
                    }
                }
            }

            return(new KeyValuePair <bool, string>(true, "[+] Successfully walked the heap."));
        }
Example #20
0
        /// <summary>
        ///     Gets the thread call stacks.
        /// </summary>
        /// <param name="threadMap">The thread map.</param>
        private static void GetThreadCallStacks(Dictionary <int, ThreadInfo> threadMap)
        {
            using (DataTarget target = DataTarget.AttachToProcess(Process.GetCurrentProcess( ).Id, 2500, AttachFlag.Passive))
            {
                if (target.ClrVersions.Count > 0)
                {
                    ClrInfo version = target.ClrVersions[0];

                    var runtime = version.CreateRuntime( );

                    var appDomains = new Dictionary <ulong, string>( );

                    foreach (var appDomain in runtime.AppDomains)
                    {
                        appDomains[appDomain.Address] = appDomain.Name;
                    }

                    foreach (var thread in runtime.Threads)
                    {
                        if (!thread.IsAlive)
                        {
                            continue;
                        }

                        ThreadInfo threadInfo;

                        if (threadMap.TryGetValue(( int )thread.OSThreadId, out threadInfo))
                        {
                            var callStack = new StringBuilder( );

                            foreach (ClrStackFrame frame in thread.StackTrace)
                            {
                                callStack.AppendLine(frame.ToString( ));
                            }

                            threadInfo.CallStack  = callStack.ToString( );
                            threadInfo.OsThreadId = ( int )thread.OSThreadId;

                            string appDomainName;

                            if (appDomains.TryGetValue(thread.AppDomain, out appDomainName))
                            {
                                threadInfo.AppDomain = appDomainName;
                            }

                            if (string.IsNullOrEmpty(threadInfo.CallStack))
                            {
                                if (thread.IsFinalizer)
                                {
                                    threadInfo.CallStack = "[Finalizer]";
                                }
                                else if (thread.IsThreadpoolWorker)
                                {
                                    threadInfo.CallStack = "[ThreadPoolWorker]";
                                }
                            }
                        }
                    }
                }
            }
        }
Example #21
0
 public MDRuntimeInfo(ClrInfo info)
 {
     m_info = info;
 }
Example #22
0
 public ClrmdRuntime(ClrInfo info, DacLibrary dac, IRuntimeHelpers helpers)
 {
     ClrInfo    = info;
     DacLibrary = dac;
     _helpers   = helpers ?? throw new ArgumentNullException(nameof(helpers));
 }
Example #23
0
        private void TracerBody()
        {
            IsEnd = false;
            while (!IsEnd)
            {
                try
                {
                    for (int i = 0; i < mProbeTimes; ++i)
                    {
                        ProcessMeasure.Step();
                        Thread.Sleep(pollingFrequency);
                    }
                    process = Process.GetCurrentProcess();
                    if (process.HasExited)
                    {
                        process.Dispose();
                        process = null;
                        return;
                    }
                    if (process.Responding)
                    {
                        process.Dispose();
                        continue;
                    }

                    var pid = process.Id;
                    {
                        StringBuilder mainThreadTrace = new StringBuilder();
                        var           trace           = GetStackTrace(mMainThread);
                        if (trace == null)
                        {
                            trace = GetStackTrace(mMainThread);
                        }
                        if (trace != null)
                        {
                            mainThreadTrace.AppendLine("--------------------------------------");
                            mainThreadTrace.AppendLine("MainThread");
                            foreach (var f in trace.GetFrames())
                            {
                                if (IsEnd)
                                {
                                    return;
                                }
                                var    method   = f.GetMethod();
                                String declType = "";
                                if (method.DeclaringType != null)
                                {
                                    declType = method.DeclaringType.FullName;
                                }
                                mainThreadTrace.AppendLine("  " + declType + "." + method.Name + "(" + f.GetFileName() + ":" + f.GetFileLineNumber() + ")");
                            }
                            mainThreadTrace.AppendLine();
                            Tracer.D(mainThreadTrace.ToString());
                        }
                    }
                    using (var dataTarget = DataTarget.AttachToProcess(pid, 5000, AttachFlag.Passive))
                    {
                        ClrInfo runtimeInfo = dataTarget.ClrVersions[0];
                        var     runtime     = runtimeInfo.CreateRuntime();

                        StringBuilder strb = new StringBuilder();
                        Dictionary <String, String> moduleMap = new Dictionary <string, string>();
                        foreach (var t in runtime.Modules)
                        {
                            if (IsEnd)
                            {
                                return;
                            }
                            if (t.IsFile)
                            {
                                String name = Path.GetFileNameWithoutExtension(t.FileName);
                                moduleMap[name] = t.FileName;
                            }
                        }

                        foreach (var t in runtime.Threads)
                        {
                            if (IsEnd)
                            {
                                return;
                            }
                            if (t.ManagedThreadId == Thread.CurrentThread.ManagedThreadId)
                            {
                                continue;
                            }
                            if (!t.IsAlive)
                            {
                                continue;
                            }

                            strb.AppendLine("--------------------------------------");
                            strb.AppendLine("Thread " + t.ManagedThreadId);
                            int count = 0;
                            foreach (var f in t.EnumerateStackTrace())
                            {
                                if (IsEnd)
                                {
                                    return;
                                }
                                strb.AppendLine(" " + f.DisplayString + "+" + f.InstructionPointer);
                                if (f.Method != null)
                                {
                                    String moduleName = f.ModuleName;

                                    Module module  = assembly.GetModule(f.ModuleName);
                                    String pdbName = "";
                                    if (module != null)
                                    {
                                        pdbName = Path.Combine(Path.GetDirectoryName(module.Assembly.Location), Path.GetFileNameWithoutExtension(module.Assembly.Location)) + ".pdb";
                                    }
                                    else
                                    {
                                        if (moduleMap.ContainsKey(moduleName))
                                        {
                                            pdbName = Path.Combine(Path.GetDirectoryName(moduleMap[moduleName]), Path.GetFileNameWithoutExtension(moduleMap[moduleName])) + ".pdb";
                                        }
                                    }
                                    if (!string.IsNullOrEmpty(pdbName) && File.Exists(pdbName))
                                    {
                                        try
                                        {
                                            var sourceFileNameAndLine = ReadClrSourceFileNameAndLine(pdbName, f.Method, f.InstructionPointer);
                                            strb.AppendLine(String.Format("  >({0}- line {1})", sourceFileNameAndLine.Item1, sourceFileNameAndLine.Item2));
                                        }
                                        catch (Exception ee)
                                        {
                                        }
                                    }
                                }
                                ++count;
                                if (count >= stackTraceIterations)
                                {
                                    break;
                                }
                            }
                        }
                        strb.AppendLine();
                        Tracer.D(strb.ToString());
                        if (process != null)
                        {
                            process.Dispose();
                            process = null;
                        }
                    }
                }
                catch (Exception ee)
                {
                    Tracer.D(ee.ToString());
                }
            }
        }
Example #24
0
 internal DesktopRuntimeBase(ClrInfo info, DataTargetImpl dt, DacLibrary lib)
     : base(info, dt, lib)
 {
 }
Example #25
0
        private static void PrintDuplicateStrings(ClrInfo clr)
        {
            Dictionary <string, int> stringDupesDict = new Dictionary <string, int>();

            ClrRuntime runtime = clr.CreateRuntime();

            if (!runtime.Heap.CanWalkHeap)
            {
                Console.WriteLine("Cannot walk the heap!");
            }
            else
            {
                foreach (ClrSegment seg in runtime.Heap.Segments)
                {
                    foreach (ClrObject obj in seg.EnumerateObjects())
                    {
                        // If heap corruption, continue past this object.
                        if (!obj.IsValid)
                        {
                            continue;
                        }

                        if (obj.Type.Name != "System.String")
                        {
                            continue;
                        }

                        string type;
                        if (seg.IsEphemeralSegment)
                        {
                            type = "Ephemeral";
                        }
                        else if (seg.IsLargeObjectSegment)
                        {
                            type = "Large";
                        }
                        else
                        {
                            type = "Gen2";
                        }

                        var   asstr      = obj.AsString();
                        ulong objSize    = obj.Size;
                        int   generation = seg.GetGeneration(obj);

                        //Console.WriteLine($"{obj} {objSize} {generation}");

                        var keyWithGen = $"{asstr}_{objSize}_{generation}_{type}";
                        if (stringDupesDict.TryGetValue(keyWithGen, out int val))
                        {
                            val = val + 1;
                            stringDupesDict[keyWithGen] = val;
                        }
                        else
                        {
                            stringDupesDict[keyWithGen] = 1;
                        }
                    }
                }
            }

            foreach (var d in stringDupesDict.OrderBy(a => a.Value))
            {
                Console.WriteLine($"Count:{d.Value},  String(value_size_gen):{d.Key}");
            }

            var totalStrings = stringDupesDict.Sum(a => a.Value);

            Console.WriteLine($"Total strings: {totalStrings}");
        }
Example #26
0
        /// <summary>
        /// Find all Strings in Heap an generate a dublicate string report
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonStrings_Click(object sender, EventArgs e)
        {
            if (Process == null)
            {
                return;
            }

            saveFileDialogStrings.FileName = String.Format("clrmd_{0:yyyyMMdd_HHmmss}", DateTime.Now);
            if (saveFileDialogStrings.ShowDialog() != DialogResult.OK)
            {
                return;
            }

            if (File.Exists(saveFileDialogStrings.FileName))
            {
                File.Delete(saveFileDialogStrings.FileName);
            }

            Cursor.Current = Cursors.WaitCursor;

            HashSet <StringObjectHelper> stringObjectList = new HashSet <StringObjectHelper>();
            ulong fullSize    = 0;
            int   objectCount = 0;

            using (StreamWriter writer = new StreamWriter(saveFileDialogStrings.FileName, true, Encoding.UTF8))
            {
                using (DataTarget dataTarget = DataTarget.AttachToProcess(Process.Id, dataTargetTimeOut, dataTargetAttachFlag))
                {
                    ClrInfo    clrVersion = dataTarget.ClrVersions.First();
                    ClrRuntime runtime    = clrVersion.CreateRuntime();
                    if (runtime.Heap.CanWalkHeap)
                    {
                        foreach (ulong ptr in runtime.Heap.EnumerateObjectAddresses())
                        {
                            ClrType type = runtime.Heap.GetObjectType(ptr);

                            if (type == null || type.IsString == false)
                            {
                                continue;
                            }

                            StringObjectHelper stringObject = new StringObjectHelper();
                            stringObject.String = (string)type.GetValue(ptr);
                            stringObject.Size   = type.GetSize(ptr);

                            StringObjectHelper stringObjectFound;
                            if (stringObjectList.TryGetValue(stringObject, out stringObjectFound))
                            {
                                stringObjectFound.PtrList.Add(ptr);
                            }
                            else
                            {
                                stringObject.PtrList.Add(ptr);
                                stringObjectList.Add(stringObject);
                            }
                            objectCount++;
                            fullSize += stringObject.Size;

                            //write all strings
                            writer.WriteLine("**{0}#{1:X}#G{2}#{3:n0}",
                                             objectCount,
                                             ptr,
                                             type.Heap.GetGeneration(ptr),
                                             stringObject.Size);

                            writer.WriteLine(stringObject.String);
                        }
                    }

                    writer.WriteLine();
                    writer.WriteLine("**Position#HeapPtr#Generation#Size");
                    writer.WriteLine();
                    writer.WriteLine("{0:n0} String Objects", objectCount);
                    writer.WriteLine("{0:n0} String unique Strings", stringObjectList.Count);
                    writer.WriteLine("{0:n0} Bytes", fullSize);
                }
            }

            //write dublicate info
            var orderedList = stringObjectList.OrderByDescending(x => x.PtrList.Count);

            using (StreamWriter writer = new StreamWriter(saveFileDialogStrings.FileName + ".unique.csv", true, Encoding.UTF8))
            {
                writer.WriteLine("Count;Size;FullSize;Content;Ptrs");
                foreach (StringObjectHelper so in orderedList)
                {
                    string pointerList = String.Join(",", so.PtrList.Select(x => String.Format("x{0:X}", x)));
                    writer.WriteLine(String.Format("{0};{1};{2};{3};{4}",
                                                   so.PtrList.Count,
                                                   so.Size,
                                                   so.Size * (ulong)so.PtrList.Count,
                                                   (so.String.Length > 50 ? so.String.Substring(0, 50) + " ..." : so.String).Replace("'", "").Replace(";", "").Replace("\r", " ").Replace("\n", ""),
                                                   pointerList.Length > 50 ? pointerList.Substring(0, 50) + " ..." : pointerList));
                }
            }

            Cursor.Current = Cursors.Default;
        }
Example #27
0
    private async Task ProcessCommand2(ILogger <Program> logger)
    {
        string filePath       = @"C:\Users\Ne4to\projects\GitHub\Ne4to\Heartbeat\tests\dumps\AsyncStask.dmp";
        string?dacPath        = null;
        bool   ignoreMismatch = false;

        var     dataTarget = DataTarget.LoadDump(filePath);
        ClrInfo clrInfo    = dataTarget.ClrVersions[0];
        var     clrRuntime = dacPath == null
            ? clrInfo.CreateRuntime()
            : clrInfo.CreateRuntime(dacPath, ignoreMismatch);

        var runtimeContext = new RuntimeContext(clrRuntime, filePath);
        var traversingMode = _commandLineOptions.TraversingHeapMode;

        ExecuteWhenTrue(PrintHttpClients, _commandLineOptions.HttpClient);
        ExecuteWhenTrue(PrintStringDuplicates, _commandLineOptions.StringDuplicate);
        ExecuteWhenTrue(PrintObjectTypeStatistics, _commandLineOptions.ObjectTypeStatistics);
        ExecuteWhenTrue(PrintTimerQueueTimers, _commandLineOptions.TimerQueueTimer);
        ExecuteWhenTrue(PrintLongStrings, _commandLineOptions.LongString);

        void PrintHttpClients()
        {
            var analyzer = new HttpClientAnalyzer(runtimeContext);

            analyzer.TraversingHeapMode = traversingMode;

            var httpClients = analyzer.GetClientsInfo();

            foreach (var httpclient in httpClients)
            {
                logger.LogInformation($"{httpclient.Address} timeout = {httpclient.Timeout.TotalSeconds:F2} seconds");
            }
        }

        void PrintStringDuplicates()
        {
            var analyzer = new StringDuplicateAnalyzer(runtimeContext);

            analyzer.TraversingHeapMode = traversingMode;

            var duplicates = analyzer.GetStringDuplicates(10, 100);

            foreach (var duplicate in duplicates)
            {
                logger.LogInformation($"{duplicate.Count} instances of: {duplicate.String}");
            }
        }

        void PrintObjectTypeStatistics()
        {
            var analyzer = new ObjectTypeStatisticsAnalyzer(runtimeContext);

            analyzer.TraversingHeapMode = traversingMode;

            var statistics = analyzer.GetObjectTypeStatistics();

            foreach (var stat in statistics)
            {
                logger.LogInformation($"{stat.TypeName}: {stat.TotalSize} ({stat.InstanceCount} instances)");
            }
        }

        void PrintTimerQueueTimers()
        {
            var analyzer = new TimerQueueTimerAnalyzer(runtimeContext);

            analyzer.TraversingHeapMode = traversingMode;

            var timers = analyzer.GetTimers(traversingMode);

            foreach (var timer in timers)
            {
                logger.LogInformation($"{timer.Address} m_dueTime = {timer.DueTime}, m_period = {timer.Period}, m_canceled = {timer.Cancelled}");

                if (timer.CancellationState != null)
                {
                    logger.LogInformation($"CanBeCanceled: {timer.CancellationState.CanBeCanceled}");
                    logger.LogInformation($"IsCancellationRequested: {timer.CancellationState.IsCancellationRequested}");
                    logger.LogInformation($"IsCancellationCompleted: {timer.CancellationState.IsCancellationCompleted}");
                }
            }
        }

        void PrintLongStrings()
        {
            var analyzer = new LongStringAnalyzer(runtimeContext);

            analyzer.TraversingHeapMode = traversingMode;

            var strings = analyzer.GetStrings(20, null);

            foreach (var s in strings)
            {
                logger.LogInformation($"{s.Address} Length = {s.Length} chars, Value = {s.Value}");
            }
        }
    }
Example #28
0
        static void handleException(Exception ex)
        {
            if (ex.Message == "Safe handle has been closed")
            {
                return;
            }

            if (MainV2.instance != null && MainV2.instance.IsDisposed)
            {
                return;
            }

            MissionPlanner.Utilities.Tracking.AddException(ex);

            log.Debug(ex.ToString());

            GetStackTrace(ex);

            // hyperlinks error
            if (ex.Message == "Requested registry access is not allowed." ||
                ex.ToString().Contains("System.Windows.Forms.LinkUtilities.GetIELinkBehavior"))
            {
                return;
            }
            if (ex.Message.Contains("The port is closed"))
            {
                CustomMessageBox.Show("Serial connection has been lost");
                return;
            }
            if (ex.Message.Contains("Array.Empty"))
            {
                CustomMessageBox.Show("Please install Microsoft Dot Net 4.6.2");
                Application.Exit();
                return;
            }
            if (ex.Message.Contains("A device attached to the system is not functioning"))
            {
                CustomMessageBox.Show("Serial connection has been lost");
                return;
            }
            if (ex.GetType() == typeof(OpenTK.Graphics.GraphicsContextException))
            {
                CustomMessageBox.Show("Please update your graphics card drivers. Failed to create opengl surface\n" + ex.Message);
                return;
            }
            if (ex.GetType() == typeof(MissingMethodException) || ex.GetType() == typeof(TypeLoadException))
            {
                CustomMessageBox.Show("Please Update - Some older library dlls are causing problems\n" + ex.Message);
                return;
            }
            if (ex.GetType() == typeof(ObjectDisposedException) || ex.GetType() == typeof(InvalidOperationException))
            // something is trying to update while the form, is closing.
            {
                log.Error(ex);
                return; // ignore
            }
            if (ex.GetType() == typeof(FileNotFoundException) || ex.GetType() == typeof(BadImageFormatException))
            // i get alot of error from people who click the exe from inside a zip file.
            {
                CustomMessageBox.Show(
                    "You are missing some DLL's. Please extract the zip file somewhere. OR Use the update feature from the menu " +
                    ex.ToString());
                // return;
            }
            // windows and mono
            if (ex.StackTrace != null && ex.StackTrace.Contains("System.IO.Ports.SerialStream.Dispose") ||
                ex.StackTrace != null && ex.StackTrace.Contains("System.IO.Ports.SerialPortStream.Dispose"))
            {
                log.Error(ex);
                return; // ignore
            }

            log.Info("Th Name " + Thread?.Name);

            var dr =
                CustomMessageBox.Show("An error has occurred\n" + ex.ToString() + "\n\nReport this Error???",
                                      "Send Error", MessageBoxButtons.YesNo);

            if ((int)DialogResult.Yes == dr)
            {
                try
                {
                    string data = "";
                    foreach (System.Collections.DictionaryEntry de in ex.Data)
                    {
                        data += String.Format("-> {0}: {1}", de.Key, de.Value);
                    }

                    string message = "";

                    try
                    {
                        Controls.InputBox.Show("Message", "Please enter a message about this error if you can.",
                                               ref message);
                    }
                    catch
                    {
                    }

                    string processinfo = "";

                    try
                    {
                        var result = new Dictionary <int, string[]>();

                        var pid = Process.GetCurrentProcess().Id;

                        using (var dataTarget = DataTarget.AttachToProcess(pid, 5000, AttachFlag.Passive))
                        {
                            ClrInfo runtimeInfo = dataTarget.ClrVersions[0];
                            var     runtime     = runtimeInfo.CreateRuntime();

                            foreach (var t in runtime.Threads)
                            {
                                result.Add(
                                    t.ManagedThreadId,
                                    t.StackTrace.Select(f =>
                                {
                                    if (f.Method != null)
                                    {
                                        return(f.Method.Type.Name + "." + f.Method.Name);
                                    }

                                    return(null);
                                }).ToArray()
                                    );
                            }
                        }

                        processinfo = result.ToJSON(Formatting.Indented); //;Process.GetCurrentProcess().Modules.ToJSON();
                    }
                    catch
                    {
                    }

                    // Create a request using a URL that can receive a post.
                    WebRequest request = WebRequest.Create("http://vps.oborne.me/mail.php");
                    request.Timeout = 10000; // 10 sec
                    // Set the Method property of the request to POST.
                    request.Method = "POST";
                    // Create POST data and convert it to a byte array.
                    string postData = "message=" + Environment.OSVersion.VersionString + " " +
                                      System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString()
                                      + " " + Application.ProductVersion
                                      + "\nException " + ex.ToString().Replace('&', ' ').Replace('=', ' ')
                                      + "\nStack: " + ex.StackTrace.ToString().Replace('&', ' ').Replace('=', ' ')
                                      + "\nTargetSite " + ex.TargetSite + " " + ex.TargetSite.DeclaringType
                                      + "\ndata " + data
                                      + "\nmessage " + message.Replace('&', ' ').Replace('=', ' ')
                                      + "\n\n" + processinfo;
                    byte[] byteArray = Encoding.ASCII.GetBytes(postData);
                    // Set the ContentType property of the WebRequest.
                    request.ContentType = "application/x-www-form-urlencoded";
                    // Set the ContentLength property of the WebRequest.
                    request.ContentLength = byteArray.Length;
                    // Get the request stream.
                    using (Stream dataStream = request.GetRequestStream())
                    {
                        // Write the data to the request stream.
                        dataStream.Write(byteArray, 0, byteArray.Length);
                    }
                    // Get the response.
                    using (WebResponse response = request.GetResponse())
                    {
                        // Display the status.
                        Console.WriteLine(((HttpWebResponse)response).StatusDescription);
                        // Get the stream containing content returned by the server.
                        using (Stream dataStream = response.GetResponseStream())
                        {
                            // Open the stream using a StreamReader for easy access.
                            using (StreamReader reader = new StreamReader(dataStream))
                            {
                                // Read the content.
                                string responseFromServer = reader.ReadToEnd();
                                // Display the content.
                                Console.WriteLine(responseFromServer);
                            }
                        }
                    }
                }
                catch (Exception exp)
                {
                    Console.WriteLine(exp.ToString());
                    log.Error(exp);
                    CustomMessageBox.Show("Could not send report! Typically due to lack of internet connection.");
                }
            }
        }
Example #29
0
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            var crashDumpPath = "../../artefacts/core_20200503_003216";

            using (DataTarget dataTarget = DataTarget.LoadDump(crashDumpPath))
            {
                foreach (ClrInfo version in dataTarget.ClrVersions)
                {
                    Console.WriteLine("Found CLR Version: " + version.Version);

                    // This is the data needed to request the dac from the symbol server:
                    DacInfo dacInfo = version.DacInfo;
                    Console.WriteLine("Filesize:  {0:X}", dacInfo.IndexFileSize);
                    Console.WriteLine("Timestamp: {0:X}", dacInfo.IndexTimeStamp);
                    Console.WriteLine("Dac File:  {0}", dacInfo.PlatformSpecificFileName);

                    // If we just happen to have the correct dac file installed on the machine,
                    // the "LocalMatchingDac" property will return its location on disk:
                    string dacLocation = version.DacInfo.LocalDacPath;;
                    if (!string.IsNullOrEmpty(dacLocation))
                    {
                        Console.WriteLine("Local dac location: " + dacLocation);
                    }

                    ClrInfo    runtimeInfo = dataTarget.ClrVersions[0]; // just using the first runtime
                    ClrRuntime runtime     = runtimeInfo.CreateRuntime();

                    // You may also download the dac from the symbol server, which is covered
                    // in a later section of this tutorial.
                    foreach (ClrAppDomain domain in runtime.AppDomains)
                    {
                        Console.WriteLine("ID:      {0}", domain.Id);
                        Console.WriteLine("Name:    {0}", domain.Name);
                        Console.WriteLine("Address: {0}", domain.Address);
                        foreach (ClrModule module in domain.Modules)
                        {
                            Console.WriteLine("Module: {0}", module.Name);
                        }
                        foreach (ClrThread thread in runtime.Threads)
                        {
                            if (!thread.IsAlive)
                            {
                                continue;
                            }

                            Console.WriteLine("Thread {0:X}:", thread.OSThreadId);

                            foreach (ClrStackFrame frame in thread.EnumerateStackTrace())
                            {
                                Console.WriteLine("Stack Name: " + frame.ToString());
                                Console.WriteLine("{0,12:X} {1,12:X} {2}", frame.StackPointer, frame.InstructionPointer, frame);
                            }

                            Console.WriteLine();

                            Console.WriteLine("{0,12} {1,12} {2,12} {3,12} {4,4} {5}", "Start", "End", "CommittedMemory", "ReservedMemory", "Heap", "Type");
                            foreach (ClrSegment segment in runtime.Heap.Segments)
                            {
                                string type;
                                if (segment.IsEphemeralSegment)
                                {
                                    type = "Ephemeral";
                                }
                                else if (segment.IsLargeObjectSegment)
                                {
                                    type = "Large";
                                }
                                else
                                {
                                    type = "Gen2";
                                }

                                Console.WriteLine("{0,12:X} {1,12:X} {2,12:X} {3,12:X} {4,4} {5}", segment.Start, segment.End, segment.CommittedMemory, segment.ReservedMemory, segment.LogicalHeap, type);
                            }

                            foreach (var item in (from seg in runtime.Heap.Segments
                                                  group seg by seg.LogicalHeap into g
                                                  orderby g.Key
                                                  select new
                            {
                                Heap = g.Key,
                                Size = g.Sum(p => (uint)p.Length)
                            }))
                            {
                                Console.WriteLine("Heap {0,2}: {1:n0} bytes", item.Heap, item.Size);
                            }
                        }

                        foreach (var handle in runtime.EnumerateHandles())
                        {
                            string objectType = runtime.Heap.GetObjectType(handle.Object).Name;
                            Console.WriteLine("{0,12:X} {1,12:X} {2,12} {3}", handle.Address, handle.Object, handle.GetType(), objectType);
                        }


                        if (!runtime.Heap.CanWalkHeap)
                        {
                            Console.WriteLine("Cannot walk the heap!");
                        }
                        else
                        {
                            foreach (ClrSegment seg in runtime.Heap.Segments)
                            {
                                for (ulong obj = seg.FirstObjectAddress; obj != 0; obj = seg.GetNextObjectAddress(obj))
                                {
                                    ClrType type = runtime.Heap.GetObjectType(obj);

                                    // If heap corruption, continue past this object.
                                    if (type == null)
                                    {
                                        continue;
                                    }

                                    int size = type.StaticSize;
                                    Console.WriteLine("{0,12:X} {1,8:n0} {2,1:n0} {3}", obj, size, seg.GetGeneration(obj), type.Name);
                                }
                            }
                        }
                        //  https://github.com/microsoft/clrmd/blob/master/doc/WalkingTheHeap.md#walking-objects-without-walking-the-segments
                        if (!runtime.Heap.CanWalkHeap)
                        {
                            Console.WriteLine("Cannot walk the heap!");
                        }
                        else
                        {
                            foreach (ulong obj in runtime.Heap.EnumerateObjects())
                            {
                                ClrType type = runtime.Heap.GetObjectType(obj);

                                // If heap corruption, continue past this object.
                                if (type == null)
                                {
                                    continue;
                                }

                                int size = type.StaticSize;
                                Console.WriteLine("{0,12:X} {1,8:n0} {2,1:n0} {3}", obj, size, type.GCDesc, type.Name);
                            }
                        }
                    }
                }
            }
        }
Example #30
0
        private static KeyValuePair <bool, string> DisableScriptControl(int pid)
        {
            //Get SeDebug Privilege
            Process.EnterDebugMode();

            // attach to CylanceSvc process and locate the IsScriptControlEnabled field
            try
            {
#if DEBUG
                Console.WriteLine("Attaching to process with pid: " + targetPID);
#endif
                dt = DataTarget.AttachToProcess(pid, 10000, AttachFlag.NonInvasive);
            }
            catch (Exception e)
            {
#if DEBUG
                Console.WriteLine(e.ToString());
#endif
                return(new KeyValuePair <bool, string>(false, e.ToString()));
            }

            //If no ClrVersions, exit
            if (dt.ClrVersions.Count == 0)
            {
                return(new KeyValuePair <bool, string>(false, "No Clr Versions detected"));
            }

#if DEBUG
            foreach (var ver in dt.ClrVersions)
            {
                Console.WriteLine("Clr Runtime Version Found: " + ver.Version.ToString());
            }
#endif
            ClrInfo ClrVersion = dt.ClrVersions[0];

            ClrRuntime cRun = ClrVersion.CreateRuntime();

            ClrHeap Heap = cRun.GetHeap();

            try
            {
                KeyValuePair <ClrInstanceField, string> res = GetField("IsScriptControlEnabled", "Cylance.Host.MemDef.MemDef", Heap);

                if (res.Key == null)
                {
                    return(new KeyValuePair <bool, string>(false, res.Value));
                }

                ClrInstanceField field = res.Key;
                Console.WriteLine("IsScriptControlEnabled -> Protected: " + field.IsProtected.ToString());
                Console.WriteLine("IsScriptControlEnabled -> HasSimpleValue: " + field.HasSimpleValue.ToString());
                Console.WriteLine("IsScriptControlEnabled -> Offset: " + field.Offset.ToString("X8"));
                Console.WriteLine("IsScriptControlEnabled -> Memory Address: " + fieldAddr.ToInt64().ToString("X8"));
                Console.WriteLine("IsScriptControlEnabled -> Value: " + fieldValue.ToString());

                //Now that we have an address for the field, change it :)

                IntPtr hProcess = OpenProcess(allAccess, false, targetPID);
                if (hProcess == IntPtr.Zero || hProcess == null)
                {
                    return(new KeyValuePair <bool, string>(false, new Win32Exception(Marshal.GetLastWin32Error()).Message));
                }
#if DEBUG
                Console.WriteLine("Obtained process handle " + hProcess.ToString("X8"));
#endif

                bool   en  = false;
                byte[] buf = new byte[] { Convert.ToByte(en) };
                return(WriteToProcess(hProcess, buf, fieldAddr));
            }
            catch (Exception e)
            {
                return(new KeyValuePair <bool, string>(false, e.ToString()));
            }
        }
Example #31
0
        static void Main(string[] args)
        {
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
            if (args == null || args.Length != 1)
            {
                ShowHowToUse();
                return;
            }
            int    procId    = 0;
            string procIdStr = args.FirstOrDefault();

            if (!int.TryParse(procIdStr, out procId))
            {
                Console.WriteLine("Couldn't parse '{0}' as int, exiting...", procIdStr);
                return;
            }
            var currProc = Process.GetCurrentProcess();

            Console.WriteLine("{0}[{1}] is {2}", Path.GetFileName(currProc.MainModule.FileName), currProc.Id, GetArchitecture(Environment.Is64BitProcess));

            System.Diagnostics.Process process = null;
            bool targetProcIs64BitProcess      = false;

            try
            {
                process = System.Diagnostics.Process.GetProcessById(procId);
                targetProcIs64BitProcess = NativeWrapper.Is64BitProcess(process.Handle);
                Console.WriteLine("Successfully connected to {0} process '{1}'[{2}]", GetArchitecture(targetProcIs64BitProcess), process.MainModule.FileName, process.Id);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Couldn't connect to process '{0}'.  Error: {1}", procId, ex);
                return;
            }

            // If current process is x64 and target process is x86, we need restart it as x86 process
            if (Environment.Is64BitProcess && !targetProcIs64BitProcess)
            {
                Console.WriteLine("Need restart it as x86 process");
                string           path     = currProc.MainModule.FileName;
                string[]         splitted = Path.GetFileName(currProc.MainModule.FileName).Split('.');
                string           x86Path  = Path.Combine(Path.GetDirectoryName(path), splitted[0] + "_x86." + splitted[1]);
                ProcessStartInfo psi      = new ProcessStartInfo(x86Path, procIdStr);
                try { Process.Start(psi); }
                catch (Exception ex)
                {
                    Console.WriteLine("Couldn't start x86 process from '{0}'", x86Path);
                }
                return;
            }
            Console.WriteLine("Start working...");

            var now = DateTime.Now.ToString(CultureInfo.InvariantCulture)
                      .Replace(CultureInfo.InvariantCulture.DateTimeFormat.DateSeparator, "_")
                      .Replace(CultureInfo.InvariantCulture.DateTimeFormat.TimeSeparator, "_");
            string fileName = string.Format("{0}_{1}_{2}.txt", Path.GetFileName(process.MainModule.FileName), procId, now);

            Console.WriteLine("The result will be saved in: '{0}'", fileName);

            using (process)
            {
                using (var stream = File.OpenWrite(fileName))
                {
                    using (TextWriter tw = new StreamWriter(stream))
                    {
                        using (DataTarget dt = DataTarget.AttachToProcess(procId, 5000, AttachFlag.NonInvasive))
                        {
                            ClrInfo version = dt.ClrVersions[0];

                            tw.WriteLine("ClrVersion: {0}", version);
                            Console.WriteLine("ClrVersion: {0}", version);

                            tw.WriteLine("Process: {0}\r\nVersion: \r\n{1}", Path.GetFileName(process.MainModule.FileName), process.MainModule.FileVersionInfo);
                            Console.WriteLine("Process: {0}\r\nVersion: \r\n{1}", Path.GetFileName(process.MainModule.FileName), process.MainModule.FileVersionInfo);

                            EnumerateLoadedModules(tw, dt);
                            tw.WriteLine();
                            Console.WriteLine();

                            ClrRuntime runtime = null;
                            try
                            {
                                runtime = version.CreateRuntime();
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine("Couldn't create ClrRuntime, Exiting... :{0}", ex);
                                return;
                            }

                            ShowThreads(tw, runtime);
                            tw.WriteLine();
                            Console.WriteLine();

                            ShowApplicationDomains(tw, runtime);
                        }
                    }
                }
            }
            Console.WriteLine("Finished.");
        }
 public string FindDac(ClrInfo clrInfo) => FindDac(clrInfo.DacInfo.FileName, clrInfo.DacInfo.TimeStamp, clrInfo.DacInfo.FileSize);
        public string FindDac(ClrInfo clrInfo)
        {
            var dac = FindDac(clrInfo.DacInfo.FileName, clrInfo.DacInfo.TimeStamp, clrInfo.DacInfo.FileSize);

            return(dac);
        }