support Windows Subsystem for Linux
Windows 10 Anniversary Edition introduced the new Windows Subsystem for Linux (WSL), where a process can run under a subsystem that supports 64-bit Linux ELF binaries and system calls.
Information on WSL:
https://blogs.msdn.microsoft.com/wsl/2016/06/08/wsl-system-calls/
- Syscall interface is completely in the kernel
- Only supports ELF64 -- no 32-bit support.
- Uses "pico processes" which have no PEB or TEB
Looks like there is at least some procfs support: https://blogs.msdn.microsoft.com/wsl/2016/06/15/wsl-file-system-support/
https://blogs.msdn.microsoft.com/wsl/2016/05/23/pico-process-overview/ Added: better fork support, 4KB-boundary mem mgmt, case-sensitive file names
To install: it's under "Turn Windows features on or off" and you then launch Bash.
Initial tests: DR crashes due to TLS problems (this one is trying late injection -- early or late makes no difference):
Program received signal SIGSEGV, Segmentation fault.
get_tls_thread_id () at /dynamorio_package/core/unix/os.c:2292
2292 /dynamorio_package/core/unix/os.c: No such file or directory.
(gdb) bt
#0 get_tls_thread_id () at /dynamorio_package/core/unix/os.c:2292
#1 0x00000000712d414f in get_thread_id () at /dynamorio_package/core/unix/os.c:2279
#2 0x000000007111974f in deadlock_avoidance_lock (lock=0x713d6180 <options_lock>, acquired=true, ownable=true)
at /dynamorio_package/core/utils.c:574
#3 0x000000007111a1be in mutex_lock (lock=0x713d6180 <options_lock>) at /dynamorio_package/core/utils.c:885
#4 0x000000007111aa6e in write_lock (rw=0x713d6180 <options_lock>) at /dynamorio_package/core/utils.c:1217
#5 0x0000000071081130 in options_init () at /dynamorio_package/core/options.c:2002
#6 0x000000007109067d in dynamorio_app_init () at /dynamorio_package/core/dynamo.c:412
#7 0x00007f18a773082b in _init (argc=1, argv=0x7ffffec044f8, envp=0x7ffffec04508)
at /dynamorio_package/core/unix/preload.c:175
(gdb) x/10i $pc
=> 0x712d417f <get_tls_thread_id+27>: mov %gs:0x70,%rax
0x712d4188 <get_tls_thread_id+36>: mov %rax,-0x8(%rbp)
0x712d418c <get_tls_thread_id+40>: mov -0x8(%rbp),%rax
0x712d4190 <get_tls_thread_id+44>: leaveq
0x712d4191 <get_tls_thread_id+45>: retq
read_thread_register** returns non-zero:
(gdb) stepi
123 in /dynamorio_package/core/unix/tls.h
1: x/i $pc
=> 0x712d0968 <read_thread_register+35>: mov %gs,%eax
(gdb) stepi
0x00000000712d096a 123 in /dynamorio_package/core/unix/tls.h
1: x/i $pc
=> 0x712d096a <read_thread_register+37>: mov %eax,-0x4(%rbp)
(gdb) p /x $eax
$1 = 0x2b
(gdb) p /x $gs
$2 = 0x0
(gdb) info reg
rax 0x2b 43
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
gdb think it's 0 yet when I read it I get 0x2b.
os_tls_init for thread 6437
tls_get_fs_gs_segment_base selector 53 index 10 ldt 0
arch_prctl fs => 0x00007fffd14922a8
tls_get_fs_gs_segment_base selector 2b index 5 ldt 0
arch_prctl gs => 0x00007fffd14922a8
privload_tls_init: app TLS segment base is 0x00007fffd14922a8
privload_tls_init: allocated 8192 at 0x000000004eb3d000
privload_tls_init: adjust thread pointer to 0x000000004eb3e700
thread 6437 app lib tls base: 0x00007fffd14922a8, alt tls base: 0x00007fffd14922a8
thread 6437 priv lib tls base: 0x000000004eb3e700, alt tls base: 0x000000004eb39000, DR's tls base: 0x000000004eb39000
os_tls_init: cur gs base is 0x00007fffd1492370
os_tls_init: arch_prctl successful for base 0x000000004eb39000
SYSLOG_ERROR: Application /bin/ls (6437). Internal Error: DynamoRIO debug check failure: /work/dr/git/src/core/unix/os.
c:1804 is_thread_tls_initialized()
It looks like the ARCH_SET_GS returns 0 for success but does not actually do anything, as a subsequent ARCH_GET_GS gets the same value as before the set.
Same with FS:
arch_prctl get fs => 0x00007fffe9cc8570 res=0x0000000000000000
arch_prctl set fs 0x000000004d091000 => res=0x0000000000000000
arch_prctl get fs => 0x00007fffe9cc8570 res=0x0000000000000000
But how does native work then? "strace ls" shows:
arch_prctl(ARCH_SET_FS, 0x7f995ac00840) = 0