首页
社区
课程
招聘
[旧帖] [转帖]理解Windows会话 0.00雪花
发表于: 2011-5-1 16:42 1685

[旧帖] [转帖]理解Windows会话 0.00雪花

2011-5-1 16:42
1685
来源:http://www.cnblogs.com/russinovich/archive/2011/04/26/2029655.html
  以前我一直不理解Windows Session(会话)倒底是一个什么概念,总是感觉这个概念很虚,现在理解了一点。写下来做一个备忘。简单的说,用户登陆到windows系统之后,不管该用户是本地登陆的,还是远程登陆,系统都会为这个用户分配一个新的会话ID(SID)。也就是说会话与用户的登录是相关连的,没有用户登录就不存在会话。因此,会话的含义是指用户登录之后的一种运行的环境。我们先看看书上是怎么说的!

  会话管理器(\Windows\System32\Smss.exe)是系统中第一个创建的用户态模式进程,负责完成执行体和内核的初始化工作的内核模式系统线程在最后阶段创建了实际的Smss进程(这段摘自: 《深入解析Windows操作系统(第4版)》80页)。

  Windows系统是支持多会话的,因此会话空间(session space)包含了一些针对每个会话的全局信息。所以会话空间是用来管理会话的。那么会话具体包含些什么呢?

     会话(session)是由进程和其他的系统对象(比如窗口站、桌面和窗口)构成的,它们代表了一个用户的工作站登录会话。会话具体是由如下几个部分组成的:

     1. 每个会话包含一个单独的win32k.sys

     2. 专门的换页池区域

     3. 私有windows子系统和登陆进程的拷贝

     4. 系统空间中被映射的空间,被称为会话空间的区域

     (参考: 《深入解析Windows操作系统(第4版)》 414页)

      现在我把会话同进程做一个比较,发现他们之间有一些相似之处:

      1. 都提供一个执行的环境

      2. 都有一个私有空间

      进程是为了内部的执行的线程提供一个空间和环境,而会话则是为内部所有的进程提供一个执行的空间和环境。(这是我总结的,感觉总结的很好,便于大家理解会话的概念)

X86会话空间的布局,如下图:(本人手工绘制 参考:《深入解析Windows操作系统(第4版)》 419页)


也就是说默认情况下会话空间的大小是8+4+20+16=48M

--------------------------------------------------------------------------------

在我的机器上做如下的实验:

lkd> !session
Sessions on machine: 1
Valid Sessions: 0
Current Session 0

可以看出我的机器上面只有一个会话,因为是我的机器,只有我在登陆。

--------------------------------------------------------------------------------

调用!sprocess 显示该会话数据结构的地址和该会话中的进程

lkd> !sprocess
Dumping Session 0

_MM_SESSION_SPACE b85dc000  这里就是会话空间的地址
_MMSESSION        b85dc15c
PROCESS 8a11a268  SessionId: 0  Cid: 028c    Peb: 7ffdf000  ParentCid: 0190
    DirBase: 0aa00060  ObjectTable: e1b01120  HandleCount: 346.
    Image: csrss.exe

PROCESS 8a2d0318  SessionId: 0  Cid: 02a4    Peb: 7ffdf000  ParentCid: 0190
    DirBase: 0aa00080  ObjectTable: e18c70b0  HandleCount: 581.
    Image: winlogon.exe

PROCESS 8a349da0  SessionId: 0  Cid: 02d0    Peb: 7ffda000  ParentCid: 02a4
    DirBase: 0aa000a0  ObjectTable: e1e8da78  HandleCount: 266.
    Image: services.exe

…….

