3

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

但是,我无法终生停止其他进程并查看任何 AppDomain。我一直在使用如下代码(我基于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*。我考虑过迭代所有方法并在所有方法上设置断点,但我也无法迭代 Modules 列表。我试过 debugger.Options.Trace,但这与使用 TraceListeners 跟踪 MDbg 的执行有关,而不是跟踪目标应用程序。

我在发布模式下运行我的 noddy 调试器应用程序,在调试模式下运行目标。我正在使用 Visual C# 2010,但我束手无策。任何人都可以对此有所了解吗?

4

3 回答 3

0

这不会那么容易。我没有针对此问题的特定源代码,但我会像这样对其进行伪编码:

  • 停止 Mdbg 进程
  • 设置一个新的 AppDomain(混合应用程序可以有 .NET2 和 .NET4 程序集,因此在当前 appdomain 中反映它们可能会引发异常!!)

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

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

  • 遍历 tempDomain 中的程序集
  • 对于每个程序集,获取类型列表
  • 报告类型.名称
  • 卸载 tempDomain
  • 调用 MDbgProcess.Go
于 2012-08-09T09:19:47.403 回答
0

由于某些原因,您应该使用debugger.Processs.Active而不是proc变量。你也应该打电话debugger.Go()之前AsyncStop。所以最终代码

[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!");
} 
于 2013-05-09T13:28:15.143 回答
0

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

        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;
            }
        }
于 2010-04-28T21:08:56.023 回答