私はC#を学んでいるので、C#プログラムを作成してHello, World!
それをコンパイルし、mono-csc
次のように実行しましたmono
。
$ mono-csc Hello.cs
$ mono Hello.exe
Hello, World!
私はそれをクリックすると実行可能とマークされているTAB
ことがわかりました。実際にはファイル名をロードするシェルを介してのみ実行されます。bash
Hello.exe
Hello.exe
はいいいえ興味深いファイル拡張子を持つELFファイル:
$ 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
これは、Microsoft Windowsの静的にリンクされた実行可能ファイルであることを意味します。 Windowsコンピュータに挿入すると実行されます。
wine
インストールしてみましたが、Windowswine
アプリケーションの互換性レイヤーで直接実行するよりも、実行時間が5倍ほど長く、Hello.exe
実行する方法mono
ではありません。wine
システムコールを傍受するか、で始まるバイナリをキャプチャするいくつかのmono
カーネルモジュールがインストールされていると仮定しますが、エラーを返します。mono
exec
4D 5A
lsmod | grep mono
ここで何が起こっているのか、カーネルはこれをどうやって知ることができますか?これ実行ファイルは特別ですか?
ただそうではないことを証明するために私のものシェルは魔法を働かせます。私は使用しましたスクラップシェル(別名sh
)これを実行すると、まだデフォルトで実行されます。
コメント作成者が気になったので、プログラム全体は次のようになります。
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");
}
}
答え1
これはbinfmt_misc実際の適用:カーネルが自分の知らないバイナリを実行する方法を教えてください。 ;表示できる/proc/sys/fs/binfmt_misc
ファイルには、Monoバイナリを実行する方法が記載されています。
enabled
interpreter /usr/lib/binfmt-support/run-detectors
flags:
offset 0
magic 4d5a
(Debian システムで).これはMZ
、()で4d5a
始まるバイナリがに提供されるべきであることをカーネルに伝えますrun-detectors
。後者は、バイナリの実行に Mono または Wine を使用するかどうかを決定します。
バイナリタイプはいつでも追加、削除、有効化、および無効化できます。詳細については上記のドキュメントを参照してください(意味は驚くべきことです。ここで使用されている仮想ファイルシステムは標準ファイルシステムとまったく同じようには機能しません)。/proc/sys/fs/binfmt_misc/status
グローバル状態が与えられると、各バイナリ「説明者」は個々の状態を表示する。これを無効にする別の方法binfmt_misc
は、カーネルモジュールを削除することです(モジュールとして構築されている場合)。これは、完全に防止するためにブラックリストに登録できることを意味します。
この機能を使用すると、MZ実行可能ファイル(Windows PEおよびPE +バイナリ、およびDOSおよびOS / 2バイナリも含まれています)、Java JARファイルなどの新しいバイナリタイプをサポートできます。既知のバイナリタイプもサポートできます。新しいアーキテクチャでは、しばしばQemuを使用します。 ;したがって、適切なライブラリを使用すると、IntelプロセッサでARM Linuxバイナリを透過的に実行できます。
問題は.NETの意味ではありますが、クロスコンパイルから来ており、これには注意事項がありますbinfmt_misc
。クロスコンパイルされたバイナリを実行できるシステムでクロスコンパイルしようとすると、一部の構成スクリプトでエラーが発生します。通常、クロスコンパイルを検出するには、バイナリをビルドして実行しようとする必要があります。バイナリが実行されるとクロスコンパイルではなく、そうでなければクロスコンパイル中です(またはコンパイラが破損しています)。autoconf
この場合、通常はビルドとホストのアーキテクチャを明示的に指定してスクリプトを変更できますが、時々一時的に無効にする必要があるかもしれませんbinfmt_misc
...