深入理解windows

时间:2023-03-09 09:57:07
深入理解windows

阿猫翻译的,用作备忘

深入理解windows——session、window stations、desktops

翻译自:http://www.brianbondy.com/blog/id/100/

本文将回答一些关于windows内部工作的简单问题。本文预期读者为有技术背景的人,同时部分内容对有一定windows编程经验的人来说特别有帮助。

如果你没有完全理解如下问题,你应该阅读本文:

  • 当你锁定计算机的时候会发生什么?对于所有正在运行的程序而言?对于任务栏而言?
  • UAC有啥特别的?他们如何锁定并且将整个屏幕变暗?他能真正的保护我吗?
  • 为毛键盘记录器无法记录一台锁屏计算机的密码
  • 屏幕保护有啥好后特别的?它怎么工作?
  • 多用户为毛可以同时登陆
  • 终端服务和远程桌面如何运作?
  • 一些远程控制软件为什么很糟糕?
  • 那个谜一样的,服务属性页中的"允许服务与桌面交互" 是什么?
  • 为毛vista那么渣而win7变好了?

要理解上面提到的全部问题,你需要理解如下概念: Sessions, Window Stations, 和Desktops.

一些解释可能难于理解,但值得学习他来了解windows是如何工作的

Sessions简介:

你机器上的所有程序,当运行时,都被叫做一个进程。进程指的是正在执行的程序副本。每个进程都包括代码页、一堆执行的线程,以及相关资源。

每个进程都唯一的属于他的启动用户,同时也属于一个叫做Session的东西。每个Session包括一堆进程,这些进程开启的窗体,Window Stations, Desktops,以及其他资源。其中Window Stations, Desktops将在本文中被介绍。

你可以在任务管理器中看到机器运行的所有进程。打开任务管理器,切换到进程选项卡,你可以看到进程以及他启动着的对应关系,也能改改看到进程对应的Session。Windows默认不显示session,但你可以在查看菜单中选择列为session id的列

任何进程都有且只有一个session。每个session都有有一个session id对应。启动后不能修改进程的session。Vista(不含)以下版本的win任务管理器中你至少会看到一个session。Vista以上版本的win你至少会看到两个session。

Win不会将你限制在初始数目的session上。你可以创建任意个数的session——有最大上限,但是为了方便起见,我们假设你可以创建无限个session。

Vista以上版本的session0是专用于服务的,0以上的第二个启动的session是第一个登录系统的用户的程序执行的地方。

当有更多用户登录到同一台机器上的时候,将会有更多session创建。包括任何途径——终端服务、远程桌面、快速切换等,任何时候,只要有一个成功登录,一个新的session就创建了。

用API CreateProcessAsUser 来在另一个session中创建进程.调用需要包括关联session的用户标识(token,安全相关)。用Win32 API SetUserToken 和用户标识(TokenSessionId)来设置session的token

下面简单的说明了目前为止,我们对win里头的理解:

  • Session 0
    • Process 0.1
    • Process 0.2
    • Process 0.3
    • ...
    • Process 0.N
  • Session 1
    • Process 1.1
    • Process 1.2
    • Process 1.3
    • ...
    • Process 1.N
  • ...
  • Session M
    • Process M.1
    • Process M.2
    • Process M.3
    • ...
    • Process M.N

Vista改了session运作方式:

Vista之前,首个登录用户和服务共享第一个session,叫做session 0.session0可以进行交互。

Vista起,将用户和服务session隔离开来,session0 用于运行服务,从而不可与用户交互(session1,上面提到过)

如此更改是由于安全原因。用于保证服务不受应用程序的干扰。为毛服务被特殊保护?主要是由于服务的特权(System权限),这个特权意义重大,能搞一些普通程序不能搞的事情。看下面的内容。"How to circumvent all security in Windows".

Vista之前3用户的session状况:

Vista之后的3用户session状况:

两张图的区别在于第一个登录用户是否与服务共享session 0.

Window Stations:                      

每个session里头都有一堆的Window Stations, 剪贴板,以及其他的乱七八糟的东西。每个station都有个名字,这个名字在所属的session中唯一。意思是在一个session中,每个window station都是独立的。多个不同session中的window stations可以叫同一个名字,但他们同样的也是相互独立的。
你可以认为一个window station是一个安全边界。同样的,一个window station创建后你也不能修改所属的session。

进程属于window station,但不同于session和进程的关系,进程可以运行时修改所属的window station

可用于搞window station的api: GetProcessWindowStation, SetProcessWindowStation, CreateWindowStation, and OpenWindowStation.

每个session都有个特别的window station叫做Winsta0. WinSta0是唯一的一个可以显示ui和接收输入的。处理键盘鼠标和显示。其他的不能搞定gui和用户输入。

