Why is Windows Subsystem for Linux able to run Windows *.exe programs?
How is WSL2 able to run Windows executables?
The Windows executable (PE binary) is added as a binfmt_misc entry in WSL2. In simple words, binfmt_misc is a Linux kernel feature which allows arbitrary executable file formats to be recognized and passed to certain programs.
In WSL2, the init
binary (from which every process is forked) register the
Windows PE binary as a executable and make it executable by itself (i.e. the init
).
Here is a output of the PE binfmt entry:
cat /proc/sys/fs/binfmt_misc/WSLInterop
enabled
interpreter /tools/init
flags: F
offset 0
magic 4d5a
WSLInterop
is just a name for the entry. The magic number 4d5a
is MZ
which
is first two bytes of Windows PE executable. Assume this is a fingerprint with
which init
(the interpreter) recognizes PE binary.
Users can disable the registry with this command:
echo 0 | sudo tee /proc/sys/fs/binfmt_misc/WSLInterop
Further readings:
- Windows Subsystem for Linux interoperability with Windows
- Wikipedia: binfmt_misc
- Kernel Support for miscellaneous (your favourite) Binary Formats v1.1
It will run any executable (Windows or linux) that is in your $PATH
environment variable. It searches the directories in order, so if you want to run the linux versions by preference, make sure those directories are before the windows directories in the path
bash is running as a pico process. When you try to run a program, the linux subsystem driver recognizes the request to run a process and calls ZwCreateUserProcess
in the windows kernel, creating the windows process.
It can call the function because all system calls made by pico processes are translated into NT calls in kernel mode, both via LXCORE.SYS
and the kernel, ntoskrnl.exe
.