예제 #1
0
    MetaDataReader(string moduleName)
    {
        CLRMetaHost    mh = new CLRMetaHost();
        CLRRuntimeInfo highestInstalledRuntime = null;

        foreach (CLRRuntimeInfo runtime in mh.EnumerateInstalledRuntimes())
        {
            if (highestInstalledRuntime == null ||
                string.Compare(highestInstalledRuntime.GetVersionString(), runtime.GetVersionString(), StringComparison.OrdinalIgnoreCase) < 0)
            {
                highestInstalledRuntime = runtime;
            }
        }
        if (highestInstalledRuntime == null)
        {
            throw new ApplicationException("Could not enumerate .NET runtimes on the system.");
        }

        IMetaDataDispenser metaDataDispenser = highestInstalledRuntime.GetIMetaDataDispenser();

        Guid   IMetaDataImport2_Guid = Guid("7DAC8207-D3AE-4c75-9B67-92801A497D44");
        object metaDataImportObj;

        metaDataDispenser.OpenScope(moduleName, 0, ref IMetaDataImport2_Guid, out metaDataImportObj);
        m_metaDataImport = metaDataImportObj as IMetadataImport2;
    }
예제 #2
0
        public int ProvideLibrary(string fileName, int timestamp, int sizeOfImage, out IntPtr hModule)
        {
            CLRMetaHost mh = new CLRMetaHost();

            foreach (CLRRuntimeInfo rti in mh.EnumerateInstalledRuntimes())
            {
                string libPath = Path.Combine(rti.GetRuntimeDirectory(), fileName);
                if (DoesFileMatch(libPath, timestamp, sizeOfImage))
                {
                    hModule = LoadLibrary(libPath);
                    if (hModule != IntPtr.Zero)
                    {
                        UpdateLastLoaded(fileName, libPath);
                        return(0);
                    }
                    else
                    {
                        return(-1);
                    }
                }
            }

            // not found
            hModule = IntPtr.Zero;
            return(-1);
        }
예제 #3
0
        private static void Main(string[] args)
        {
            int pid;

            if (args.Length == 1 && int.TryParse(args[0], out pid))
            {
                try
                {
                    var process = Process.GetProcessById(int.Parse(args[0]));

                    var mh = new CLRMetaHost();
                    mh.EnumerateLoadedRuntimes(process.Id);
                    var version     = MdbgVersionPolicy.GetDefaultAttachVersion(process.Id);
                    var debugger    = new CorDebugger(version);
                    var processInfo = new ProcessInfo(process, debugger);
                    foreach (var line in processInfo.GetDisplayStackTrace())
                    {
                        Console.WriteLine(line);
                    }
                }
                catch (Exception e)
                {
                    Console.Error.WriteLine("Error getting process thread dump: " + e);
                }
            }
            else
            {
                Console.Error.WriteLine("Simple utility to generate .NET managed process thread dump (similar to Java jstack)");
                Console.Error.WriteLine("Usage: " + AppDomain.CurrentDomain.FriendlyName + " <PID>");
            }
        }
예제 #4
0
        public static string clrDetails(this List <Process> clrProcesses)
        {
            var clrDetails = "";

            foreach (var clrProcess in clrProcesses)
            {
                var id       = clrProcess.Id;
                var name     = clrProcess.ProcessName;
                var fileName = clrProcess.MainModule.FileName;
                var runtimes = new CLRMetaHost().EnumerateLoadedRuntimes(id);
                var versions = (from runtime in runtimes
                                select runtime.GetVersionString()).toList().join(",");
                clrDetails += "id: {0} \t name: {1} \t runtimes: {2} \t fileName: {3}".line().format(id, name, versions, fileName);
            }
            return(clrDetails);
        }
