나는 C #을 배우고 있으므로라는 작은 C # 프로그램을 만든 Hello, World!
다음 컴파일 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
이는 Microsoft Windows 정적으로 링크 된 실행 파일임을 의미합니다. Windows 상자에 놓으면 실행해야합니다.
내가 한 wine
설치하지만, wine
윈도우 응용 프로그램에 대한 호환성 계층되고, 약 5 배 오래 실행하는 데 걸리는 Hello.exe
로 mono
하고 직접 않습니다 실행, 그래서 그것은 아니에요 wine
그게 실행합니다.
나는 syscall / s 를 가로 채 거나로 시작하는 바이너리를 잡는 mono
커널 모듈이 설치되어 있다고 가정 하고 있지만 친구는 오류를 반환합니다.mono
exec
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
; 의 내용을보십시오 여기에 보이는 파일들 중에서 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
일시적 으로 비활성화해야합니다 .