
本当に驚くべきことを発見しました。
私は、Windowsコンピュータで(Visual Studioから)を使用して単純なC# Hello Worldをコンパイルしcsc
、結果のexe
ファイルをLinuxコンピュータにコピーして、で実行することができますmono helloworld.exe
。これまでのところ、すべてが私には理にかなっています。このSOの投稿Windows の場合、helloworld.exe
これは基本的に C# ランタイムを起動するだけのトリックであり、CIL バイトコードはファイルの後半のデータ セクションから読み取られるだけです。同様に、Linux の場合、 を実行すると C# ランタイムが起動し、exe トリックを気にすることなくバイトコードが直接読み取られるexe
と思います。mono helloworld.exe
後世のために、ここに私が入手した情報源を載せておきます。Charles Petzold の優れた無料の C# 本:
//---------------------------------------------
// FirstProgram.cs (c) 2006 by Charles Petzold
//---------------------------------------------
class FirstProgram
{
public static void Main()
{
System.Console.WriteLine("Hello, Microsoft .NET Framework!");
}
}
しかし、ここからが面白いところです。Linux (uname -r
私のマシンでは4.14.188-1-MANJARO
) では、単純に./helloworld.exe
これを実行するだけで動作します。
私は調査を始めましたが、実行中の最初の数行は次のとおりですstrace ./helloworld.exe
。
execve("./hw.exe", ["./hw.exe"], 0x7fffae8e6070 /* 61 vars */) = 0
[ Process PID=3381 runs in 32 bit mode. ]
brk(NULL) = 0x7eedb000
arch_prctl(0x3001 /* ARCH_??? */, 0xffb19948) = -1 EINVAL (Invalid argument)
readlink("/proc/self/exe", "/usr/bin/wine", 4096) = 13
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xf7faa000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/bin/../lib32/tls/i686/sse2/libwine.so.1", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/usr/bin/../lib32/tls/i686/sse2", 0xffb18e00) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/bin/../lib32/tls/i686/libwine.so.1", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/usr/bin/../lib32/tls/i686", 0xffb18e00) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/bin/../lib32/tls/sse2/libwine.so.1", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/usr/bin/../lib32/tls/sse2", 0xffb18e00) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/bin/../lib32/tls/libwine.so.1", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/usr/bin/../lib32/tls", 0xffb18e00) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/bin/../lib32/i686/sse2/libwine.so.1", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/usr/bin/../lib32/i686/sse2", 0xffb18e00) = -1 ENOENT (No such file or directory)
Linux プログラム ローダーが Windows の PE 形式ではなく ELF ファイルのみを理解すると予想していたため、「このファイルは有効な実行ファイルではありません」というエラーが表示されることを予想していました。しかし、どうやらシステムは Wine の検索を開始するほど賢いようです (出力ではstrace
、Wine ライブラリの検索が開始されていることがわかります。Linux マシンに Wine をインストールしていたため、最終的には後で見つかります)。
それで何が起こっているのでしょうか?execve
呼び出しは、PE ファイルを検出すると wine の使用を試みるのに十分賢いのでしょうか、それともこれは何かbash
実行されているのでしょうか? それとも、まったく別の何かなのでしょうか?
答え1
パッケージ マネージャー経由で Wine または Mono のいずれかがインストールされており、それとともに、ユーザーが exe ファイルを起動したときにカーネルに何を実行するかを指示する特別な構成ファイルもインストールされているはずです。
詳細はこちらをご覧ください:https://en.wikipedia.org/wiki/Binfmt_misc