예제 #5
0
        static void Main(string[] args)
        {
            var host    = new CLRMetaHost();
            var runtime = host.GetInstalledRuntimeByVersion("v4.0.30319");
            var debug   = runtime.GetLegacyICorDebugInterface();

            debug.Initialize();
            debug.SetManagedHandler(new SelfManagedCallback());

            STARTUPINFO si = new STARTUPINFO();

            si.cb = Marshal.SizeOf(si);

            // initialize safe handles
            si.hStdInput  = new Microsoft.Win32.SafeHandles.SafeFileHandle(new IntPtr(0), false);
            si.hStdOutput = new Microsoft.Win32.SafeHandles.SafeFileHandle(new IntPtr(0), false);
            si.hStdError  = new Microsoft.Win32.SafeHandles.SafeFileHandle(new IntPtr(0), false);

            PROCESS_INFORMATION pi = new PROCESS_INFORMATION();

            //constrained execution region (Cer)

            var appname = "test.exe";
            ICorDebugProcess proc;

            debug.CreateProcess(
                appname,
                appname,
                null,
                null,
                1,
                (UInt32)CreateProcessFlags.CREATE_NEW_CONSOLE,
                new IntPtr(0),
                ".",
                si,
                pi,
                CorDebugCreateProcessFlags.DEBUG_NO_SPECIAL_OPTIONS,
                out proc);

            //var runtime = GetRuntimeInfo(host);
            Console.WriteLine();

            Console.Read();
        }
예제 #6
0
        /// <summary>
        /// Returns the version of the runtime to debug in a process
        /// we are attaching to, assuming we can only pick one
        /// </summary>
        /// <param name="processId">The process to attach to</param>
        /// <returns>The version of the runtime to debug, or null if the policy can't decide</returns>
        public static string GetDefaultAttachVersion(int processId)
        {
            try
            {
                CLRMetaHost           mh       = new CLRMetaHost();
                List <CLRRuntimeInfo> runtimes = new List <CLRRuntimeInfo>(mh.EnumerateLoadedRuntimes(processId));
                if (runtimes.Count > 1)
                {
                    // It is ambiguous so just give up
                    return(null);
                }
                else if (runtimes.Count == 1)
                {
                    return(runtimes[0].GetVersionString());
                }
            }
            catch (EntryPointNotFoundException)
            {
                try
                {
                    return(CorDebugger.GetDebuggerVersionFromPid(processId));
                }
                catch (COMException) { }
            }

            // if we have neither failed nor detected a version at this point then there was no
            // CLR loaded. Now we try to determine what CLR the process will load by examining its
            // binary
            string binaryPath = GetBinaryPathFromPid(processId);

            if (binaryPath != null)
            {
                string version = GetDefaultRuntimeForFile(binaryPath);
                if (version != null)
                {
                    return(version);
                }
            }

            // and if that doesn't work, return the version of the CLR the debugger is
            // running against (a very arbitrary choice)
            return(Environment.Version.ToString());
        }
예제 #7
0
        /// <摘要>
        ///获得所有托管进程
        /// </摘要>
        public static List <ManagedProcess> GetManagedProcesses()
        {
            List <ManagedProcess> managedProcesses = new List <ManagedProcess>();

            // CLR宿主包含一个ICLRMetaHost接口,提供了一个方法,可以列举指定进程加载的所有运行时
            CLRMetaHost host = new CLRMetaHost();

            var processes = System.Diagnostics.Process.GetProcesses();

            foreach (System.Diagnostics.Process diagnosticsProcess in processes)
            {
                try
                {
                    // 列举指定进程加载的所有运行时
                    var runtimes = host.EnumerateLoadedRuntimes(diagnosticsProcess.Id);

                    // 如果进程加载了CLR,则被认定为托管进程
                    if (runtimes != null && runtimes.Count() > 0)
                    {
                        managedProcesses.Add(new ManagedProcess(diagnosticsProcess));
                    }
                }

                // 当文件无法找到或操作被拒绝时,EnumerateLoadedRuntimes方法会抛出Win32Exception异常
                // 例如:目标进程是系统进程或系统闲置进程
                catch (Win32Exception)
                { }


                // 在x86平台上创建的程序试图在64位操作系统上执行64位进程时,
                // EnumerateLoadedRuntimes方法会抛出COMException异常
                catch (COMException)
                { }


                // 再次抛出其他异常
                catch
                {
                    throw;
                }
            }
            return(managedProcesses);
        }
