Sunday, April 03, 2016

Some notes on Ubuntu Bash on Windows 10

So the latest news is that you can run Ubuntu and bash on Windows 10. In other words, from the bash command-line, you execute apt-get to get/run any Ubuntu binary -- the same binary that runs on Linux. How do it work?

I don't know yet, but browsing around on the Internet suggests that it's a kernel driver in Windows that emulates Linux system calls.

Remember, the operating system is two parts: the kernel and user-space. The interaction between them is ~300 system-calls. Most of these are pretty straight-forward, such as opening a file, reading from the file, and closing the file.

To make a system call, you put the integer number in eax/rax register, fill in the other registers as needed, then calling the SYSENTER instruction.

Each process maintains a table of what the system calls do. In fact, a hacker/debugging/reversing technique is to edit that table in order to hook system calls, do some hackery things, then call the original system call.

That means Microsoft can write a driver, that runs in the kernel, that replaces the system calls for a process, from Windows ones to Linux ones. This driver then needs to emulate the Linux functionality. So, any code running in the bash process will think it's Linux.

For example, when the programmer calls "open()" to open a file, then Linux layer gets this, changes the filename to match what Windows wants, like "/mnt/c/blah" to "C:/blah", then hands things off to the Windows API to open the file.

There's probably fewer than 100 system calls that you need to emulate for this to work, with everything else returning an error code. You don't need to emulate all the functionality of these things, such the 90% that everything expects.

This is something that actually an individual could probably get working. It's all straightforward code, so it doesn't require anything complex.

My program masscan is included in Ubuntu. Will it run under Wind10-bash? The answer is "maybe".

Everything in masscan will work up to the point that it attempts to create a "raw socket". This is a feature not supported by Windows in user-mode, but which I'm pretty sure is supported by the Windows kernel. The question is whether the emulation code has emulated raw sockets.

If it has, then masscan under bash should work much faster than it currently does under Windows. That's because right now, I go through Winpcap, which is slow as snot. Any other way to transmit packets should be radically faster.

They say that one shouldn't expect to be able to run Linux network services, so it's possible that they don't support sockets at all. This is garbage -- if so it's an intentional omission rather than one of limited resources. There's good reasons why they can't support some features, such as epoll(), but all other basic socket functions have straightforward analogues.

By the way, the same approach can be used to support FreeBSD as well. Conversely, I don't think it'll work well going the other way, as a technique for emulating Windows. Microsoft puts a lot of formerly kernel functionality up in Windows DLLs in userspace, with a very complicated syscall interface. Unlike Linux, apps don't call system calls directly, but DLL APIs. Thus, WINE (Windows-on-Unix) works by supplying alternate DLLs rather than trying to emulate system calls.

Consequently, if this is the technique being used, then Microsoft is supporting Ubuntu on Windows (all the user-space stuff), but not supporting Linux (which technically refers to just the kernel).


pmb said...

"from", not "form"!!!! FFS

pmb said...

"from", not "form"!!!! FFS

felixphew said...

One thing that nearly everybody is missing is that FreeBSD does the exact same thing - it emulates Linux syscalls, and thus supports running Linux binaries. Outlined from a practical perspective here, more technical detail here.

Carlos said...

It's really clever idea, in essence MS revived the multiple subsystems that Windows NT always supported. Remember, way back when, Windows NT actually could run POSIX and OS/2 programs (CLI only), not just WIN32. Eventually those subsystems were discontinued, but apparently MS kept the subsystem architecture, so now, according to this video, they created a Linux subsystem for Windows.

It's usermode only, so things that need kernelmode probably won't work.

Joe Duarte said...

Robert, but, but, why??

Has bash source code been audited and/or refactored since shellshock? Why are people still using it?

Also, see this on the emulation angle: