Ich lerne C#, also habe ich ein kleines C#-Programm erstellt, das Hello, World!
sagt , dann mit mono-csc
kompiliert und lief es mit mono
:
$ mono-csc Hello.cs
$ mono Hello.exe
Hello, World!
Ich habe das bemerkt, als ich TAB
gedrückt habe in bash
, Hello.exe
wurde als ausführbar markiert. Tatsächlich läuft es nur über eine Shell, die den Dateinamen lädt!
Hello.exe
ist nicht eine ELF-Datei mit einer komischen Dateiendung:
$ 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
bedeutet, dass es sich um eine statisch verknüpfte ausführbare Datei von Microsoft Windows handelt. Legen Sie es auf einer Windows-Box ab, und es wird (sollte) ausgeführt.
Ich habe wine
installiert, aber wine
, eine Kompatibilitätsebene für Windows-Apps, dauert etwa fünfmal so lange, um Hello.exe
auszuführen als mono
und es direkt auszuführen, also ist es kein wine
das läuft.
Ich nehme an, es gibt etwas mono
Kernel-Modul installiert mit mono
das fängt die exec
ab syscall/s oder fängt Binärdateien ab, die mit 4D 5A
beginnen , aber lsmod | grep mono
und Freunde geben einen Fehler zurück.
Was geht hier vor und woher weiß der Kernel, dass dies ausführbar ist etwas Besonderes?
Nur zum Beweis, es ist nicht mein Shell funktioniert, ich habe die Crap Shell (auch bekannt als sh
), um es auszuführen, und es wird immer noch nativ ausgeführt.
Hier ist das vollständige Programm, da ein Kommentator neugierig war:
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");
}
}
Akzeptierte Antwort:
Das ist binfmt_misc in Aktion:Es ermöglicht dem Kernel zu sagen, wie er Binärdateien ausführen soll, von denen er nichts weiß. Sehen Sie sich den Inhalt von /proc/sys/fs/binfmt_misc
an; Unter den Dateien, die Sie dort sehen, sollte eine erklären, wie man Mono-Binärdateien ausführt:
enabled
interpreter /usr/lib/binfmt-support/run-detectors
flags:
offset 0
magic 4d5a
(auf einem Debian-System). Dies teilt dem Kernel mit, dass Binärdateien mit MZ
beginnen (4d5a
) sollte an run-detectors
übergeben werden . Letzterer findet heraus, ob Mono oder Wine verwendet werden soll, um die Binärdatei auszuführen.
Binäre Typen können jederzeit hinzugefügt, entfernt, aktiviert und deaktiviert werden; Einzelheiten finden Sie in der obigen Dokumentation (die Semantik ist überraschend, das hier verwendete virtuelle Dateisystem verhält sich nicht ganz wie ein Standard-Dateisystem). /proc/sys/fs/binfmt_misc/status
gibt den globalen Status an, und jeder binäre „Deskriptor“ zeigt seinen individuellen Status. Eine andere Möglichkeit, binfmt_misc
zu deaktivieren soll sein Kernel-Modul entladen, wenn es als Modul gebaut wurde; das bedeutet auch, dass es möglich ist, es auf die schwarze Liste zu setzen, um es vollständig zu vermeiden.
Diese Funktion ermöglicht die Unterstützung neuer Binärtypen, wie z. B. ausführbare MZ-Dateien (zu denen Windows PE- und PE+-Binärdateien, aber auch DOS- und OS/2-Binärdateien gehören!), Java-JAR-Dateien usw. Es ermöglicht auch die Unterstützung bekannter Binärtypen auf neuen Architekturen , normalerweise mit Qemu; Daher können Sie mit den entsprechenden Bibliotheken ARM-Linux-Binärdateien transparent auf einem Intel-Prozessor ausführen!
Verwandte:Linux-Dinge, die ich vergesse, Spickzettel
Ihre Frage stammt aus der Cross-Kompilierung, wenn auch im Sinne von .NET, und das bringt eine Einschränkung mit binfmt_misc
mit sich :Einige Konfigurationsskripte verhalten sich schlecht, wenn Sie versuchen, auf einem System, auf dem die cross-kompilierten Binärdateien ausgeführt werden können, eine Cross-Kompilierung durchzuführen. Typischerweise beinhaltet das Erkennen von Cross-Compilation das Erstellen einer Binärdatei und den Versuch, sie auszuführen; Wenn es läuft, kompilieren Sie nicht, wenn nicht, sind Sie es (oder Ihr Compiler ist kaputt). autoconf
Skripte können in diesem Fall normalerweise behoben werden, indem die Build- und Host-Architektur explizit angegeben werden, aber manchmal müssen Sie binfmt_misc
deaktivieren vorübergehend…