您尚未登录。

#1 2019-09-26 14:07:53

Mr.I
路人丙
所在地: Kerbal
注册时间: 2015-08-29
帖子: 175

[已解决] 终端中运行由 mingw 交叉编译出来的 Windows/DOS PE 格式的 .exe 文件时,系统会自动调用 wine?

我今天无意中发现了这件事情,刚写了个 C 语言的 hello world,用 mingw 交叉编译了一下。

代码如下:

/*
 * 一个 C 语言的 hello world 程序:a.c
 * 我用 mingw 编译了 a.c 并获得了下面的 a.exe:
 *     x86_64-w64-mingw32-gcc a.c
 */

#include <stdio.h>
#include <unistd.h>


int main(void)
{
    printf("-- it starts --\n");
    sleep(10);
    printf("-- it ends --\n");

    return 0;
}

然后,调试的时候,我本来是想执行:

wine ./a.exe

然后失手打成了:

./a.exe

这个。。。居然成功运行了。。。 hmm

然后,我用 hexdump 检查了一下这个 a.exe,确认了这个确实不是 ELF 格式的,而是 Windows 的 PE 格式的 binary:

# hexdump -C a.exe | less 得到的文件头部内容:

00000000  4d 5a 90 00 03 00 00 00  04 00 00 00 ff ff 00 00  |MZ..............|
00000010  b8 00 00 00 00 00 00 00  40 00 00 00 00 00 00 00  |........@.......|
00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 80 00 00 00  |................|
00000040  0e 1f ba 0e 00 b4 09 cd  21 b8 01 4c cd 21 54 68  |........!..L.!Th|
00000050  69 73 20 70 72 6f 67 72  61 6d 20 63 61 6e 6e 6f  |is program canno|
00000060  74 20 62 65 20 72 75 6e  20 69 6e 20 44 4f 53 20  |t be run in DOS |
00000070  6d 6f 64 65 2e 0d 0d 0a  24 00 00 00 00 00 00 00  |mode....$.......|
00000080  50 45 00 00 64 86 11 00  f5 4e 8c 5d 00 7a 05 00  |PE..d....N.].z..|
00000090  0a 06 00 00 f0 00 27 00  0b 02 02 20 00 1e 00 00  |......'.... ....|
000000a0  00 3c 00 00 00 0a 00 00  f0 14 00 00 00 10 00 00  |.<..............|
000000b0  00 00 40 00 00 00 00 00  00 10 00 00 00 02 00 00  |..@.............|
000000c0  04 00 00 00 00 00 00 00  05 00 02 00 00 00 00 00  |................|
000000d0  00 20 06 00 00 06 00 00  f7 bf 06 00 03 00 00 00  |. ..............|
000000e0  00 00 20 00 00 00 00 00  00 10 00 00 00 00 00 00  |.. .............|
000000f0  00 00 10 00 00 00 00 00  00 10 00 00 00 00 00 00  |................|
00000100  00 00 00 00 10 00 00 00  00 00 00 00 00 00 00 00  |................|
00000110  00 80 00 00 6c 07 00 00  00 00 00 00 00 00 00 00  |....l...........|
00000120  00 50 00 00 7c 02 00 00  00 00 00 00 00 00 00 00  |.P..|...........|
00000130  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

后来,我在 sleep(10) 的过程中按下了 ctrl + C,然后这个东西 print 了一行看起来是由 wine 输出的日志:

$ ./a.exe 
-- it starts --
^C002f:fixme:console:CONSOLE_DefaultHandler Terminating process 2d on event 0

然后,我就想:会不会是 zsh 发现这个是个 Windows 的 binary,所以就自动帮我调用了 wine。
于是,我换成 bash 和 sh 各试了一遍,结果一样,还是可以直接执行 ./a.exe,并且仍然可以在 sleep(10) 的过程中用 ctrl + C 中断并使其输出这条 wine 的日志。

那么,看起来并不是 shell 的关系(这里我假设了功能上比较原始的 sh 不会在这种事情上动手脚,我并不是很确定)。

那么,这是怎么回事呢?为什么我的系统会自动调用 wine 来执行 Windows PE 格式的文件呢?
如果说,shell 没有在这件事情上动手脚的话,那么,是谁调出来了 wine 呢?而且内核和 ld 不是应该只认 ELF 格式的 binary 吗 hmm

最近编辑记录 Mr.I (2019-09-26 14:53:34)


运维工程师,业余程序员,偶尔写写代码,对 ArchLinux 和 Gnome3 一见钟情 wink

离线

#2 2019-09-26 14:25:29

farseerfc
会员
注册时间: 2013-07-30
帖子: 202
个人网站

Re: [已解决] 终端中运行由 mingw 交叉编译出来的 Windows/DOS PE 格式的 .exe 文件时,系统会自动调用 wine?

是 wine 註冊了內核的 binfmt_misc 作爲 PE 文件的解釋器。

$ cat /proc/sys/fs/binfmt_misc/DOSWin
enabled
interpreter /usr/bin/wine
flags:
offset 0
magic 4d5a

wine 包提供了 /usr/lib/binfmt.d/wine.conf 這個文件, systemd 在啓動的時候 systemd-binfmt.service 服務會讀取其中的文件註冊 binfmt_misc。

參考 https://en.wikipedia.org/wiki/Binfmt_misc


computerは神様だと信じていて
だからVIMの上でずっと指が舞って
自ら恋愛相手を作り出して

离线

#3 2019-09-26 14:53:05

Mr.I
路人丙
所在地: Kerbal
注册时间: 2015-08-29
帖子: 175

Re: [已解决] 终端中运行由 mingw 交叉编译出来的 Windows/DOS PE 格式的 .exe 文件时,系统会自动调用 wine?

farseerfc 说:

是 wine 註冊了內核的 binfmt_misc 作爲 PE 文件的解釋器。

$ cat /proc/sys/fs/binfmt_misc/DOSWin
enabled
interpreter /usr/bin/wine
flags:
offset 0
magic 4d5a

wine 包提供了 /usr/lib/binfmt.d/wine.conf 這個文件, systemd 在啓動的時候 systemd-binfmt.service 服務會讀取其中的文件註冊 binfmt_misc。

參考 https://en.wikipedia.org/wiki/Binfmt_misc

好棒的回答,非常感谢!

我感觉我打开了新世界的大门了 big_smile


运维工程师,业余程序员,偶尔写写代码,对 ArchLinux 和 Gnome3 一见钟情 wink

离线

#4 2019-09-26 18:16:30

xtricman
エクス·トリクマン
注册时间: 2012-12-26
帖子: 783

Re: [已解决] 终端中运行由 mingw 交叉编译出来的 Windows/DOS PE 格式的 .exe 文件时,系统会自动调用 wine?

已经是本论坛少有的正常画风的问答帖了。

离线

页脚