모노는 어떻습니까? bash, Hello.exe실행 표시되었다. 실제로 파일

나는 C #을 배우고 있으므로라는 작은 C # 프로그램을 만든 Hello, World!다음 컴파일 mono-csc하고 실행했습니다 mono.

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

나는 명중 할 때 눈치 TABbash, 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윈도우 응용 프로그램에 대한 호환성 계층되고, 약 5 배 오래 실행하는 데 걸리는 Hello.exemono하고 직접 않습니다 실행, 그래서 그것은 아니에요 wine그게 실행합니다.

나는 syscall / s 를 가로 채 거나로 시작하는 바이너리를 잡는 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");
  }
}


답변

이것은 binfmt_misc 의 작동 방식입니다. 알 수없는 바이너리를 실행하는 방법을 커널에 알려줍니다. /proc/sys/fs/binfmt_misc; 의 내용을보십시오 여기에 보이는 파일들 중에서 Mono 바이너리를 실행하는 방법을 설명해야합니다.

enabled
interpreter /usr/lib/binfmt-support/run-detectors
flags:
offset 0
magic 4d5a

(데비안 시스템에서). 이것은 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일시적 으로 비활성화해야합니다 .