I'm learning C#, so I made a little C# program that says Hello, World!, then compiled it with mono-csc and ran it with mono:
$ mono-csc Hello.cs
$ mono Hello.exe
Hello, World!
I noticed that when I hit TAB in bash, Hello.exe was marked executable. Indeed, it runs by just a shell loading the filename!
Hello.exe is not an ELF file with a funny file extension:
$ readelf -a Hello.exe
readelf: Error: Not an ELF file - it has the wrong magic bytes at the start
$ xxd Hello.exe | head -n1
00000000: 4d5a 9000 0300 0000 0400 0000 ffff 0000 MZ..............
MZ means it's a Microsoft Windows statically linked executable. Drop it onto a Windows box, and it will (should) run.
I have wine installed, but wine, being a compatibility layer for Windows apps, takes about 5x as long to run Hello.exe as mono and executing it directly do, so it's not wine that runs it.
I'm assuming there's some mono kernel module installed with mono that intercepts the exec syscall/s, or catches binaries that begin with 4D 5A, but lsmod | grep mono and friends return an error.
What's going on here, and how does the kernel know that this executable is special?
Just for proof it's not my shell working magic, I used the Crap Shell (aka sh) to run it and it still runs natively.
Here's the program in full, since a commenter was curious:
using System;
class Hello {
/// <summary>
/// The main entry point for the application
/// </summary>
[STAThread]
public static void Main(string[] args) {
System.Console.Write("Hello, World!\n");
}
}