原标题:一起聊聊WSL的那些事儿(上)

WSL是什么?

WSL 是由微软开发的一个提供了Linux大部分内核接口的程序容器,其使用的是GNU协议中包括的Linux内核代码,所以不存在版权的问题。在这个容器上可以安装很多Linux操作系统。比如Ubuntu, Opensuse等等。在WSL中可以运行bash shell 以及许多Linux下的指令,比如sed, awk这类应用,甚至可以通过X11转发,使用带有GUI的程序。

* Picture 1 WSL界面,基本上和Linux的操作界面一致

* Picture 2 使用xming转发后qemu

从1903版本开始,Windows支持使用P9 文件协议,从而能够在explorer.exe中直接访问安装的Linux操作系统中的文件系统。

* Picture 3 P9协议下访问WSL(图片来自网络)

虽然WSL目前的功能并不是特别的完善,不过有些场合下使用可以带来比较方便的效果,比如: · Web开发的场合,可以更加方便的部署

·可以方便的使用Linux下的各种tool

·比虚拟机启动速度快,某些场景下会很方便

虽然WSL的使用场景可能不怎么多,不过在这个上面也已经爆出过一些高危漏洞,像是CVE-2018-0743这种漏洞,只需要短短几行代码,就能从WSL影响到主机,导致BSOD。

* Picture 4引发漏洞的PoC

早期的Windows 10需要打开开发者选项才能够安装WSL,不过1703之后的版本都可以直接通过微软商店下载来开启这个功能(PS:目前只有64位支持)。

WSL中的权限是继承于当前的用户的,也就是说,如果当前用户为非管理员用户,那么即使在WSL中使用sodu或者切换成su用户,也无法获得管理员才有的权限。例如,有些网络工具可能会需要构造raw packet,但是在Windows下这个行为是需要管理员权限才能做到的,那么如果WSL中想要使用这个工具的话,那么就必须以管理员的身份运行WSL,才能够通过sudo调用这个软件。

* Picture 5 Microsoft Store里的WSl

进程

Linux和Windows下自然有许多不同的点,为了解决这些差异,WSL做了许多翻译工作。为了实现进程中的差异,WSL使用了一种叫做Pico Process的进程来进行中间翻译。

最小进程 Minimal Process

为了更好的理解Pico Process,首先要介绍Minimal Process这个相关的定义。在Windows 历史上,曾经出现过一个叫做Drawbridge的概念。最初这个系统是为了能够让应用程序能够运行在一个独立的环境中,并且让运行环境与主机的操作系统分离,并且均处于同一个用户模式的地址空间下(最初的目的似乎是为了让SQL Server能够直接运行在Linux环境下提出的一个概念)。

Minimal Process就是为了实现Drawbridge而提出的一种进程模型。这种特殊的进程是一个最小的进程,其不会使用CreateProcess这个API进行创建,而是使用NtCreateProcessEx这个内核函数来对进程进行创建。创建之后会通知操作系统不要对这部分的地址空间进行操作,并且交给它控制权,但是其本身缺少很多普通进程中拥有的东西。比如说没有一般进程中的PEB,用户共享的数据块未被映射到进程中,也不会有ntdll映射在其中,是一个完全空白的进程。并且在这之中创建的线程不会创建TEB。虽然没有进程PEB,但是抽象出来的进程/线程也会有一个类似的PEB/TEB来管理这个进程/线程。

* Picture 6各种进程比较(图片来自网络)

自从2013年之后,win10便开始使用这类进程了。一个叫做Memory Compression,另一个叫做Virtualization based Security(VBS),这两个进程其实就是Minimal Process 。如果用类似procexp之类的工具去观察的话,会发现其中基本上所有的线程都是由内核直接启动的。虽然没有进程PEB,但是抽象出来的进程/线程也会有一个类似的PEB/TEB来管理这个进程/线程。

* Picture 7 Memory Compression

微进程 Pico Process

Pico Process就是一个和Minimal Process类似的进程。如同Picture 6中画的那样,它和Minimal Process一样,缺少很多普通进程有的基本元素,例如PEB,ntdll等,相当于 Pico Process也是一个内核进程。每一个Pico Process都会与一个叫做Pico Provider,一个存在内核态的内核对象关联。这个内核对象是实现Linux下的程序运行在Windows运行环境中的一个关键对象。同样的,在Pico Process中创建的线程叫做Pico Thread,不过在Pico Process中,普通的线程和Pico Thread都是可以共存的。

