Session 0:微软为“性能贪婪”买单的二十年
很多做Windows开发的工程师,第一次听说Session 0隔离(Session 0 Isolation),大概率是因为遇到了Bug。比如,写了一个系统服务(Windows Service),想在后台弹出对话框通知用户,结果发现对话框压根弹不出来;或者在服务里调用MessageBox,程序直接挂起;甚至有时...... 本文来自微信公众号: 宇众不同的露萱 ,作者:宇众不同的露萱,原文标题:《Session 0:微软为“性能贪婪”买单的二十年》 很多做Windows开发的工程师,第一次听说Session 0隔离(Session 0 Isolation
本条来自 虎嗅(Business / 中文商业),聚焦 consumer。 很多做Windows开发的工程师,第一次听说Session 0隔离(Session 0 Isolation),大概率是因为遇到了Bug。比如,写了一个系统服务(Windows Service),想在后台弹出对话框通知用户,结果发现对话框压根弹不出来;或者在服务里调用MessageBox,程序直接挂起;甚至有时...... 本文来自微信公众号: 宇众不同的露萱 ,作者:宇众不同的露萱,原文标题:《Session 0:微软为“性能贪婪”买单的二十年》 很多做Windows开发的工程师,第一次听说Session 0隔离(Session 0 Isolation),大概率是因为遇到了Bug。 比如,写了一个系统服务(Windows Service),想在后台弹出对话框通知用户,结果发现对话框压根弹不出来;或者在服务里调用MessageBox,程序直接挂起;甚至有时候想通过服务启动一个有界面的客户端,发现进程虽然跑起来了,但屏幕上空空如也,连个UI影子都看不到。 翻官方文档,微软会用非常标准、非常严肃的语气告诉你: 从Windows Vista开始,出于安全考虑,系统服务运行在Session 0中,而用户登录运行在Session 1及后续Session中。Session 0与用户会话完全隔离,不允许任何交互式UI。
很多做Windows开发的工程师,第一次听说Session 0隔离(Session 0 Isolation),大概率是因为遇到了Bug
- 很多做Windows开发的工程师,第一次听说Session 0隔离(Session 0 Isolation),大概率是因为遇到了Bug
很多做Windows开发的工程师,第一次听说Session 0隔离(Session 0 Isolation),大概率是因为遇到了Bug
比如,写了一个系统服务(Windows Service),想在后台弹出对话框通知用户,结果发现对话框压根弹不出来;或者在服务里调用MessageBox,程序直接挂起;甚至有时
本文来自微信公众号: 宇众不同的露萱 ,作者:宇众不同的露萱,原文标题:《Session 0:微软为“性能贪婪”买单的二十年》 很多做Windows开发的工程师,第一次听说Session 0隔离(Session 0 Isolation
很多做Windows开发的工程师,第一次听说Session 0隔离(Session 0 Isolation),大概率是因为遇到了Bug。比如,写了一个系统服务(Windows Service),想在后台弹出对话框通知用户,结果发现对话框压根弹不出来;或者在服务里调用MessageBox,程序直接挂起;甚至有时...... 本文来自微信公众号: 宇众不同的露萱 ,作者:宇众不同的露萱,原文标题:《Session 0:微软为“性能贪婪”买单的二十年》 很多做Windows开发的工程师,第一次听说Session 0隔离(Session 0 Isolation),大概率是因为遇到了Bug。 比如,写了一个系统服务(Windows Service),想在后台弹出对话框通知用户,结果发现对话框压根弹不出来;或者在服务里调用MessageBox,程序直接挂起;甚至有时候想通过服务启动一个有界面的客户端,发现进程虽然跑起来了,但屏幕上空空如也,连个UI影子都看不到。 翻官方文档,微软会用非常标准、非常严肃的语气告诉你: 从Windows Vista开始,出于安全考虑,系统服务运行在Session 0中,而用户登录运行在Session 1及后续Session中。Session 0与用户会话完全隔离,不允许任何交互式UI。
官方解释非常合理。但每次读到这里,我其实都有个疑问: 如果这个设计这么好、这么安全,为什么微软到了2006年(Vista发布时)才想起来做? Windows NT架构过了整整13年。难道Dave Cutler(Windows NT之父)和他的顶尖团队,当年就没意识到后台服务和用户界面混在一起有安全风险吗? 后来查了一些早期的NT技术文档和旧邮件,我才发现,事情根本不是“微软突然醒悟了”,而是他们终于买单了早期一个看似极其高明、实则后患无穷的架构设计。 现在的年轻程序员可能很难想象,在90年代初,Windows NT的目标不是去替代Windows 3.1,而是要跟UNIX抢服务器市场,跟VMS抢企业市场。 那时候的Windows NT架构其实非常优雅。为了追求极致的安全和模块化,微软采用了微内核思想(虽然不是纯粹的微内核): 图形子系统(GDI、USER)是运行在用户态的一个独立进程,叫csrss.exe。 如果你在系统里启动一个后台服务,或者运行一个桌面程序,大家要画界面,都得通过LPC(Local Procedure Call,本地过程调用)跨进程发消息给csrss.exe,让它帮忙把窗口画出来。 在那个时代,不管你是后台Service,还是前台用户程序,大家都生活在同一个巨大的空间里。这个空间,就是后来的Session 0。 这个设计在架构上非常漂亮,隔离性也很好。但它带来了一个致命的问题:慢。 在硬件条件下,频繁的跨进程通信(Context Switch)开销大得吓人。用户拖动一个窗口,系统就要在用户进程、csrss.exe和驱动之间来回切上下文几百次。当时的电脑跑Windows NT 3.1,用户体验简直是一场灾难,窗口刷新像幻灯片一样。 微软面临一个选择:是坚持优雅但极其缓慢的架构,还是为了性能向现实妥协? 1996年,Windows NT 4.0发布。 为了彻底解决图形性能问题,微软做了一个在当时争议极大的决定:把图形子系统(GDI和USER)直接搬进了内核态(Kernel Mode)。 这就是win32k.sys的由来。 这招极其管用。图形渲染不再需要繁琐的跨进程通信,系统性能瞬间飞升。Windows桌面变得顺滑无比,这也是Windows后来能统治PC桌面的关键一步。 但天下没有免费的午餐。 把图形子系统放进内核后,为了让后台服务(比如SQL Server、IIS、或者各种打印服务)也能方便地给管理员弹窗、显示状态,微软保留了所有的便利性: 所有服务和第一个登录的用户,依然共享同一个Session,也就是Session 0。 不仅共享Session,它们还共享同一个桌面对象(WinStation0\Default)、同一个消息队列,甚至可以互相发Windows消息(WM_SYSCOMMAND、WM_DROPFILES等)。 在90年代末,这被认为是一种“特性”(Feature)。 你想想,一个后台运行的备份服务,发现磁盘满了,直接在屏幕上弹个框提示管理员:“请插入光盘B”,管理员点个确定,服务继续跑。多方便! 这种便利性,直接导致了接下来的十年里,全世界的Windows程序员都在这么写代码。无数的企业级软件、杀毒软件、硬件驱动服务,都深深地依赖“Session 0可以直接弹窗和交互”这个假设。 但灾难的种子,就在这时候种下了。 安全专家Chris Paget发表了一篇著名的论文,揭露了一种被称为Shatter Attack(粉碎攻击)的漏洞利用方式。 这种攻击的原理简单得令人发指,但后果极其严重。 在Windows的消息机制里,你可以用SendMessage或者PostMessage给任意一个窗口发消息。如果这个窗口属于一个高权限的系统服务(运行在System权限下),事情就变得有意思了。 比如,有些Windows控件(如RichEdit)支持一些特殊的消息,比如EM_SETWORDBREAKPROC。这个消息的作用是:“请把我提供的这段代码地址,作为换行回调函数来执行。” 如果一个运行在低权限的用户程序,给Session 0里高权限服务的窗口发了这条消息,然后再触发一次换行…… 高权限服务就会无条件地去执行那个地址里的代码。 低权限用户直接拿到了系统最高权限(SYSTEM)。 更要命的是,因为大家都在Session 0里,所有服务的窗口对低权限程序都是完全可见、可发消息的。这根本不是某个具体软件的Bug,而是整个Windows交互模型的底层设计缺陷。 只要Session 0里还允许服务弹窗口,只要服务和用户还待在同一个Session里,这种攻击就永远禁不绝。 当时正值微软推出“可信计算”倡议,盖茨亲自发内部信要求把安全放在第一位。面对Shatter Attack这种底层的系统级漏洞,微软必须做决定了。 修补这个漏洞有两个选项: 选项A:挨个修补API,禁止跨权限发某些危险消息(UIPI机制)。
选项B:彻底切割。把服务和用户强行拆开,服务留在Session 0,用户去Session 1、2、3……
微软很快发现,只搞选项A是治标不治本的。因为只要有图形交互,就有无数种奇奇怪怪的方法可以通过窗口句柄搞事情。 必须选B。 于是,在Windows Vista中,Session 0隔离正式上线。 微软划出了一道无比坚固的红线: Session 0专门给系统服务用,里面完全没有图形界面(No UI)。
第一个登录的用户,不再分配到Session 0,而是从Session 1开始。
Session 0和Session 1之间的所有GUI消息通道、剪贴板、共享内存全部切断。
从技术角度看,这个方案极为干净利落,彻底封死了Shatter Attack。 但对整个Windows生态来说,这是一场巨大的地震。 Vista发布后的好几年里,无数软件被骂“不兼容Vista”,其中相当一部分就是因为Session 0隔离。 那些习惯了在服务里弹窗、在服务里截屏、在服务里启动UI进程的软件,全部瘫痪。 微软为了安抚开发者,甚至在Vista和Win7里做了一个非常妥协的补丁服务——Interactive Services Detection(UI0Detect)。 当Session 0里的服务试图弹窗时,系统会在右下角冒出一个提示:“有一个程序试图在屏幕上显示消息”。用户点进去后,整个桌面会被切到一个黑乎乎的、极其丑陋的临时的Session 0桌面里,让你点那个对话框。 这个过渡方案丑陋至极,但它折射出架构变革时的无奈:为了兼容性,你总得给旧世界的遗产留一口气。 直到Windows 10,微软才彻底废弃了UI0Detect服务。至此,Session 0的交互彻底成为了历史。 如果重新审视这段历史,你会发现技术演进中一个非常有意思的轮回: 1993年(NT 3.1):想要优雅的隔离,但因为性能代价太高,放弃了。
1996年(NT 4.0):为了极致的性能和便利,把安全和隔离塞进了同一个桶里(Session 0)。
2006年(Vista):享受了十年的性能红利后,安全欠债爆仓,不得不花极大的生态代价,重新把隔离做回来。
这种“先为了性能/便利合并,再为了安全/可维护性拆分”的故事,在计算机历史上一次次重演。 今天的Linux容器、浏览器沙盒机制、甚至WebAssembly的设计,其实多多少少都能看到当年Windows处理Session 0时面临的相同困境:我们到底该在安全边界和运行效率之间划哪一条线?
本条目归入「Consumer Trends」垂直,涉及真实话题:consumer。
· 市场:关注 consumer 对相关品类与竞争格局的潜在影响。
· 消费者:受众行为与偏好变化值得追踪。
· 品牌:本动向对品牌资产建设的启示。
· 渠道:内容分发与触点组合(社媒 / 电商 / 线下)的协同值得复盘。
· 核心话题:consumer。
· 可思考:如何把「consumer」的洞察,转化为可衡量的内容与增长动作?
面试中可引用「Session 0:微软为“性能贪婪”买单的二十年」:围绕 consumer,说明你对行业动向的判断与可落地动作。
本条目相关英文术语可在「商务英语」模块按话题检索,用于外企面试表达训练。
本条正文未命中预设商业词表,可前往 /english 系统学习。
系统商务英语 →