Mono 有何神奇之处?

Mono 有何神奇之处?

我正在学习 C#,所以我制作了一个 C# 程序Hello, World!,然后用 编译它mono-csc并运行它mono

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

我注意到当我点击 , 时TABbash标记Hello.exe为可执行。事实上,它仅通过加载文件名的 shell 来运行!

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 应用程序的兼容层,运行时间大约是直接执行它的 5 倍Hello.exemono所以它不是wine运行它的。

我假设安装了一些mono内核模块,mono它可以拦截exec系统调用,或者捕获以 开头的二进制文件4D 5A,但是lsmod | grep mono并且朋友会返回错误。

这里发生了什么,内核如何知道这一点可执行文件很特殊吗?


只是为了证明它不是我的shell工作魔法,我用过废壳(又名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暂时禁用...

相关内容