--------------------------------------------------------------------------------
我现在查看会话的结构
lkd> dt nt!_MM_SESSION_SPACE b85dc000
   +0x000 ReferenceCount   : 0x15
   +0x004 u                : __unnamed
   +0x008 SessionId        : 0
   +0x00c SessionPageDirectoryIndex : 0x18626
   +0x010 GlobalVirtualAddress : 0xb85dc000 _MM_SESSION_SPACE
   +0x014 ProcessList      : _LIST_ENTRY [ 0x8a11a31c - 0x89b98c8c ]
   +0x01c NonPagedPoolBytes : 0
   +0x020 PagedPoolBytes   : 0
   +0x024 NonPagedPoolAllocations : 0
   +0x028 PagedPoolAllocations : 0
   +0x02c NonPagablePages  : 0x17
   +0x030 CommittedPages   : 0x5e4
   +0x038 LastProcessSwappedOutTime : _LARGE_INTEGER 0x0
   +0x040 PageTables       : 0x8a0bb3e8 _MMPTE
   +0x044 PagedPoolMutex   : _FAST_MUTEX
   +0x064 PagedPoolStart   : 0xb9800000
   +0x068 PagedPoolEnd     : 0xb9bfffff
   +0x06c PagedPoolBasePde : 0xc0602e60 _MMPTE
   +0x070 PagedPoolInfo    : _MM_PAGED_POOL_INFO
   +0x094 Color            : 0xba6
   +0x098 ProcessOutSwapCount : 5
   +0x09c ImageList        : _LIST_ENTRY [ 0x8a355ea0 - 0x8a1de1e8 ]
   +0x0a4 GlobalPteEntry   : 0xc05c2ee0 _MMPTE
   +0x0a8 CopyOnWriteCount : 0x13
   +0x0ac SessionPoolAllocationFailures : [4] 0
   +0x0bc AttachCount      : 0
   +0x0c0 AttachEvent      : _KEVENT
   +0x0d0 LastProcess      : (null)
   +0x0d8 Vm               : _MMSUPPORT
   +0x118 Wsle             : 0xbcc0003c _MMWSLE
   +0x11c WsLock           : _ERESOURCE
   +0x154 WsListEntry      : _LIST_ENTRY [ 0x80561b58 - 0x80561b58 ]
   +0x15c Session          : _MMSESSION
   +0x198 Win32KDriverObject : _DRIVER_OBJECT
   +0x240 WorkingSetLockOwner : (null)
   +0x244 PagedPool        : _POOL_DESCRIPTOR
   +0x126c ProcessReferenceToSession : 43
   +0x1270 LocaleId         : 0x409

来自微软官方的C结构的定义如下:

view sourceprint?001 typedef struct _MM_SESSION_SPACE  

002 {  

003     //  

004     // This is a pointer in global system address space, used to make various  

005     // fields that can be referenced from any process visible from any process  

006     // context.  This is for things like mutexes, WSL chains, etc.  

007     //  

008     struct _MM_SESSION_SPACE *GlobalVirtualAddress;  

009   

010     LONG ReferenceCount;  

011   

012     union

013     {  

014         ULONG LongFlags;  

015         MM_SESSION_SPACE_FLAGS Flags;  

016     } u;  

017   

018     ULONG SessionId;  

019   

020     //  

021     // This is the list of the processes in this group that have  

022     // session space entries.  

023     //  

024   

025     LIST_ENTRY ProcessList;  

026   

027     LARGE_INTEGER LastProcessSwappedOutTime;  

028   

029     //  

030     // All the page tables for session space use this as their parent.  

031     // Note that it's not really a page directory - it's really a page  

032     // table page itself (the one used to map this very structure).  

033     //  

034     // This provides a reference to something that won't go away and  

035     // is relevant regardless of which process within the session is current.  

036     //  

037   

038     PFN_NUMBER SessionPageDirectoryIndex;  

039   

040     //  

041     // This is the count of non paged allocations to support this session  

042     // space.  This includes the session structure page table and data pages,  

043     // WSL page table and data pages, session pool page table pages and session  

044     // image page table pages.  These are all charged against  

045     // MmResidentAvailable.  

046     //  

047   

048     SIZE_T NonPageablePages;  

049   

050     //  

051     // This is the count of pages in this session that have been charged against  

052     // the systemwide commit.  This includes all the NonPageablePages plus the  

053     // data pages they typically map.  

054     //  

055   

056     SIZE_T CommittedPages;  

057   

058     //  

059     // Start of session paged pool virtual space.  

060     //  

061   

062     PVOID PagedPoolStart;  

063   

064     //  

065     // Current end of pool virtual space. Can be extended to the  

066     // end of the session space.  

067     //  

068   

069     PVOID PagedPoolEnd;  

070   

071     //  

072     // PTE pointers for pool.  

073     //  

074   

075     PMMPTE PagedPoolBasePde;  

076   

077     ULONG Color;  

078   

079     LONG ResidentProcessCount;  

080   

081     ULONG SessionPoolAllocationFailures[4];  

082   

083     //  

084     // This is the list of system images currently valid in  

085     // this session space.  This information is in addition  

086     // to the module global information in PsLoadedModuleList.  

087     //  

088   

089     LIST_ENTRY ImageList;  

090   

091     LCID LocaleId;  

092   

093     //  

094     // The count of "known attachers and the associated event.  

095     //  

096   

097     ULONG AttachCount;  

098   

099     KEVENT AttachEvent;  

100   

101     PEPROCESS LastProcess;  

102   

103     //  

104     // This is generally decremented in process delete (not clean) so that  

105     // the session data page and mapping PTE can finally be freed when this  

106     // reaches zero.  smss is the only process that decrements it in other  

107     // places as smss never exits.  

108     //  

109   

110     LONG ProcessReferenceToSession;  

111   

112     //  

113     // This chain is in global system addresses (not session VAs) and can  

114     // be walked from any system context, ie: for WSL trimming.  

115     //  

116   

117     LIST_ENTRY WsListEntry;  

118   

119     //  

120     // Session lookasides for fast pool allocation/freeing.  

121     //  

122   

123     GENERAL_LOOKASIDE Lookaside[SESSION_POOL_SMALL_LISTS];  

124   

125     //  

126     // Support for mapping system views into session space.  Each desktop  

127     // allocates a 3MB heap and the global system view space is only 48M  

128     // total.  This would limit us to only 20-30 users - rotating the  

129     // system view space with each session removes this limitation.  

130     //  

131   

132     MMSESSION Session;  

133   

134     //  

135     // Session space paged pool support.  

136     //  

137   

138     KGUARDED_MUTEX PagedPoolMutex;  

139   

140     MM_PAGED_POOL_INFO PagedPoolInfo;  

141   

142     //  

143     // Working set information.  

144     //  

145   

146     MMSUPPORT  Vm;  

147     PMMWSLE    Wsle;  

148   

149     PDRIVER_UNLOAD Win32KDriverUnload;  

150   

151     //  

152     // Pool descriptor for less than 1 page allocations.  

153     //  

154   

155     POOL_DESCRIPTOR PagedPool;  

156   

157 #if (_MI_PAGING_LEVELS >= 3)  

158   

159     //  

160     // The page directory that maps session space is saved here so  

161     // trimmers can attach.  

162     //  

163   

164     MMPTE PageDirectory;  

165   

166 #else  

167   

168     //  

169     // The second level page tables that map session space are shared  

170     // by all processes in the session.  

171     //  

172   

173     PMMPTE PageTables;  

174   

175 #endif  

176   

177 #if defined (_WIN64)  

178   

179     //  

180     // NT64 has enough virtual address space to support per-session special  

181     // pool.  

182     //  

183   

184     PMMPTE SpecialPoolFirstPte;  

185     PMMPTE SpecialPoolLastPte;  

186     PMMPTE NextPdeForSpecialPoolExpansion;  

187     PMMPTE LastPdeForSpecialPoolExpansion;  

188     PFN_NUMBER SpecialPagesInUse;  

189 #endif  

190   

191     LONG ImageLoadingCount;  

192   

193 #if DBG  

194     ULONG Debug[MM_SESS_COUNTER_MAX];  

195   

196     MM_SESSION_MEMORY_COUNTERS Debug2[MM_SESS_MEMORY_COUNTER_MAX];  

197 #endif  

198   

199 } MM_SESSION_SPACE, *PMM_SESSION_SPACE;

