理解Windows会话

以前我一直不理解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页)

Session

也就是说默认情况下会话空间的大小是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结构的定义如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
typedef struct _MM_SESSION_SPACE
{
     //
     // This is a pointer in global system address space, used to make various
     // fields that can be referenced from any process visible from any process
     // context.  This is for things like mutexes, WSL chains, etc.
     //
     struct _MM_SESSION_SPACE *GlobalVirtualAddress;
 
     LONG ReferenceCount;
 
     union
     {
         ULONG LongFlags;
         MM_SESSION_SPACE_FLAGS Flags;
     } u;
 
     ULONG SessionId;
 
     //
     // This is the list of the processes in this group that have
     // session space entries.
     //
 
     LIST_ENTRY ProcessList;
 
     LARGE_INTEGER LastProcessSwappedOutTime;
 
     //
     // All the page tables for session space use this as their parent.
     // Note that it's not really a page directory - it's really a page
     // table page itself (the one used to map this very structure).
     //
     // This provides a reference to something that won't go away and
     // is relevant regardless of which process within the session is current.
     //
 
     PFN_NUMBER SessionPageDirectoryIndex;
 
     //
     // This is the count of non paged allocations to support this session
     // space.  This includes the session structure page table and data pages,
     // WSL page table and data pages, session pool page table pages and session
     // image page table pages.  These are all charged against
     // MmResidentAvailable.
     //
 
     SIZE_T NonPageablePages;
 
     //
     // This is the count of pages in this session that have been charged against
     // the systemwide commit.  This includes all the NonPageablePages plus the
     // data pages they typically map.
     //
 
     SIZE_T CommittedPages;
 
     //
     // Start of session paged pool virtual space.
     //
 
     PVOID PagedPoolStart;
 
     //
     // Current end of pool virtual space. Can be extended to the
     // end of the session space.
     //
 
     PVOID PagedPoolEnd;
 
     //
     // PTE pointers for pool.
     //
 
     PMMPTE PagedPoolBasePde;
 
     ULONG Color;
 
     LONG ResidentProcessCount;
 
     ULONG SessionPoolAllocationFailures[4];
 
     //
     // This is the list of system images currently valid in
     // this session space.  This information is in addition
     // to the module global information in PsLoadedModuleList.
     //
 
     LIST_ENTRY ImageList;
 
     LCID LocaleId;
 
     //
     // The count of "known attachers and the associated event.
     //
 
     ULONG AttachCount;
 
     KEVENT AttachEvent;
 
     PEPROCESS LastProcess;
 
     //
     // This is generally decremented in process delete (not clean) so that
     // the session data page and mapping PTE can finally be freed when this
     // reaches zero.  smss is the only process that decrements it in other
     // places as smss never exits.
     //
 
     LONG ProcessReferenceToSession;
 
     //
     // This chain is in global system addresses (not session VAs) and can
     // be walked from any system context, ie: for WSL trimming.
     //
 
     LIST_ENTRY WsListEntry;
 
     //
     // Session lookasides for fast pool allocation/freeing.
     //
 
     GENERAL_LOOKASIDE Lookaside[SESSION_POOL_SMALL_LISTS];
 
     //
     // Support for mapping system views into session space.  Each desktop
     // allocates a 3MB heap and the global system view space is only 48M
     // total.  This would limit us to only 20-30 users - rotating the
     // system view space with each session removes this limitation.
     //
 
     MMSESSION Session;
 
     //
     // Session space paged pool support.
     //
 
     KGUARDED_MUTEX PagedPoolMutex;
 
     MM_PAGED_POOL_INFO PagedPoolInfo;
 
     //
     // Working set information.
     //
 
     MMSUPPORT  Vm;
     PMMWSLE    Wsle;
 
     PDRIVER_UNLOAD Win32KDriverUnload;
 
     //
     // Pool descriptor for less than 1 page allocations.
     //
 
     POOL_DESCRIPTOR PagedPool;
 
#if (_MI_PAGING_LEVELS >= 3)
 
     //
     // The page directory that maps session space is saved here so
     // trimmers can attach.
     //
 
     MMPTE PageDirectory;
 
#else
 
     //
     // The second level page tables that map session space are shared
     // by all processes in the session.
     //
 
     PMMPTE PageTables;
 
#endif
 
#if defined (_WIN64)
 
     //
     // NT64 has enough virtual address space to support per-session special
     // pool.
     //
 
     PMMPTE SpecialPoolFirstPte;
     PMMPTE SpecialPoolLastPte;
     PMMPTE NextPdeForSpecialPoolExpansion;
     PMMPTE LastPdeForSpecialPoolExpansion;
     PFN_NUMBER SpecialPagesInUse;
#endif
 
     LONG ImageLoadingCount;
 
#if DBG
     ULONG Debug[MM_SESS_COUNTER_MAX];
 
     MM_SESSION_MEMORY_COUNTERS Debug2[MM_SESS_MEMORY_COUNTER_MAX];
#endif
 
} 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。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
typedef struct _PEB
{
     BYTE Reserved1[2];
     BYTE BeingDebugged;
     BYTE Reserved2[1];
     PVOID Reserved3[2];
     PPEB_LDR_DATA Ldr;
     PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
     BYTE Reserved4[104];
     PVOID Reserved5[52];
     PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
     BYTE Reserved6[128];
     PVOID Reserved7[1];
     ULONG SessionId;
} PEB, *PPEB;

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


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

 
今天先写到这儿了!


  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
