私はC#を学んでいるので、Hello, World!
と言う小さなC#プログラムを作成し、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
をインストールしていますが、wine
はWindowsアプリの互換性レイヤーであるため、Hello.exe
をmono
として実行するのに約5倍の時間がかかり、直接実行しますなので、実行するのはwine
ではありません。
mono
syscall/sをインターセプトする、または4D 5A
で始まるバイナリをキャッチするmono
とともにインストールされているexec
カーネルモジュールがあると仮定していますが、lsmod | grep mono
と友達はエラーを返します。
ここで何が起こっているのですか、そしてカーネルはthis実行可能ファイルが特別であることをどのようにして知っていますか?
証明のためだけではありませんmyシェルの動作魔法、私は The Crap Shell (aka 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");
}
}
これは 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
_を無効にするもう1つの方法は、モジュールとして構築されている場合、カーネルモジュールをアンロードすることです。これは、完全に回避するためにブラックリストに登録することが可能であることも意味します。
この機能により、MZ実行可能ファイル(Windows PEおよびPE +バイナリだけでなく、DOSおよびOS/2バイナリも含まれます)などの新しいバイナリタイプをサポートできます。Java JARファイル...また、既知のバイナリタイプを新しいアーキテクチャでサポートできるようになり、通常はQemuを使用するため、適切なライブラリを使用して、IntelプロセッサでARM Linuxバイナリを透過的に実行できます。
あなたの質問は、.NETの意味ではありますが、クロスコンパイルから生じたもので、_binfmt_misc
_に関する警告が表示されます。クロスコンパイルされたバイナリを実行できるシステムでクロスコンパイルしようとすると、一部の構成スクリプトが正しく動作しません。通常、クロスコンパイルの検出には、バイナリの構築と実行の試行が含まれます。実行された場合、クロスコンパイルは行われず、実行されなかった場合(またはコンパイラが壊れています)。この場合、autoconf
スクリプトは通常、ビルドアーキテクチャとホストアーキテクチャを明示的に指定することで修正できますが、_binfmt_misc
_を一時的に無効にする必要がある場合があります...