2

On 64-bit Ubuntu 14.04.2 LTS, I can apparently run "x86" exe files, but not "x64" ones.

If I use monodevelop to build the x86 configuration of a project, resulting in x86/test.exe, I can run it with ./x86/test.exe, but if I instead build the x64 configuration resulting in ./x86/test.exe, I cannot run it with ./x64/test.exe - I get an error:

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

I can run both fine if I prefix the command with mono (mono ./x64/test.exe and /usr/bin/cli ./x64/test.exe both work fine).

I can see that mono is configured to run these kinds of binaries:

$ 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

Both of the files appear to begin with MZ:

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

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

But binfmt-detector-cli fails to detect one of them:

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

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

More information about the exe files:

$ 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    

I don't really understand what I'm talking about, unfortunately. I started this investigation by reading Recovering from messed up binfmts configuration, but it's a little bit over my head.

Someone
  • 21
  • 2

1 Answers1

0

Back in 2015 the binfmt-detector-cli failed to accept the "PE32+" (i.e, x64) executable, so implicitly they were all filtered as "not CLR binary". That was "fixed" in early 2022 with https://github.com/mono/linux-packaging-mono/pull/35. However, the result of the change is that most PE32+ files (CLR or not) were now tagged as "CLR binary" (sort of inverting the bug).

I have a proposal to fix the detector in https://github.com/mono/linux-packaging-mono/pull/38. I believe this change understands the differences between PE32 and PE32+. Basically the "CLR Runtime Data Directory" entry is in a different location in the two formats.

NOTE: There are three levels of "binary" here. The MS-DOS executable with the "MZ" file magic header registered with the kernel. Embedded in that is a suite of "PE" headers. For the CLR-relevant formats, there are 32-bit and 64-bit (ish) variations of called "PE32" and "PE32+". Finally there is a header (sometimes called the "CLR Runtime Data Directory entry") that says if the executable content are CLR-managed-runtime binary data or native binary data.

P.T.
  • 111
  • 2