理解Microsoft专家认证程序 理解Microsoft认证的不同等级和类型 选择成为MCP(Microsft认证专家)的考试科目 选择成为MCSD的考试科目 选择成为MCT的考试科目 MCSE认证考试的科目 选择合适的MCSE课程组合 核心课程考试 选修课程考试 考试编号的识别 课程内容和考试内容的对照 理解微软的MCSE长远考虑 理解微软出题的方式 使用本书帮助备考 在Internet上寻找对考试有帮助的信息 寻求微软认可的课程指导 寻找高质量的和三方帮助 寻找可利用的评估软件拷贝 报名参加考试 考试的费用问题 考前的自我调整 使用考试中心提供的考试工具 参加模拟测试 熟悉使用计算机进行考试 充分利用考试时间 考题的形式 理解多重选择题型 理解对错题题型 理解多重选择多重答案题型 理解基于解决方案型的问题 理解“建议方法”类型的考题 分析考试结果 准备重新考试 合理安排考试课程的顺序 熟悉Windows系列产品 比较Windows NT Server和NT Workstation 比较Windows NT Workstaton和Windows 95 在Windowx 95和Windows NT Workstation之间作出选择 关于Microsoft Windows NT的70-069号考试:实现和支持Microsoft Windows NT Server 4.0 70-069号考试(实现和支持Microsoft Windows NT Server 4.0)覆盖的内容 Windows NT 4.0界面简介 Windows NT 4.0任务栏(taskbar)的使用 Windows NT回收站简介 Windows NT帐号简介 理解单域模型支持和帐号数量 安全认证号简介 使用管理向导(Administrative Wizards)创建帐号 使用Server Manager(服务器管理器)程序创建计算机帐号 Userver Manager for Domains(域的用户管理器)简介 使用User Mnager for Domains创建用户帐号 刷新用户帐号列表 用户帐号列表的排序 事件查看器(Event View)程序简介 筛选Event Viewer中的事件 授予用户在本地登录的权利 使用Windows NT诊断程序查看系统配置 激活“Windows NT Security(Windows NT安全)”对话框 理解登录验证过程 理解访问令牌(Access Token) Windows NT目录服务简介 理解Windows NT如何构造用户帐号数据库 使用Windows NT中的Ctrl+Alt+Del组合键 把Windows NT计算机设置成自动登录 改变Windows NT口令 用拨号网络登录 复制用户帐号 为简化多个帐号的创建工作而建立用户帐号模板 删除和重新命名用户帐号 理解保护缺省的Administrator帐号的重要性 重新命名管理员帐号 理解缺省的Guest帐户 Windows NT在哪里创建帐号 设置口令限制条件 设置用户登录地点 创建宿主文件夹 设置用户登录时间 创建临时用户帐号 重新设置用户帐号口令 修改多个用户帐号 自动注销有时间限制的用户 要求用户在下次登录时改变口令 设置帐号规则 设置用户口令永不过期 停用用户帐号 解开登录失败后的用户帐号 Windows NT组简介 理解用户权限和组的访问权限 理解用户和组的权利 分清权限(permission)和权利(right) 设置组成成员关系 理解全局帐号 理解本地帐号 定义Everyone组 Network组的详细说明 Inteactive组的详细说明 Administrators组的详细说明 Guest组的详细说明 Users组的详细说明 Print Operators组的详细说明 Backup Operators(帐户操作员)组的详细说明 Replicator(复制员)组的详细说明 Domain Guests(域客户)组的详细说明 Domain Users(域用户)组的详细说明 Domain Admins(域管理员)组的详细说明 赋予拨号进入权限 理解用户配置文件(User Profile) 为Windows用户创建并使用登录脚本文件(Logon Script) 创建漫游式用户配置文件(Roaming User Profile) 创建强制性用户配置文件(Mandatory User Profile) 为用户帐号分配一个配置文件 创建帐户时变量的使用 创建随机初始化口令 理解内建组(Built-in Group) 理解组和策略 设置主组(Primary Group) 理解删除一个组的影响 域控制器(Domain Controller)简介 成员服

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值