Getting Started with Binary Formats
When I first started writing C# programs which I wanted to deploy, I stumbled upon a concept that I never had to think about before. That of binary formats.
1 What's What
It was much to my delight and surprise that I started reading about the binfmt_misc
module in the Linux kernel which lets you register interpreters based on a magic number. It goes beyond writing the #!
line as the first one of your script in that this approach works for binary files too. Of course, I do feel a tad uncomfortable about talking about interpreters when it comes to binary files. Here, I'm on about interpreters in their broadest sense, including virtual machines and emulators.
The update-binfmts
command lets you specify how to execute programs according to their binary formats. Thanks to that kernel module, you can sort of directly execute a program from the command line without having to explicitly call a specific virtual machine or interpreter.
2 Usage
2.1 Format File
It's possible to register a format with the update-binfmts
command but it's perhaps easier to write a format file directly in /usr/share/binfmts
. I'm doing so here for a C# program:
package usr_local_bin_mono
interpreter /usr/local/bin/mono
magic MZ
These three lines are the bare minimum:
- The DEB package name. Of course, this may sound a bit out of place when it comes to an interpreter which doesn't come from a package to begin with but which was, for instance, manually installed in a custom location. No matter, though, you can get away with any sort of string that will make sense to you.
- The path to the interpreter.
- The magic number of the executable. Now, clearly, the whole trick is to work out what that could be. Let's just say it's beyond the scope of this post and hope to get away with it. The
mono-common
package taught me every C# executable begins with the lettersMZ
, for instance.
2.2 Importing or Updating a Format
After writing the format file, you need to import the format:
update-binfmts --import cli
You can do the same to update a format after having modified the format file.
2.3 Removing a Format
You can remove an imported format. For this, you need to specify the package name and the interpreter path in addition to the format name:
update-binfmts --package usr_local_bin_mono --remove cli /usr/local/bin/mono
3 Examples
If you install the mono-common
package, you can take a look at what their /usr/share/binfmts/cli
does.