Estou aprendendo c #, então fiz um pequeno programa em c # que diz Hello, World!
, compilei mono-csc
e executei com mono
:
$ mono-csc Hello.cs
$ mono Hello.exe
Hello, World!
Notei que quando eu bati TAB
em bash
, Hello.exe
foi marcado executável. Na verdade, ele roda apenas por um shell que carrega o nome do arquivo!
Hello.exe
não é um arquivo ELF com uma extensão de arquivo engraçada:
$ 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
significa que é um executável estaticamente vinculado do Microsoft Windows. Solte-o em uma caixa do Windows e ele (deve) ser executado.
Tenho wine
instalado, mas wine
, sendo uma camada de compatibilidade para aplicativos Windows, leva cerca de 5x mais tempo para executar Hello.exe
como mono
e executá-lo diretamente que, portanto, não é wine
que vai.
Eu estou assumindo que há algum mono
módulo do kernel instalado com mono
que intercepta o exec
syscall / s ou captura binários que começam com 4D 5A
, mas os lsmod | grep mono
amigos retornam um erro.
O que está acontecendo aqui e como o kernel sabe que esse executável é especial?
Só para provar que não é a minha mágica de trabalho do shell, usei o Crap Shell (aka sh
) para executá-lo e ele ainda é executado de forma nativa.
Aqui está o programa na íntegra, uma vez que um comentarista estava curioso:
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");
}
}
program codefile
, no seu caso o programa é mono, enquanto meus exemplos incluem php, python, perl e java. Eu suspeito que se mono permitir extensão para outro arquivo que não seja .exe ainda executado via código. Não deve depender absolutamente do Windows, pois, finalmente, este é um código compilado. No entanto, se o seu arquivo de origem tiver algum código dependente, como APIs apenas do Windows, obviamente você precisará do wine para executar esse arquivo exe.
/etc/magic
ou /usr/share/file/magic
(ou local mágico semelhante) é o arquivo que contém as informações necessárias para poder fazer isso.
$ foo.jar
pouco do que $ java -jar foo.jar
- semelhante ao que é feito para mono.
php hello.php
oupython hello.py
ouperl hello.pl
ou no caso de linguagem compilada como java,java hello
eles também serão executados, pois não são executáveis lá, mas um programa lê e executa o arquivo. No entanto, se você executar./hello.exe
em vezmono hello.exe
do que eu encontrei sua pergunta e resposta aceita mais razoável (que no caso definitivamente usar binfmt-apoio.