私は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
これは、MicrosoftWindowsの静的にリンクされた実行可能ファイルであることを意味します。それをWindowsボックスにドロップすると、実行されます(実行されるはずです)。
私はwine
を持っています インストールされていますが、wine
、Windowsアプリの互換性レイヤーであるため、Hello.exe
の実行には約5倍の時間がかかります。 mono
として 直接実行するので、wine
ではありません それを実行します。
mono
があると思います mono
とともにインストールされたカーネルモジュール exec
をインターセプトします syscall / s、または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");
}
}
承認された回答:
これは実際のbinfmt_miscです。これにより、カーネルは、知らないバイナリを実行する方法を知ることができます。 /proc/sys/fs/binfmt_misc
の内容を見てください;そこに表示されるファイルの中で、モノバイナリを実行する方法を説明する必要があります:
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実行可能ファイル(WindowsPEおよびPE+バイナリだけでなく、DOSおよびOS / 2バイナリも含まれます!)、Java JARファイルなどの新しいバイナリタイプをサポートできます。また、既知のバイナリタイプを新しいアーキテクチャでサポートできます。 、通常はQemuを使用します。したがって、適切なライブラリを使用すると、Intelプロセッサ上でARM Linuxバイナリを透過的に実行できます!
関連:チートシートを忘れたLinuxのこと
あなたの質問は、.NETの意味ではありますが、クロスコンパイルから生じたものであり、binfmt_misc
に関する警告が表示されます。 :クロスコンパイルされたバイナリを実行できるシステムでクロスコンパイルしようとすると、一部の構成スクリプトが誤動作します。通常、クロスコンパイルの検出には、バイナリの構築と実行の試行が含まれます。実行されている場合はクロスコンパイルされていません。実行されていない場合は、クロスコンパイルされています(またはコンパイラが壊れています)。 autoconf
この場合、スクリプトは通常、ビルドアーキテクチャとホストアーキテクチャを明示的に指定することで修正できますが、binfmt_misc
を無効にする必要がある場合もあります。 一時的に…