¿Cómo cargó Linux este exe compilado con C#?

¿Cómo cargó Linux este exe compilado con C#?

Acabo de descubrir algo realmente sorprendente.

Puedo compilar un simple C# hola mundo en mi computadora con Windows usando csc(desde Visual Studio), copiar el exearchivo resultante a mi computadora con Linux y ejecutarlo con mono helloworld.exe. Hasta ahora todo tiene sentido para mí: segúnesta publicación SO, en Windows, helloworld.exees básicamente solo un truco que termina iniciando el tiempo de ejecución de C#, y el código de bytes CIL simplemente se lee de alguna sección de datos más adelante en el exearchivo. Del mismo modo, me imagino que, en Linux, mono helloworld.exesimplemente inicia el tiempo de ejecución de C# y lee directamente el código de bytes sin molestarse con el truco del exe.

Para la posteridad, aquí está la fuente, que obtuve deExcelente libro gratuito sobre C# de Charles Petzold:

//---------------------------------------------
// FirstProgram.cs (c) 2006 by Charles Petzold
//---------------------------------------------
class FirstProgram
{
    public static void Main()
    {
        System.Console.WriteLine("Hello, Microsoft .NET Framework!");
    }
}

Pero aquí es donde las cosas se ponen interesantes: en Linux ( uname -ren mi máquina da 4.14.188-1-MANJARO), simplemente puedo hacerlo ./helloworld.exey ¡funciona!

Empecé a investigar un poco y aquí están las primeras líneas de la ejecución strace ./helloworld.exe:

execve("./hw.exe", ["./hw.exe"], 0x7fffae8e6070 /* 61 vars */) = 0
[ Process PID=3381 runs in 32 bit mode. ]
brk(NULL)                               = 0x7eedb000
arch_prctl(0x3001 /* ARCH_??? */, 0xffb19948) = -1 EINVAL (Invalid argument)
readlink("/proc/self/exe", "/usr/bin/wine", 4096) = 13
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xf7faa000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/bin/../lib32/tls/i686/sse2/libwine.so.1", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/usr/bin/../lib32/tls/i686/sse2", 0xffb18e00) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/bin/../lib32/tls/i686/libwine.so.1", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/usr/bin/../lib32/tls/i686", 0xffb18e00) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/bin/../lib32/tls/sse2/libwine.so.1", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/usr/bin/../lib32/tls/sse2", 0xffb18e00) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/bin/../lib32/tls/libwine.so.1", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/usr/bin/../lib32/tls", 0xffb18e00) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/bin/../lib32/i686/sse2/libwine.so.1", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/usr/bin/../lib32/i686/sse2", 0xffb18e00) = -1 ENOENT (No such file or directory)

Habría esperado algún error que dijera "este archivo no es un ejecutable válido", ya que solo espero que el cargador de programas de Linux comprenda los archivos ELF en lugar del formato PE de Windows. En cambio, parece que de alguna manera el sistema es lo suficientemente inteligente como para comenzar a buscar Wine (en el straceresultado, puedes ver que comienza a buscar bibliotecas de Wine, y como instalé Wine en mi máquina Linux, finalmente las encuentra más tarde). en).

Entonces, ¿qué está pasando? ¿Es la execvellamada lo suficientemente inteligente como para intentar usar Wine si detecta un archivo PE, o es algo que bashestá haciendo? ¿O es algo completamente diferente?

Respuesta1

Definitivamente tiene Wine o Mono instalado a través de un administrador de paquetes y junto con él un archivo de configuración especial que le dice al kernel qué hacer una vez que el usuario inicia un archivo exe.

Más sobre esto aquí:https://en.wikipedia.org/wiki/Binfmt_misc

información relacionada