Monovation: Assembly Injection into Live Processes

People are loving the C# Interactive Shell.

In the past people have embedded languages like Boo into their applications (MonoDevelop and Banshee for example both have options to embed Boo and a shell).

Zoltan designed a new system for Mono that allows developers to inject and execute code into running Mono applications. Paolo provided significant feedback and design guidelines for the code to be incorporated into Mono.

Thanks to both Zoltan and Paolo this functionality is now available through the Mono.Management assembly: you provide an executable and a PID, and the executable is injected and its Main method executed on the target process:

	using Mono.Attach;

	[..]

	// Get a handle to a running Mono process.
	VirtualMachine vm = new VirtualMachine (pid);

	// Load hello.exe into the target process, and run it
	vm.Attach ("/tmp/hello.exe", "");
	

You can use this for billions of things of course. You could patch running programs, you could attach logging software to a running program, or you could inject a C# evaluator into a live application and examine its state, or tweak it live.

Zoltan came up with a really cool extension to the the csharp command (this is the command-line C# Interactive Shell). The csharp command now takes an --attach command line argument and a PID.

The csharp shell can now use the Mono.Attach.VirtualMachine to injects itself into the remote process and then the client and server communicate through a couple of sockets.

For example, this is the sample that Zoltan used to pitch his idea for supporting attaching to the virtual machine. With the following you can pause a live Banshee process:

$ ps aux | grep banshee
miguel   12359 17.0  2.7 141372 55708 pts/5    Sl+  14:30   0:02 banshee-1 /usr/lib64/banshee-1/Nereid.exe
$ csharp --attach 12359
csharp> using Banshee.ServiceStack;
csharp> using Banshee.Gui;
csharp> var s = ServiceManager.Get ();
csharp> s.PlaybackActions ["PlayPauseAction"].Activate ();
	

All of the code is now on SVN, you need both the mono and mcs modules from trunk.

A GUI Shell

The above commands are a tiny bit risky and are also limited to the shell.

The above commands will execute on a separate thread from the application, and any commands that you execute would be executed on a separate thread which could corrupt the state of your application.

So this weekend, I wrote a tool that integrates with Gtk# applications, its called gsharp and you can find it in the mono-tools module (it borrows some code from Banshee).

gsharp is a Gtk# version of the csharp command. What is important is that it also supports injection of the code on other programs, but makes sure that all the code executes in the Gtk# thread, by issuing all of its commands from the Gtk# idle handler. This means that it is safe to use gsharp with your Gtk# applications.

GUI version of the tool.

Here you can select which project you want to inject the GUI into:

Needs some work, show process names.

This version shows the gsharp tool attached to F-Spot, as I am not very familiar with the codebase, I can not do very much with it:

We will need to implement one of these as well for Windows.Forms applications. This should luckily be easy to do as most of the smarts live in the Mono.CSharp assembly (our embeddable compiler).

Security of Agents

A couple of weeks ago, I asked for people to weigh in on a security concern for temporary files. This was for Zoltan's attach functionality.

The code is now implemented and I would love if security experts could do a source code audit of our implementation. And validate whether our assumptions are safe.

Here is the source code.

Posted on 29 Sep 2008 by Miguel de Icaza
This is a personal web page. Things said here do not represent the position of my employer.