--------------------------------------------------------------------------------

查看会话空间的内存使用,调用!vm 4命令

lkd> !vm 4
.
.
.
    Terminal Server Memory Usage By Session:

    Session Paged Pool Maximum is 4096K
    Session View Space Maximum is 49152K

    Session ID 0 @ b85dc000:
    Paged Pool Usage:           0K
    Commit Usage:            6032K

--------------------------------------------------------------------------------

现在我们清楚了,当用户登陆到系统中之后,用户下所有的进程都属于这个会话空间。在每个进程的PEB当中就有SessionID。

view sourceprint?01 typedef struct _PEB  

02 {  

03     BYTE Reserved1[2];  

04     BYTE BeingDebugged;  

05     BYTE Reserved2[1];  

06     PVOID Reserved3[2];  

07     PPEB_LDR_DATA Ldr;  

08     PRTL_USER_PROCESS_PARAMETERS ProcessParameters;  

09     BYTE Reserved4[104];  

10     PVOID Reserved5[52];  

11     PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;  

12     BYTE Reserved6[128];  

13     PVOID Reserved7[1];  

14     ULONG SessionId;  

15 } PEB, *PPEB;

该结构最后一个成员就是SessionId。

--------------------------------------------------------------------------------

那么这里就产生一个问题了,同一台机器上面分别属于不同会话空间下的进程之间如何通讯呢?微软的MSDN里面的一些API就说的很清楚了。
我举一个例子吧。如CreateFileMapping MSDN的描述在  http://msdn.microsoft.com/en-us/library/aa366537(VS.85).aspx
lpName 如果使用"Global\" or "Local\" 作用范围是全局的。

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 7992
活跃值: (2566)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
嗯.很好..学习了..谢谢分享.
2011-5-1 17:00
0
雪    币: 1820
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
3
好长,终于看完了……人机交互界面?
2011-5-2 10:50
0
游客
登录 | 注册 方可回帖
返回
//