如何使用 MDbg 以编程方式枚举正在运行的 .NET 进程中的类型?

发布于 2024-08-31 04:16:03 字数 1358 浏览 6 评论 0原文

我想打印正在运行的 .NET 进程中加载​​的所有不同类型的列表。我的计划是最终基于此构建一个 GUI 应用程序,因此我想从我的代码而不是第三方工具来完成此操作。我认为最好的选择是使用 MDbgCore 附加到正在运行的进程,然后使用 MDbgProcess.AppDomains 获取 CorAppDomain 对象,并尝试向下遍历对象模型。

但是,我一生都无法停止其他进程并查看任何应用程序域。我一直在使用如下代码(我基于 Mike Stall 的博客

    [MTAThread] // MDbg is MTA threaded
    static void Main(string[] args)
    {
        MDbgEngine debugger = new MDbgEngine();

        debugger.Options.StopOnModuleLoad = true;

        // Launch the debuggee.            
        int pid = Process.GetProcessesByName("VS2010Playground")[0].Id;
        MDbgProcess proc = debugger.Attach(pid);
        if (proc.IsAlive)
        {
            proc.AsyncStop().WaitOne();

            Console.WriteLine(proc.AppDomains.Count);
            if (proc.AppDomains.Count > 0)
            {
                Console.WriteLine(proc.AppDomains[0].CorAppDomain);
            }
        }

        Console.WriteLine("Done!");
    } 

此打印:

MDbgPlayground.exe
0
Done!

我尝试了各种风格的 debugger.Options.Stop*。我想过迭代所有方法并在所有方法上设置断点,但我也无法迭代模块列表。我尝试过 debugger.Options.Trace,但这与使用 TraceListeners 跟踪 MDbg 的执行有关,而不是跟踪目标应用程序。

我正在发布模式下运行我的 noddy 调试器应用程序,并在调试模式下运行目标。我正在使用 Visual C# 2010,但我已经束手无策了。任何人都可以阐明这一点吗?

I want to print out a list of all the different Types loaded in a running .NET process. My plan is to eventually build a GUI app based on this, so I want to do this from my code as opposed to a third party tool. I think my best bet is to use MDbgCore to attach to the running process, and then use MDbgProcess.AppDomains to get CorAppDomain objects, and try and walk the object model down.

However, I can't for the life of me stop the other process and see any AppDomains. I've been using code like the following (which I've based on code from Mike Stall's blog)

    [MTAThread] // MDbg is MTA threaded
    static void Main(string[] args)
    {
        MDbgEngine debugger = new MDbgEngine();

        debugger.Options.StopOnModuleLoad = true;

        // Launch the debuggee.            
        int pid = Process.GetProcessesByName("VS2010Playground")[0].Id;
        MDbgProcess proc = debugger.Attach(pid);
        if (proc.IsAlive)
        {
            proc.AsyncStop().WaitOne();

            Console.WriteLine(proc.AppDomains.Count);
            if (proc.AppDomains.Count > 0)
            {
                Console.WriteLine(proc.AppDomains[0].CorAppDomain);
            }
        }

        Console.WriteLine("Done!");
    } 

This prints:

MDbgPlayground.exe
0
Done!

I've tried various flavours of debugger.Options.Stop*. I've thought of iterating over all the methods and setting breakpoints on all of them, but I can't iterate over the Modules list either. I've tried debugger.Options.Trace, but that's to do with tracing execution of MDbg using TraceListeners, not tracing the target app.

I'm running my noddy debugger app in release mode, and the target in debug mode. I'm using Visual C# 2010, and I'm at my wit's end. Can anyone shed any light on this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

天涯沦落人 2024-09-07 04:16:03

只是做一些修补,尝试这样的事情(您可能需要根据需要进行修改)...

        foreach (Process process in Process.GetProcesses())
        {
            try
            {
                Assembly test = Assembly.LoadFrom(process.MainModule.FileName);
                Console.WriteLine(test.FullName);

                foreach (Type type in test.GetTypes())
                    Console.WriteLine(type.FullName);
            }
            catch
            {
                continue;
            }
        }

Just doing some tinkering, try something like this (you may need to modify as necesary)...

        foreach (Process process in Process.GetProcesses())
        {
            try
            {
                Assembly test = Assembly.LoadFrom(process.MainModule.FileName);
                Console.WriteLine(test.FullName);

                foreach (Type type in test.GetTypes())
                    Console.WriteLine(type.FullName);
            }
            catch
            {
                continue;
            }
        }
極樂鬼 2024-09-07 04:16:03

这不会那么容易。我没有解决这个问题的具体源代码,但我会像这样伪编码:

  • Do a stop on the Mdbg process
  • Setup a new AppDomain (混合应用程序可以有 .NET2 和 .NET4 程序集,因此反映当前应用程序域中的它们可能会引发异常!!)

    System.AppDomain tempDomain=System.AppDomain.CreateDomain("ReflectionOnly");

  • 迭代 MDbgProcess.Modules 并将它们加载到应用程序域中,仅使用 Assembly.ReflectionOnlyLoad 进行反射(请参阅 如何加载 .NET 程序集以进行反射操作并随后卸载它?)

  • 迭代 tempDomain 中的程序集
  • 对于每个程序集,获取类型列表
  • 报告 Type.Name
  • Unload tempDomain
  • Invoke MDbgProcess.Go

This is not going to be so easy. I don't have specific source code for this problem, but I would pseudo-code it like this:

  • Do a stop on the Mdbg process
  • Setup a new AppDomain (mixed apps can have .NET2 and .NET4 assemblies, so reflecting on them in the current appdomain may throw an exception!!)

    System.AppDomain tempDomain=System.AppDomain.CreateDomain("ReflectionOnly");

  • Iterate through MDbgProcess.Modules and load them into the appdomain for reflection-only using Assembly.ReflectionOnlyLoad (see How to load a .NET assembly for reflection operations and subsequently unload it?)

  • Iterate through the assemblies in tempDomain
  • For each assembly, get a list of types
  • Report the Type.Name
  • Unload tempDomain
  • Invoke MDbgProcess.Go
静若繁花 2024-09-07 04:16:03

由于某些原因,您应该使用 debugger.Processs.Active 而不是 proc 变量。
另外,您应该在 AsyncStop 之前调用 debugger.Go()。所以最终代码

[MTAThread] // MDbg is MTA threaded
static void Main(string[] args)
{
    MDbgEngine debugger = new MDbgEngine();

    debugger.Options.StopOnModuleLoad = true;

    // Launch the debuggee.            
    int pid = Process.GetProcessesByName("VS2010Playground")[0].Id;
    MDbgProcess proc = debugger.Attach(pid);
    proc.Go();
    if (proc.IsAlive)
    {
        proc.AsyncStop().WaitOne();

        Console.WriteLine(debugger.Process.Active.AppDomains.Count);
        if ((debugger.Process.Active.AppDomains.Count > 0)
        {
            Console.WriteLine((debugger.Process.Active.AppDomains[0].CorAppDomain);
        }
    }

    Console.WriteLine("Done!");
} 

For some reasons you should use debugger.Processs.Active instead of proc variable.
Also you should call debugger.Go() before AsyncStop. So final code

[MTAThread] // MDbg is MTA threaded
static void Main(string[] args)
{
    MDbgEngine debugger = new MDbgEngine();

    debugger.Options.StopOnModuleLoad = true;

    // Launch the debuggee.            
    int pid = Process.GetProcessesByName("VS2010Playground")[0].Id;
    MDbgProcess proc = debugger.Attach(pid);
    proc.Go();
    if (proc.IsAlive)
    {
        proc.AsyncStop().WaitOne();

        Console.WriteLine(debugger.Process.Active.AppDomains.Count);
        if ((debugger.Process.Active.AppDomains.Count > 0)
        {
            Console.WriteLine((debugger.Process.Active.AppDomains[0].CorAppDomain);
        }
    }

    Console.WriteLine("Done!");
} 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文