mono-runtime 中的 binfmt-detector-cli 无法识别 x64 可执行文件?

mono-runtime 中的 binfmt-detector-cli 无法识别 x64 可执行文件?

在 64 位 Ubuntu 14.04.2 LTS 上,我显然可以运行“x86”exe 文件,但不能运行“x64”exe 文件。

如果我使用 monodevelop 来构建项目的 x86 配置,结果是x86/test.exe,我可以使用运行它./x86/test.exe,但如果我构建 x64 配置,结果是./x86/test.exe,我无法使用运行它./x64/test.exe- 我收到错误:

run-detectors: unable to find an interpreter for ./x64/test.exe

如果我在命令前加上mono( ,我就能很好地运行这两个命令,mono ./x64/test.exe而且/usr/bin/cli ./x64/test.exe这两个命令都可以正常工作。

我可以看到 mono 配置为运行这些类型的二进制文件:

$ update-binfmts --display   
...                                       
cli (enabled):                                                                                                                 
     package = mono-runtime                                                                                                    
        type = magic                                                                                                           
      offset = 0                                                                                                               
       magic = MZ                                                                                                              
        mask =                                                                                                                 
 interpreter = /usr/bin/cli                                                                                                    
    detector = /usr/lib/cli/binfmt-detector-cli

这两个文件似乎都以以下内容开头MZ

$ head ./x86/test.exe
MZ\220^@^C^@^@^@^D^@^@^@\377\377^@^@\270^@...

$ head ./x64/test.exe                  
MZ\220^@^C^@^@^@^D^@^@^@\377\377^@^@\270^@...

但是 binfmt-detector-cli 无法检测到其中一个:

$ /usr/lib/cli/binfmt-detector-cli ./x86/test.exe; echo $?                                                                                                               
0                                                           

$ /usr/lib/cli/binfmt-detector-cli ./x64/test.exe; echo $?                                                                                                               
1                                  

有关 exe 文件的更多信息:

$ file ./x86/test.exe                    
./x86/test.exe: PE32 executable (console) Intel 80386 Mono/.Net assembly, for MS Windows            

$ file ./x64/test.exe                
./x64/bin/ShapeSearch.exe: PE32+ executable (console) x86-64 Mono/.Net assembly, for MS Windows    

不幸的是,我不太明白我在说什么。我开始这项调查时读了从混乱的 binfmts 配置中恢复,但这有点超出我的理解范围。

答案1

早在 2015 年,它就binfmt-detector-cli无法接受“PE32+”(即 x64)可执行文件,因此它们都被隐式地过滤为“非 CLR 二进制文件”。这个问题在 2022 年初被“修复”,https://github.com/mono/linux-packaging-mono/pull/35但是,更改的结果是大多数 PE32+ 文件(无论是否为 CLR)现在都被标记为“CLR 二进制文件”(有点像反转错误)。

我有一个建议修复探测器https://github.com/mono/linux-packaging-mono/pull/38。我相信这个变化理解了 PE32 和 PE32+ 之间的差异。基本上,“CLR 运行时数据目录”条目在两种格式中位于不同的位置。

注意:这里有三个级别的“二进制”。MS-DOS 可执行文件带有在内核中注册的“MZ”文件魔术头。嵌入其中的是一套“PE”头。对于与 CLR 相关的格式,有 32 位和 64 位(ish)变体,称为“PE32”和“PE32+”。最后有一个头(有时称为“CLR 运行时数据目录条目”),它表明可执行内容是 CLR 管理的运行时二进制数据还是本机二进制数据。

相关内容