예제 #8
0
        /// <summary>
        /// Refreshes the processes hash which stores info on all managed process running
        /// </summary>
        public void RefreshProcessList()
        {
            processes.Clear();

            foreach (var process in Process.GetProcesses())
            {
                if (Process.GetCurrentProcess().Id == process.Id)
                {
                    // let's hide our process
                    continue;
                }

                // list the loaded runtimes in each process, if the ClrMetaHost APIs are available
                CLRMetaHost mh;
                try
                {
                    mh = new CLRMetaHost();
                }
                catch (Exception)
                {
                    continue;
                }

                IEnumerable <CLRRuntimeInfo> runtimes;
                try
                {
                    runtimes = mh.EnumerateLoadedRuntimes(process.Id);
                }
                catch (Exception)
                {
                    continue;
                }

                // TODO: only one CLR version for now...
                if (runtimes.Any())
                {
                    var version  = MdbgVersionPolicy.GetDefaultAttachVersion(process.Id);
                    var debugger = new CorDebugger(version);
                    processes[process.Id] = new ProcessInfo(process, debugger);
                }
            }
        }
예제 #9
0
        public static List <Process> attachableProcesses(this MDbgEngine engine)
        {
            var attachableProcesses = new List <Process>();

            foreach (var process in Process.GetProcesses())
            {
                if (Process.GetCurrentProcess().Id == process.Id)      // let's hide our process
                {
                    continue;
                }

                CLRMetaHost mh = null;
                try
                {
                    mh = new CLRMetaHost();
                }
                catch (System.EntryPointNotFoundException)
                {
                    continue;
                }

                IEnumerable <CLRRuntimeInfo> runtimes = null;
                try
                {
                    runtimes = mh.EnumerateLoadedRuntimes(process.Id);
                }
                catch
                {
                    continue;
                }

                //if there are no runtimes in the target process, don't print it out
                if (!runtimes.GetEnumerator().MoveNext())
                {
                    continue;
                }
                attachableProcesses.add(process);
            }
            return(attachableProcesses);
        }
예제 #10
0
        private static string FindAttachVersion(int pid)
        {
            var attachVersion     = MdbgVersionPolicy.GetDefaultAttachVersion(pid);
            var installedVersions = new CLRMetaHost().EnumerateInstalledRuntimes().Select(r => r.GetVersionString()).ToList();

            if (installedVersions.Contains(attachVersion))
            {
                return(attachVersion);
            }

            var matchingVersion = installedVersions.Find(v => attachVersion.Contains(v.Replace("v", "")) || v.Contains(attachVersion.Replace("v", "")));

            if (matchingVersion != null)
            {
                return(matchingVersion);
            }

            Console.WriteLine("Error: could not find installed runtime attach version.");
            Console.WriteLine("  Default attach version: " + attachVersion);
            Console.WriteLine("  Installed versions: " + string.Join(", ", installedVersions));
            return(null);
        }
