Как подключиться из C# к другому .NET процессу?

137
18 ноября 2020, 20:00

Как средствами C# подключиться к другому процессу и мониторить некоторые данные из него? Известно, что исследуемое приложение так же написано на .NET, при необходимости декомпилируется с помощью JetBrains dotPeek. Знаю, что можно работать с адресами, забив на то, что проект .NET, но хотелось бы использовать более удобные методы, обращаясь к значениям по именам свойств классов, отсюда и вопрос. Возможно это что-то вроде собственного отладчика получается, как в студии, только без временной остановки процесса.

Answer 1

Например, используя Microsoft.Diagnostics.Runtime. Впрочем, запросы у вас слишком велики: получить значения свойств без приостановки процесса (т.е. в пассивном режиме отладки) невозможно. Свойства - это, в конце концов, те же методы. Получить значение поля в пассивном режиме, конечно, можно. Например, следующий код демонстрирует присоединение к процессу в пассивном режиме, поиск в его управляемой куче объекта определенного типа и получение значения его поля:

using System;
using Microsoft.Diagnostics.Runtime;
namespace ConsoleApplication1
{
    class Program
    {       
        static void Main(string[] args)
        {
            DataTarget dt=DataTarget.AttachToProcess(17680,5000,AttachFlag.Passive); 
            using (dt)
            {
                ClrInfo runtimeInfo = dt.ClrVersions[0];
                ClrRuntime runtime = runtimeInfo.CreateRuntime();
                ClrType type;
                foreach (ulong obj in runtime.Heap.EnumerateObjectAddresses())
                {
                    type = runtime.Heap.GetObjectType(obj);
                    if (type == null) continue;
                    if (type.Name == "System.Windows.Forms.Form" || 
                        (type.BaseType != null && type.BaseType.Name == "System.Windows.Forms.Form"))
                    {
                        Console.WriteLine("Address 0x{0:X}: {1}", obj, type.Name);
                        ClrInstanceField f = type.GetFieldByName("Foo");
                        object val = f.GetValue(obj);
                        if (val != null) Console.WriteLine(val.ToString());
                    }
                }
            }
            Console.ReadKey();
        }
    } 
}

Примечание. Пример рассчитан на ClrMD v1.X. Во второй версии некоторые используемые API могли быть изменены.

READ ALSO
Умирает объект созданный при помощи EasyHook

Умирает объект созданный при помощи EasyHook

Я немного не до понимаю время жизни меж-доменных объектов, они же MarshalByRefObject, но вот я поставил хук на IDirect3DDevice9::EndScene, далее происходит какое-то...

159
Получить AssemblyVersion из Assembly

Получить AssemblyVersion из Assembly

Можно ли получить AssemblyVersion из Assembly без загрузки ее в процесс(Из файла)?

141
Как реализовать запрос c Row_Number в MySQL?

Как реализовать запрос c Row_Number в MySQL?

Как реализовать ROW_NUMBER() OVER ( PARTITION BY row1, row2 ORDER BY row3) с двумя поля в PARTITION BY, как пример:

107
Не меняется кодировка(Collation) в столбце MySQL

Не меняется кодировка(Collation) в столбце MySQL

пытаюсь сделать столбец регистрозависимым путем смены Collation на utf8_binНо после выполнения скрипта ничего не меняется и столбец остается table default

149