モノの驚くべき点は何ですか?

モノの驚くべき点は何ですか?

私はC#を学んでいるので、C#プログラムを作成してHello, World!それをコンパイルし、mono-csc次のように実行しましたmono

$ mono-csc Hello.cs
$ mono Hello.exe
Hello, World!

私はそれをクリックすると実行可能とマークされているTABことがわかりました。実際にはファイル名をロードするシェルを介してのみ実行されます。bashHello.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カーネルモジュールがインストールされていると仮定しますが、エラーを返します。monoexec4D 5Alsmod | 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...

関連情報