当Pico Process运行的时候,每一个Pico Thread 进行系统调用,异常处理,或者ETW(Error trace windows)进行追踪的时候,都会被重定向到这个Pico Provider上。并且所有对Pico Process的操作,包括各类文件请求,打开进程句柄,进程创建与消亡等等,也会去调用这个Pico Provider。

前文提到,Pico Process中是没有普通进程中的基本组件,所以其中也是没有句柄表,所以可以通过检测当前进程中的句柄数量来确认当前进程是否为Pico Process。

Pico Provider

前文提到,Pico Provider这个内核对象实现了Linux往Windows中系统中断调用等的翻译,为了实现操作系统层面的抽象,必须要直接进行系统级的中断解析,所以这个对象是由驱动实现的。不过这个Pico Provider是由两个不同的驱动组成的,一个叫做lxss,另一个叫做lxcore。

Lxss是作为服务入口存在的。其本身并没有实现相关功能,在DriverEntry中调用的是在lxcore中实现的LxInitialize函数。

* Picture 8 Lxss服务的注册表内容

在这个驱动中,完成了以下的工作:

· 初始化Pico Provider

· 初始化用于通信的IRP

· 注册了通信用的IOCTL

· 注册了一个叫做 Devicelxss 的设备

并且初始化后的Pico Provider会一直存在内存中。

而lxcore就是真正的核心功能。在这个功能中实现了对于Pico Process,Pico Thread,的相关函数接口,并且对于Linux的文件系统中的VFS部分,lxcore也实现了相关的抽象,完成了一个类似中间件的功能。同时,其还实现了一个叫做ADSS系列函数的接口,作为一个抽象的bus使用。

lxcore对于Linux下的特性,有一些是完全独立实现的(例如pipe),有一些则是直接封装Win NT驱动中的一些特性(例如对于线程调度的处理)。还有一些是混合处理的,比如说Linux下的文件系统到Windows文件系统的映射,Linux的虚拟文件系统(Virtual File System)是 Linux 内核中的一个软件层,用于给用户空间的程序提供文件系统接口;同时,它也磁盘文件系统提供了一个接口,允许不同的文件系统共存。这其中对部分设备的抽象,Windows可以直接进行封装,但是类似于/proc这样的目录,Windows则是重新实现了一个特殊的接口来处理。

* Picture 9 WSL中对文件系统的处理困难重重

虽然前面提到过,Pico Process相对于Windows内核来说,是一个内核进程,但是其本身其实是有用户态的地址空间的,在WSL的Linux这边看起来,其本身栈中基本的VSOD,栈空间,二进制文件的映射等等都会映射在里面。当Linux这边的程序执行的时候,其本身当进行内核调用的时候,就会传递给Pico Provider,然后Pico Provider就会将当前的请求分发出去,调用在lxcore中实现的对应的将请求翻译成Windows 的相关函数。

Lxcore会对Linux中的系统调用进行翻译,调用对应的Windows内核函数,完成对相关实现的抽象。通过修改注册表项【HKEY_LOCAL_MACHINESYSTEMControlSet001Serviceslxss】能够让lxcore打印此时Linux发送往Windows内核中的请求:

* Picture 10 Windbg中查看的,WSL中翻译的内核调用

WSL中为了翻译系统调用,其中一个主要的工作就是翻译ABI(application binary interface),也就是两者在调用约定上的差异。双方在序列化参数的时候,存放参数的寄存器有一些不同。举个简单的例子,Linux的64位下会将系统调用号存放在rax中,然后调用参数的存放顺序为rdi,rsi,rdx,rcx,r8,r9,之后的参数会存放到栈中,而Windows下的调用参数的存放顺序则为rcx,rdx,r8,r9,从第五个参数就会存放在栈上。所以在发生系统中断调用的时候,WSL会将参数重新放入位置上,再去调用Windows的相关调用。

Pico Provider中存放了很多的相关系统调用,在初始化阶段,会通过函数PsRegisterPicoProvider进行注册。有意思的一点是,这个注册是双向的:代表了Linux内核的lxcore中定义了很多对于lxcore中关于关于Pico Process和Pico Thread构建以及获取上下文的相关函数,而在代表了Windows内核的ntoskrl.exe中则定义了很多关于Pico Process和Pico Thread终止的相关函数,以及系统调用分发相关的函数。在这个注册函数中,会相互进行注册。