예제 #11
0
        /// <summary>
        /// Gets all managed processes.
        /// </summary>
        public static List <ManagedProcess> GetManagedProcesses()
        {
            List <ManagedProcess> managedProcesses = new List <ManagedProcess>();

            // CLRMetaHost implements ICLRMetaHost Interface which provides a method that
            // return list all runtimes that are loaded in a specified process.
            CLRMetaHost host = new CLRMetaHost();

            var processes = System.Diagnostics.Process.GetProcesses();

            foreach (System.Diagnostics.Process diagnosticsProcess in processes)
            {
                try
                {
                    // Lists all runtimes that are loaded in a specified process.
                    var runtimes = host.EnumerateLoadedRuntimes(diagnosticsProcess.Id);

                    // If the process loads CLRs, it could be considered as a managed process.
                    if (runtimes != null && runtimes.Count() > 0)
                    {
                        managedProcesses.Add(new ManagedProcess(diagnosticsProcess));
                    }
                }

                // The method EnumerateLoadedRuntimes will throw Win32Exception when the
                // file cannot be found or access is denied. For example, the
                // diagnosticsProcess is System or System Idle Process.
                catch (Win32Exception)
                { }

                // The method EnumerateLoadedRuntimes will throw COMException when it tries
                // to access a 64bit process on 64bit OS if this application is built on
                // platform x86.
                catch (COMException)
                { }
            }
            return(managedProcesses);
        }
예제 #12
0
        void RefreshProcesses()
        {
            this.listBoxProcesses.Items.Clear();
            int count = 0;

            int curPid = System.Diagnostics.Process.GetCurrentProcess().Id;

            foreach (Process p in Process.GetProcesses())
            {
                if (Process.GetCurrentProcess().Id == p.Id)  // let's hide our process
                {
                    continue;
                }

                //list the loaded runtimes in each process, if the ClrMetaHost APIs are available
                CLRMetaHost mh = null;
                try
                {
                    mh = new CLRMetaHost();
                }
                catch (System.EntryPointNotFoundException)
                {
                    // Intentionally ignore failure to find GetCLRMetaHost().
                    // Downlevel we don't have one.
                    continue;
                }

                IEnumerable <CLRRuntimeInfo> runtimes = null;
                try
                {
                    runtimes = mh.EnumerateLoadedRuntimes(p.Id);
                }
                catch (System.ComponentModel.Win32Exception e)
                {
                    if ((e.NativeErrorCode != 0x0) &&           // The operation completed successfully.
                        (e.NativeErrorCode != 0x3f0) &&         // An attempt was made to reference a token that does not exist.
                        (e.NativeErrorCode != 0x5) &&           // Access is denied.
                        (e.NativeErrorCode != 0x57) &&          // The parameter is incorrect.
                        (e.NativeErrorCode != 0x514) &&         // Not all privileges or groups referenced are assigned to the caller.
                        (e.NativeErrorCode != 0x12))            // There are no more files.
                    {
                        // Unknown/unexpected failures should be reported to the user for diagnosis.
                        Console.WriteLine("Error retrieving loaded runtime information for PID " + p.Id
                                          + ", error " + e.ErrorCode + " (" + e.NativeErrorCode + ") '" + e.Message + "'");
                    }

                    // If we failed, don't try to print out any info.
                    if ((e.NativeErrorCode != 0x0) || (runtimes == null))
                    {
                        continue;
                    }
                }
                catch (System.Runtime.InteropServices.COMException e)
                {
                    if (e.ErrorCode != (int)HResult.E_PARTIAL_COPY)  // Only part of a ReadProcessMemory or WriteProcessMemory request was completed.
                    {
                        // Unknown/unexpected failures should be reported to the user for diagnosis.
                        Console.WriteLine("Error retrieving loaded runtime information for PID " + p.Id
                                          + ", error " + e.ErrorCode + "\n" + e.ToString());
                    }

                    continue;
                }

                //if there are no runtimes in the target process, don't print it out
                if (!runtimes.GetEnumerator().MoveNext())
                {
                    continue;
                }

                count++;


                string version = "";
                foreach (CLRRuntimeInfo rti in runtimes)
                {
                    version += rti.GetVersionString();
                }
                string s = "[" + p.Id + "] [ver=" + version + "] " + p.MainModule.FileName;
                this.listBoxProcesses.Items.Add(new Item(p.Id, s));
            }

            if (count == 0)
            {
                this.listBoxProcesses.Items.Add(new Item(0, "(No active processes)"));
            }
        }