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");
}
}
php hello.phporpython hello.pyorperl hello.plor in case of compiled language like javajava hellothey would also run as their are no executable there but a program read and execute file. However if you run./hello.exeinstead ofmono hello.exethe I found your question and accepted answer more reasonable (which in case definitely use binfmt-support.program codefile, in your case program is mono, while my examples includes php, python, perl and java. I suspect if mono allow extension to other than .exe file still executed via code. It should not depend at all on windows as finally this is execute a compiled code. However if your source file have some dependent code like windows only APIs then obviously you must need wine for running that exe file./etc/magicor/usr/share/file/magic(or similar magical location) is the file that contains the information necessary to be able to do this.$ foo.jarrather than$ java -jar foo.jar- similar to what is done for mono.