可能有的人会提出说,Pico Provider也挺不安全的,因为随便写一个程序调用或者hook这个PsRegisterPicoProvider就能够实现对Pico Provider的操控。微软也想到了,所以这个函数的调用其实是收到了严格的限制的。函数调用需要在所有的第三方驱动被加载之前被调用,相当于只有微软本身可以对其进行注册。并且 lxcore 也是被注册在Patch Guard中的,所以也受到驱动保护。只要驱动文件被修改,就有可能发生蓝屏。

WSL与Windows进程的通信

Pico Process相当于是和普通的进程隔离的一类进程,那么可能会想到一个问题:这个wsl本身是一个exe进程,但是它背后启动的很多程序都是Pico Process(例如,输入ls之后要打印文件内容),这些进程内容又是怎么输出来的呢?这就说明,在Pico Process和普通进程之间,存在一种通信手段,能够让数据进行通信。

这里就要提到一个叫做ADSS的概念,ADSS全称是Android Sub System,是最初微软为了能够让Android应用运行时,其数据能通过一种相当于PCI接口的形式(打个比方就是像是内Android系统像是内存条一样插在主板上)和Windows phone通信,从而让app能够运行在Windows phone上运行的一个计划。虽然最后Windows phone计划已经死亡了,但是这个系列留下来的接口就继续用在了WSL中,用来实现容器之间的通信。

* Picture 11 WSL的进程与Windows进程通信

在这种模型中,WSL是作为一个Client,而WinNT则是类似于Server。每当需要通信的时候,WSL就会向设备 /dev/lxss 进行读写或者使用IOCTL进行操作,此时在Pico Provider中注册的设备“Lxss”就会调用其中定义好的回调函数,对读写和IOCTL等不同的行为进行相应的操作。

* Picture 12 lxcore中,LXSS设备注册的回调函数

在Windows NT(普通进程对应的内核)中,注册了一个COM对象ILxssInstance,这个对象底层实现了一套与ADSS相关的接口。所以这边可以通过获取对应的COM对象,并且调用其中的RegisterAdssBusServer注册对于抽象Bus的监听。这样就能够实现一个类似CS的结构来实现Windows NT 和WSL的通信。

一些杂谈

1)通过Pico Process,WSL将增加一些Windows中没有的新特性

* 支持fork

* 粒度更小的内存管理(Windows一般来用户模式的地址空间是以一个64k大的chunk作为单位的。不过对于Pico-process来说,其可以支持4kb大小的,以page为对齐单位的管理

* 实现了对文件系统大小写敏感的特性(其实这个特性NTFS本身已经支持)

2)WSL中也是可以启动exe文件的,原因在于在启动进程的时候,Windows的底层中断KiSyscall64会检查当前启动的线程的种类,如果当前线程种类为普通线程的话,则会去初始化一个普通进程,于是也是可以启动一个exe

* Picture 13 进程初始化中的逻辑

后续内容,敬请期待~

参考网站:

http://www.alex-ionescu.com/publications/BlueHat/bluehat2016.pdf

https://devblogs.microsoft.com/commandline/announcing-wsl-2/

https://blogs.msdn.microsoft.com/wsl/

https://devblogs.microsoft.com/commandline/whats-new-for-wsl-in-windows-10-version-1903/

*以上部分图片来自网络返回搜狐,查看更多

责任编辑:

