모노의 놀라운 점은 무엇인가요?

모노의 놀라운 점은 무엇인가요?

저는 C#을 배우고 있으므로 C# 프로그램을 만든 Hello, World!다음 이를 컴파일 mono-csc하고 다음과 같이 실행했습니다 mono.

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

나는 그것을 클릭했을 때 실행 가능으로 표시 TAB되어 있음 을 알았습니다 . 실제로 파일 이름을 로드하는 셸을 통해서만 실행됩니다!bashHello.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설치해 봤는데, Windows wine응용 프로그램에 대한 호환성 레이어로 직접 실행하는 것보다 실행 시간이 5배 정도 길어서 Hello.exe실행 하는 방법 mono은 아닙니다 .wine

시스템 호출을 가로채 거나 로 시작하는 바이너리를 캡처하는 일부 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");
  }
}

답변1

이것은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...

관련 정보