Как программно перечислить типы в работающем процессе .NET с использованием MDbg? - PullRequest
3 голосов
/ 29 апреля 2010

Я хочу распечатать список всех различных типов, загруженных в работающий процесс .NET. Мой план состоит в том, чтобы в конечном итоге построить приложение с графическим интерфейсом на основе этого, поэтому я хочу сделать это из своего кода, а не стороннего инструмента. Я думаю, что лучше всего использовать MDbgCore для присоединения к запущенному процессу, а затем использовать MDbgProcess.AppDomains для получения объектов CorAppDomain и попробовать пройти объектную модель вниз.

Однако я не могу на всю жизнь остановить другой процесс и посмотреть какие-либо домены приложений. Я использую код, подобный следующему (который основан на коде из блога Майка Сталла )

    [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.Trace, но это связано с отслеживанием выполнения MDbg с использованием TraceListeners, а не с отслеживанием целевого приложения.

Я запускаю мое приложение noddy debugger в режиме выпуска, а цель в режиме отладки. Я использую Visual C # 2010, и я нахожусь в конце своего ума. Кто-нибудь может пролить свет на это?

Ответы [ 3 ]

0 голосов
/ 09 августа 2012

Это не так просто. У меня нет конкретного исходного кода для этой проблемы, но я бы псевдокод это так:

  • Остановить процесс Mdbg
  • Установка нового домена приложений (смешанные приложения могут иметь сборки .NET2 и .NET4, поэтому их отражение в текущем домене приложения может вызвать исключение !!)

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

  • Выполните итерацию по модулям MDbgProcess.Modules и загрузите их в домен приложения только для отражения, используя Assembly.ReflectionOnlyLoad (см. Как загрузить сборку .NET для операций отражения и затем выгрузить ее? )

  • Перебирать сборки в tempDomain
  • Для каждой сборки получить список типов
  • Сообщить о типе. Имя
  • Выгрузить tempDomain
  • Invoke MDbgProcess.Go
0 голосов
/ 09 мая 2013

По некоторым причинам вы должны использовать 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!");
} 
0 голосов
/ 29 апреля 2010

Просто немного повозившись, попробуйте что-то вроде этого (вам может понадобиться изменить его как необходимый) ...

        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;
            }
        }
...