输入上下文句柄相关函数 linux,一起聊聊WSL的那些事儿(上)相关推荐

  1. wsl ubuntu拒绝访问_一起聊聊WSL的那些事儿(下)

    前文回顾:一起聊聊WSL的那些事儿(上) 文件系统 在WSL这个feature刚出来的时候,很多人都抢着装上了这个特性,包括笔者的同学们都争先恐后的体验这个特性,不过最后都成了黑子,因为大家发现Fil ...

  2. 【转】搞机:window10安装Linux子系统(WSL)及迁移到非系统盘

    转自:搞机:window10安装Linux子系统(WSL)及迁移到非系统盘_泛泛之素-CSDN博客_wsl移动到非系统盘 痛点: 在电脑上想要使用linux又想使用windows系统只能安装双系统,因 ...

  3. firefox启动很慢 linux_Win10安装和使用Linux子系统(WSL 2)完整指南

    Windows Linux子系统(WSL)是Windows 10 操作系统的子系统,开发人员.测试人员可以通过它们直接从Windows运行本机Linux应用程序.编写脚本和执行命令.在微软公司发布的W ...

  4. Windows10玩转Linux子系统(WSL)

    Windows10玩转Linux子系统(WSL) WSL简介 WSL 是 Windows Subsystem for Linux 的缩写,意思是 linux 版的 window 子系统. Linux ...

  5. 【Linux】在Windows 10环境下安装适用于 Linux 的子系统 (WSL安装指南)

    更多教程:https://docs.microsoft.com/zh-cn/windows/wsl/install-win10 安装适用于 Linux 的 Windows 子系统 (WSL) 时有两个 ...

  6. 在windows上执行Linux命令,wsl安装及应用

    最近因为学习涉及到一些linux命令,听说可以在Windows Powershell 上运行linux命令,今天来安装实现一下 流程参考Basic commands for WSL | Microso ...

  7. wsl2无法使用systemctl_Win 10 更新,Linux 内核的 WSL 2 开始上线

    微软今天发布了 Windows 10 build 18917 Insider 版本,其中最引人关注的是内核采用 Linux 重构的 WSL 2(Windows Subsystem for Linux) ...

  8. Win 10 更新,Linux 内核的 WSL 2 开始上线

    微软今天发布了 Windows 10 build 18917 Insider 版本,其中最引人关注的是内核采用 Linux 重构的 WSL 2(Windows Subsystem for Linux) ...

  9. Linux输入事件类型EV_SW,Linux的input输入子系统:总体框架

    一.input输入子系统总体框架 Linux输入子系统将输入驱动抽象为三层:设备驱动层.核心层.事件处理层. 设备驱动层:将底层的硬件输入事件转化为统一事件形式,向输入核心(Input Core)汇报 ...

  10. linux系统某些应用无法输入,ubuntu 16.04下搜狗输入法不能输入中文解决(linux下常见软件崩溃问题解决方案)...

    之前一段时间正常使用的搜狗输入法突然无法输出中文(具体现象是,可以呼出搜狗输入法界面,但是候选词列表无显示),解决之后记录下来,希望能为同样遇到这个问题的人提供参考 我的系统是 ubuntu 16.0 ...

最新文章

  1. FILE文件流的中fopen、fread、fseek、fclose的使用
  2. 【Socket】linux网络多路复用IO技术
  3. 【树莓派】最常用的树莓派 Linux 命令及说明
  4. Python中的正则表达式(re)
  5. binlog 分析及回滚神器Analysisbinlog
  6. OCI 完成 TOB 选举,阿里工程师入选全球 9 人名单
  7. mysql 定义游标_mysql 游标的使用
  8. hibernate插件下载
  9. Auto病毒,落雪病毒,威金病毒,U盘病毒,魔波病毒,arp病毒,QQ病毒,熊猫烧香病毒,rose病毒清除方法
  10. 对比性句子sentiment analysis
  11. Kafka学习笔记: Kafka 百惑梳理
  12. 2020泰迪杯C题解题流程
  13. Tencent后台开发Java岗二面:Java中高级核心知识全面解析
  14. 学计算机进富士康,大学生进富士康上班工资多高,有发展前景吗?看看前辈们怎么说...
  15. linux下TCGA数据下载,TCGA数据下载方式小结
  16. 2022T电梯修理考试试题及在线模拟考试
  17. win10局域网共享文件夹
  18. UTL_FILE 包使用介绍
  19. 从“小米电源的售后维修”谈谈售后服务体系
  20. 任务6:认知ATmega168PA最小工作系统

热门文章

  1. 高校三维地图校内导航系统解决方案
  2. 团队管理经典书籍推荐:《团队管理必读12篇》
  3. 【0226】信息安全与密码技术
  4. 读书百客:《游终南山》赏析
  5. FAT文件系统规范v1.03学习笔记---1.保留区之启动扇区与BPB
  6. html+盒子+边距,盒子模型、边框、边距
  7. 什么是天线阵列及天线阵列类型
  8. 灰灰深入浅出讲解支持向量机(SVM)
  9. 程序员容易发福的原因及解决办法
  10. 获取路由器内的ADSL上网账号和密码或者获取电脑内的ADSL上网账号和密码教程 by 星空武哥