How to launch Windows binaries on Linux directly

1934

Author: Manolis Tzanidakis

Although I rarely run Windows these days, it seems I can’t break the habit of using one or two Windows applications instead of their open source equivalents. However, instead of having a full-blown Windows desktop, I prefer to run these programs on my GNU/Linux system with Wine. The problem is that I’m tired of having to enter cd ~/.wine/drive_c/Program FilesMy Windows App; wine My Windows App.exe every time I want to launch one of these programs. Having shell scripts for each program is not a great solution either. Wouldn’t it be better to simply run My Windows App.exe directly on an XTerm? Fortunately the Linux kernel already lets you do that with a feature called binfmt_misc.

If you run your distribution’s stock kernel, chances are this feature is already available. If it’s not, or you prefer to build your own kernels, make sure to select CONFIG_BINFMT_MISC (Executable file formats -> Kernel support for MISC binaries) either built-in or as a module. In the latter case, make sure that the binfmt_misc module is auto-loaded during boot (on Debian and its derivatives run echo binfmt_misc >> /etc/modules). Mount bifmt_misc with the command mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc, or copy the following line to your /etc/fstab to have it mounted automatically on each boot:

none /proc/sys/fs/binfmt_misc binfmt_misc defaults 0 0

Now, you must tell binfmt_misc to invoke /usr/bin/wine (use the full path of the Wine binary on your system, or it won’t work) to deal with Win16 and Win32 binaries:

echo ':DOSWin:M::MZ::/usr/bin/wine:' > /proc/sys/fs/binfmt_misc/register

To make this setting permanent, if you use Gentoo, copy the previous command to your /etc/rc.d/rc.local or /etc/conf.d/local.start file. If you use a Debian-based distro, copy the following as /etc/init.d/wine:

#!/bin/sh
test -e proc/sys/fs/binfmt_misc/register || exit 0
case "$1" in
  start)
    echo ':DOSWin:M::MZ::/usr/bin/wine:' > /proc/sys/fs/binfmt_misc/register
    ;;
  stop)
    echo 0 > /proc/sys/fs/binfmt_misc/status
    ;;
  *)
    echo "Usage: $0 {start|stop}" >&2
    exit 3
    ;;
esac

Make it executable (chmod 755 /etc/init.d/wine) and have it started during boot (update-rc.d wine start 99 2 3 4 5 . stop 10 0 1 6 .).

The last step is to make your Windows application’s binary file executable with chmod 755 ./My Windows App.exe and run it as if it were a native Linux program: ./My Windows App.exe. For making things even easier, you can symlink it to a directory in your PATH, such as /usr/local/bin, and even remove the .exe extension.

binfmt_misc can be used to launch Java or Python programs in the same fashion. For more information read Documentation/binmft_misc.txt on any recent Linux kernel tarball.

This technique might have some security implications — like fostering local privilege escalation — so make sure to use it on an updated system with trusted users. Even better, mount your /proc file system as nosuid.

Category:

  • Linux