进程用于设置window station的api: SetProcessWindowStation.
但一个进程设置了所属的window station,就可以访问station所属的东西,比如桌面和剪贴板。后头将讨论桌面。.

进程被父进程启动,如果你没有改window station,将继承父进程的window station。如下api用于创建新的window station: CreateWindowStation

目前为止,win里头有如下的东西:

  • Session 0
    • Winsta0
      • Some Processes
    • Winsta1
      • Some Processes
    • ...
    • WinstaN
      • Some Processes
  • Session 1
    • Winsta0
      • Some Processes
    • Winsta1
      • Some Processes
    • ...
    • WinstaN
    • Some Processes
  • ...
  • Session M
    • Winsta0
      • Some Processes
    • Winsta1
      • Some Processes
    • ...
    • WinstaN
      • Some Processes

Windows Desktops

每个 Window Station都有一堆桌面(desktops)。 桌面(desktop)是载入内核内存空间中的,逻辑上存在的显示设备。所有GUI对象都在桌面上分配。

每个桌面都属于一个session和(同时也属于)一个 window station

同一时间每个session只有一个桌面能被显示。根据定义,必须属于WinSta0. 该桌面叫做输入桌面。可以用如下api拿一个到当前session的输入桌面的句柄: OpenInputDesktop

WinSta0 有三个桌面:

  1. Winlogon (登录屏幕)
  2. Default (程序所在的桌面)
  3. ScreenSaver(屏幕保护)

在vista以上版本的win中有第四个桌面,叫做安全桌面("Secure Desktop"),用于uac提示。

锁定机器的时候从默认桌面转入WinLogon桌面.

NT服务运行的时候,每个有指定权限的服务都将创建自己的station和桌面。(下头会讲相关内容,参考. 允许服务与桌面交互)

如下api用于处理桌面相关:

要指定启动进程的desktop 和window station,可以修改STARTUP结构的lpDesktop成员。通常被CreateProcessAsUser or CreateProcess调用

目前为止,windows桌面内部结构如下:

  • Session 0
    • Station Winsta0
      • Desktop Winlogon
        • Some processes
      • Desktop Default
        • Some processes
      • Desktop Screensaver
        • Some processes
      • Desktop UAC
        • Some processes
      • Some other Desktops
        • Some processes
    • Station Winsta1
      • Some other Desktops
        • Some processes
    • ...
    • Station WinstaN
      • Some other Desktops
        • Some processes
  • Session 1
    • Station Winsta0
      • Desktop Winlogon
        • Some processes
      • Desktop Default
        • Some processes
      • Desktop Screensaver
        • Some processes
      • Desktop UAC
        • Some processes
      • Some other Desktops
        • Some processes
    • Station Winsta1
      • Some other Desktops
        • Some processes
    • ...
    • Station WinstaN
      • Some other Desktops
        • Some processes
  • ...
  • Session M
    • Station Winsta0
      • Desktop Winlogon
        • Some processes
      • Desktop Default
        • Some processes
      • Desktop Screensaver
        • Some processes
      • Desktop UAC
        • Some processes
      • Some other Desktops
        • Some processes
    • Station Winsta1
      • Some other Desktops
        • Some processes
    • ...
    • Station WinstaN
      • Some other Desktops
        • Some processes

选读:服务配置页的谜样的多选框

奇怪的多选框:允许服务与桌面交互。

这个多选框决定服务是运行在Window Station Winsta0还是其他的,不允许用户交互的Window Station。不确定这个多选框是不是会在今后的版本被移除,但直到win7还会是被支持的。(8.1也还是支持的)

任何服务都可以从注册表中打开该选项,因此他本身就可能有安全隐患,因此猜测可能会在今后的版本中移除。.

打开选项会创建一个新的session,并创建新的window station叫做winsta0.若服务试图显示gui,会 在用户当前session上激活一个提示框,告诉你其他桌面有消息需要被处理。你可以单击确定来显示gui,或者说等个5min再提示。单击显示,一般会看到一个黑屏,上头放着service的gui,没有别的东西了。

关闭该选项的时候,若服务试图显示gui,没有任何提示,调用不会失败但也不会有任何的效果。服务起的的时候会在session0上启动。

Windows 句柄

Windows系统中的窗口属于desktop对象。

窗口是任何用于显示的gui元素,通常被一个windows句柄(hwnd)所指示。理解windows句柄是非常重要的,这样可以理解在与Desktop交互的时候什么\

Sessions通信

取决于通信类型,跨session通信是可能的。

管道,全局事件,sockets等可以跨session通信。.

但如windows messages和本地事件是不允许跨session通信的。

