How can C # connect to another process and monitor some data from it? It is known that the application under study is also written in .NET, if necessary it is decompiled using JetBrains dotPeek. I know that you can work with addresses, scoring on the fact that the project is .NET, but I would like to use more convenient methods, referring to the values ​​by the names of the properties of the classes, hence the question. Perhaps this is something like a debugger of your own, like in a studio, but without a temporary stop of the process.

  • If it were, for example, a standard PE, it would be possible to calculate the offset and try to get the data from the memory and recreate the data structure in your program and then work with it, and then most likely it will not work. The studio debugger will not allow you to debug something without source codes, so the analogy here is not quite appropriate. Studio debugging leads by source. - Dmitry Gvozd
  • See the windbg. - Vasek
  • @ Dmitry Gvozd, but you can debug the decompiled projects in the studio, if the same JetBrains dotPeek generates symbol files together with the source code. Well, the whole thing is that I don’t want to calculate displacements and so on. After all, the studio somehow does it without crap, which means you can do it yourself. But how? - Jluc

1 answer 1

For example, using Microsoft.Diagnostics.Runtime . However, your requests are too high: it is impossible to get the property values ​​without pausing the process (that is, in the passive debugging mode). Properties are, after all, the same methods. Obtain the value of the field in the passive mode, of course, possible. For example, the following code demonstrates attaching to a process in the passive mode, searching in its controlled heap an object of a certain type and getting the value of its field:

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(); } } } 
  • Here, here is something I wanted! Thank you so much!) - Jluc