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.php
orpython hello.py
orperl hello.pl
or in case of compiled language like javajava hello
they would also run as their are no executable there but a program read and execute file. However if you run./hello.exe
instead ofmono hello.exe
the I found your question and accepted answer more reasonable (which in case definitely use binfmt-support. – kuldeep.kamboj Feb 03 '16 at 07:16program 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. – kuldeep.kamboj Feb 03 '16 at 13:04./hello.exe
which is without defining program and require it be executable, So there must be role of binfmt_misc to mark it as executable by mono. – kuldeep.kamboj Feb 03 '16 at 13:06/etc/magic
or/usr/share/file/magic
(or similar magical location) is the file that contains the information necessary to be able to do this. – Feb 03 '16 at 16:12magic
was just identifying native file types like media, I never realised it did interesting stuff like this :) – cat Feb 03 '16 at 16:15$ foo.jar
rather than$ java -jar foo.jar
- similar to what is done for mono. – Feb 03 '16 at 16:19binfmt_misc
doesn't usemagic
, but as long as the magic bytes are within the first 128 you can use the information given in the magic files to write abinfmt_misc
descriptor. If you want to find out more about magic files, look atlibmagic
. – Stephen Kitt Feb 03 '16 at 17:23