如前所述,windows vista有巨大的改变,从这个版本开始所有服务在session0中而不与用户共享。意味着大量的以windows services模式运行的程序,不再能直接显示gui。

对服务而言适当的显示gui的方式是做一些跨session通信,如管道等。这时候gui程序会是另一个程序,通过跨进程通信方式与服务交互。

另一个方式是在用户session的winsta0中的默认桌面上启动一个进程。

桌面间的通信

Windows消息不能跨桌面通信,只能在同一桌面上通信。如下文章确认: Inter-Desktop communication via message passing is not possible.

意味着用于监视和得到通知的hook消息只能在同一桌面上完成。

因此键盘记录器不能记录到锁屏的密码,因为在不同桌面上。

枚举桌面后,可以枚举每个桌面的所有窗口.可以用API EnumDesktopWindows 来枚举桌面窗体。这个api拿一个desktop的句柄并且返回在这个desktop里头的窗体的句柄,侧面证明了windows是desktop的一个子对象。

绕过安全机制(未测试)

访问并对其他session、window station、desktop为所欲为实际上是可能的。方法是建立一个以system账户运行的服务。

该服务运行并提权(通过manifest问卷)后,可以拿到token并且将其与任何session中的任何进程的token相联系,然后用token运行一个帮助程序来做任何想做的事。实际上windows任务管理器就是这么干的。

//uac创建两个token,第二个是受限的token,第一个则是logonuser返回的token。
//UAC creates 2 tokens.  The second one is the restricted token and the first one is the one returned by LogonUser
//Vista and above links the elevated token to the Logonuser token though :))))
TOKEN_LINKED_TOKEN tlt;
DWORD len;
if(GetTokenInformation(hToken
    , (TOKEN_INFORMATION_CLASS)TokenLinkedToken
    , &tlt, sizeof(TOKEN_LINKED_TOKEN)
    , &len))
{
    hLinkedToken = tlt.LinkedToken;
    //From here you can start elevated processes
}

捆绑在一起 Tying it all together

回答之前的问题。

当你锁定计算机的时候会发生什么?对于所有正在运行的程序而言?对于任务栏而言?

锁屏将当前桌面转换到winlogon桌面,这两个桌面在同一个window station winsta0中的。当然,两个桌面在同一个session中。

同样也意味着每个session有自己独立的登录屏幕,并且同一时间,在同一个机器上不同的用户有自己的独立的屏幕

UAC有啥特别的?他们如何锁定并且将整个屏幕变暗?他能真正的保护我吗?

Uac默认将你转入一个叫做安全桌面的桌面上。Uac创建截屏并且将变暗效果在图像上处理。然后在上头显示uac。Uac是安全桌面的一部分,用户可以要求在当前桌面上显示uac提示窗口(安全性较低一些)

为毛键盘记录器无法记录一台锁屏计算机的密码

小时候。。这不重要啦I remember as a kid writing a key logger and using it at school. I was able to see everyone's login password, then later I could login as them and see all of their files. Since then multi Session operating systems have been introduced though.

键盘记录软件 依赖于hook监听windows message来接受每个键的事件(按下、弹起、击键——按下短时间弹起)

由于键盘记录器与登录界面不在同一桌面,因此不能记录密码.

跨session的键盘记录器可能是可能的。但没有发现存在的。看上头获得更多信息。

屏保及其工作原理

没有什么特别的,没有隐藏任何gui元素,也没有在上头绘制,只是做了一次桌面切换操作,切换到屏保桌面。记住桌面是一个逻辑的图形设备

多用户同时登陆

非常简单,每个用户有一个自己的session,每个session有其他的东西,每个人看到自己的winsta0 window Station.

.

终端服务

终端服务与远程桌面让你能访问一个已经打开的session或新的session。Session可以在已连接或未连接的状态。

为毛一些远程控制软件很渣

一些原厂控制软件(不是终端服务/远程桌面)没有考虑session,只能运作在第一个session上。包括大多数 VNC servers including FogCreek Copilot.

这种软件有多个session存在时不能控制其他session.

进程跨session通信

可以,但是你需要知道通信指的是什么(管道、socket等)

进程跨桌面接受消息?

做不到

Vista为毛那么渣,而win7就可以接受了

(一种原因是)vista部分的破坏了向后兼容性,许多软件开发公司及他们的产品没来得及处理session0隔离。最大的问题在于没有正确的理解。

Win7推出的时候一段时间已经过去了,因此一些改变已经发生。因此vista看起来很渣,当然,这就是vista的问题,因为他首先破坏了向后兼容性。

我没说vista完美,远远没到完美,但对vista的批评高于它应得的。

进一步阅读