欢迎光临 Enjoy IT (ITECN.NET) 登录 | 注册 | 帮助

Windows 7 研究——MinWin 初步探索

张康宗(Smallfrogs)
http://www.KZTechs.com

<本文欢迎转载,但是请注明来源和作者>

在很早的时候,网上就出现了关于新一代Windows 内核 MinWin 的说明,例如新一代 Windows 核心才有 25M 等等宣传,甚至还出现了一个字符界面构成的Windows 启动画面的图片。在临近 Windows 7 发布之前,Smallfrogs 将把自己所知的一些关于 MinWin 的内容呈现给大家。

在本文开始之前,先说一下 Windows 核心的具体含义吧。实际上,Windows 核心是由用户态模块和内核态模块构成的,换句话说这些模块是整个操作系统最最核心的部分。在Windows Server 2008 里面,诞生了一个 Server Core 安装模式,在这个安装模式下,Windows 没有了资源管理器等大多数 GUI 程序,但是在 Windows Server 2008 里面,Server Core 并不是那么的纯粹,各个组件的模块化还不足以进行更精细化的区分。

如果对Windows 开发稍微有点了解的都知道,Windows 里面的 API 有成千上万,各个 API 之间的关系错综复杂。要剥离出一个更纯粹的 Server Core会显得更加的困难。而 MinWin 的一个重要的目的就是创建一个独立的架构分区(architectural partitions),使之能够独立的构建、运行和测试,而MinWin被定义为一系列的启动和网络所需要的组件的最小集合,也就是说仅仅包括:

  • Windows 内核(内核态的Ntoskrnel.exe、内核态的启动装载器、用户态的关键DLL等)
  • TCP/IP协议栈
  • 设备驱动
  • ……

而要完成独立的架构分区,需要对一些关键的系统核心模块进行重构。在整个Windows里面,最最关键的用户态核心DLL模块有那么几个:

  • ntdll.dll
  • kernel32.dll
  • advapi32.dll
  • ……

上述几个DLL构成了Windows 用户态核心,而其他的一些DLL,例如Shell32.DLL等都是对上述几个API功能的封装和丰富等,换句话说,如果没有Shell32.DLL,那么系统应该也是能够正常运行的。

在上述的几个DLL里面,原先的分工是这样的:

  • ntdll.dll:负责和Windows内核层打交道
  • kernel32.dll:提供了文件、进程、线程、内存、堆栈等API,所有的Win32应用程序都会加载这个模块
  • advapi32.dll:提供了一些Win32 API高级API,例如:注册表操作、服务操作、ACL操作等

但是在Windows 7里面,因为MinWin的需要,上述API的分工有了一些变化,部分API的实现从一个DLL迁移到了另外的DLL里面,而且还新增了一个DLL:kernelbase.dll。关于新增DLL的用途,今天暂时不用管它,先看看有哪些API的实现有迁移吧。

要判断API的迁移,最简单的办法就是分析PE的输出表,因为所有的Windows基础API的实现都是以__stdcall 方式导出的,只需要对输出表进行分析就知有没有变化了。Smallfrogs 分别对kernel32.dll和advapi32.dll的输出表进行了分析,发现注册表类的API的实现已经从Windows 7之前的advapi32.dll迁移到了kernel32.dll里面。

这是MinWin带来的第一个显著的变化,当然,MinWin 是不会那么简单的,后面一段时间,Smallfrogs 将继续给大家分享自己对 MinWin 的研究结果,例如兼容性问题、虚拟DLL等很多全新的、由 Windows 7带来的变化。

发表于 作者 smallfrogs | 2 评论

Windows 7 研究——IE8 松散耦合进程框架探索

张康宗(Smallfrogs)
http://www.KZTechs.com

<本文欢迎转载,但是请注明来源和作者>

在2008年8月份IE8 Beta刚刚面世不久的时候,我曾经用极短的篇幅介绍了一下IE8的新的Tab控制模型(详情见:《IE8 新特性分析:IE8的稳定性源自何处》 一文)。今天,我将继续和大家分享一些最近一段时间获得的新的知识。

IE8 松散耦合进程框架,英文原文是Loosely Coupled IE (LCIE),是一种基于作业(Job)的进程管理方式。这种方式已经逐渐被各大浏览器所采用,例如Google Chrome。

下图是IE8的LCIE框架结构:

作业是Windows 2000引入的一种进程管理方式,可以用一个宿主进程管理多个子进程。管理进程可以给子进程设置很多属性,特别是一些和性能相关的属性,具体可以参考 SetInformationJobObject Function (Windows) 的API说明文档。

当我们安装完IE8以后,打开一个Tab,使用 Process Explorer 会发现,有2个iexplore.exe实例,这个就是最典型的LCIE表现:Tab工作在进程空间里面,有一个独立的框架进程用于管理Tab进程。

如下图所示,我打开了4个Tab,出现了4个Tab进程(进程ID分别为 9000、9672、6052、3056),框架进程的进程PID是7416:

因为LCIE的模型决定了IE的框架和Tab是独立的进程体,因此相互之间是需要通信的,根据Process Explorer的显示,框架进程和Tab进程的通信是使用的ALPC(高级本地过程调用,在Windows内核里面经常可以见到,效率很高)机制(在Windows Vista上面),关于LPC的技术解释,请Google搜索。

我们继续研究LCIE的标签创建方式。当我们新开启一个Tab以后,系统会创建一个iexplorer.exe进程用于和这个Tab绑定,那么我开启10个Tab以后,是10个进程吗?实际的测试结果是:不一定。具体创建多少个Tab进程实际是由IE框架确定的,根据目前已知的结论,IE框架会根据可用的物理内存大小确认最多创建几个Tab进程。

注:默认情况下,我的2台笔记本(物理内存均配置了4GB,可用内存一般在1.5GB左右)在Windows Vista里面,创建的Tab进程最多是5个。

那么,是否有可能控制Tab进程的数量呢?答案是可以的。IE8 Frame在启动的时候,会检查注册表

HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main下面的TabProcGrowth键值(键值类型DWORD),利用这个键值,就可以操作IE8的Tab数量了。

TabProcGrowth=0 IE框架和Tab工作在一个进程里面,Tab采用线程的方式创建。

当TabProcGrowth=0的时候,IE的保护模式(Protect Mode)会关闭,这种模式类似于在Windows Vista下面把 IE7 以 run as administrator方式启动。
TabProcGrowth=1 IE框架和Tab工作在不同的进程里面。

但是Tab按照不同的mandatory integrity level (MIC)创建,举例就是需要关闭保护模式的Tab工作在一个浏览进程里面,另外的工作在另外的一个浏览进程里面。

例如:我把taobao.com和kztechs.com加入了Trusted Site列表里面,当使用这个模式的时候,访问taobao.com和kztechs.com的时候,Tab将工作在一个进程里面,而访问其他的站点的时候,Tab将工作在另外的一个进程里面。

这是因为加入Trusted Site列表以后,IE的保护模式会关闭,MIC等级的不同造成了的不同的Tab进程的出现。
TabProcGrowth>1 在这个模式下,TabProcGrowth的值将决定最多创建的Tab进程数目。如果TabProcGrowth为100,那么最多创建100个Tab进程。
TabProcGrowth 不存在(默认情况) 使用默认的机制,根据可用的物理内存数量决定Tab进程的数量。

 

关于IE8 LCIE的FAQ:

1、为什么不是每个Tab一个进程,而有一个上限呢?

因为创建一个进程的开销是远远大于创建一个线程的,创建一个进程,需要重新加载所有相关的模块,而且进程间的切换也会带来很大的性能损耗。IE8的LCIE机制在达到Tab进程最多数目以后,后续的新开网页将将采用负载平衡的机制让不同的Tab进程进行处理,以达到资源的最大利用。

2、LCIE模型里面,会话是怎么处理的?我怎么感觉到不同的Tab都使用的是同一个会话呢?

的确,因此Tab进程的出现,会话的处理是比较关注的一个点。在IE8里面,会话是和IE框架绑定的,在这个IE框架下的所有Tab,共享同一个会话,具体来说就是:假设第一个Tab进程访问了msdn.microsoft.com网站并属于了Live ID登录以后,后续新开的Tab进程如果也访问了msdn.microsoft.com网站,那么是共享刚才的Live ID的,除非过期;而且,即使你从开始菜单里面点击IE图标,新创建的窗口也是使用先前的会话的。

3、在LCIE模型里面,如果让不同的窗口使用不同的会话呢?

要在IE8里面,让不同的窗口使用不同的会话,可以点击文件菜单-->新建会话菜单项,使用这个方式,新创建的窗口将采用一个新的会话,以便和之前的会话区分开来。

4、为什么有时候IE8 Tab进程在访问的页面关闭以后,Tab进程还是存在呢?

这是为了性能考虑的,防止用户马上又新开一个窗口,前面说过创建一个Tab进程是需要很多资源的。在默认情况下,IE8的Tab进程在网页窗口关闭以后,将驻留60秒时间,然后再退出。当然,我们也可以通过设置注册表 HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main下的TabShutdownDelay DWORD键值来控制Tab进程的退出时间。注意:TabShutdownDelay的单位是毫秒(1秒等于1000毫秒)。


文末:

IE8相对于IE7来说,无论是进程框架和渲染引擎都得到了极大的改善和优化,而且在各种标准支持方面都比IE7好了不少,虽然IE8不是最快的浏览器,也不是应试分数最好的浏览器,但是无论是兼容性还是安全性方面,都是值得大家去安装的。如果你是因为受不了IE7的慢而使用FireFox或Chrome浏览器的,现在可以再体验一下IE8,相信会比IE7有着明显的改善的,呵呵。

下回,我将继续对Windows 7的一些核心组件撰文,继续分享Smallfrogs对于Windows 7的研究结果。敬请期待。

发表于 作者 smallfrogs | 3 评论

[Win7] Windows 7 相关研究心得分享启动了

张康宗(Smallfrogs)
http://www.KZTechs.com

由于工作原因,沉默了很长一段时间了,估计很多人都忘记我了吧,呵呵。

在这段时间里面,业界经历在翻天覆地的变化,而Windows也在翻天覆地的变化着,在Windows 7 RC 即将发布之际,我将把近期对 Windows 7 的一些研究心得给大家分享一下,从蛙眼的角度看看 Windows 7 到底有哪些变化。

整个系列文章会比较长,我所关注的重点是兼容性方面的内容,因为这也是我工作中所接触最多的一些点,大部分内容已经经过确认,但是少部分内容是我推测出来的,如果文章中有错误,请大家指出,谢谢。

第一篇:Windows 7 研究——IE8 松散耦合进程框架探索(2009/04/20)

第二篇:Windows 7 研究——MinWin 初步探索(2009/06/01)

BTW:这篇博文将持续更新,把最新的相关文章的链接加入进来。

发表于 作者 smallfrogs | 1 评论

WinSxS 混乱导致的应用程序不能启动

张康宗(Smallfrogs)
http://www.KZTechs.com

有人看过下面的MessageBox提示信息吗:

---------------------------
C:\dllsxstest.exe
---------------------------
C:\dllsxstest.exe

由于应用程序配置不正确,应用程序未能启动。重新安装应用程序可能会纠正这个问题。

---------------------------
确定  
---------------------------

 

如果看到这个错误,那么一定是因为运行库的manifest混乱或破坏导致WinSxS机制无法正常使用从而引起应用程序加载失败。

从Windows XP开始,微软引入了WinSxS机制用于解决DLL版本冲突的问题。解决方法是通过一个额外的清单文件(manifest)记录所需要的运行库的版本号等信息。进程创建的时候,CSRSS进程通过SxS.DLL模块解析manifest文件,然后加载合适的DLL版本。

今天,我这里处理了一个WinSxS版本混乱导致的应用程序无法加载的问题。

环境如下:

  • 有一个EXE文件,不依赖任何的运行库
  • 有很多DLL文件,分别在EXE文件目录的子目录下
  • EXE文件所在目录下有一套安装的VC8运行库
  • DLL文件需要依赖VC8运行库
  • 因为各种原因,没有使用 vcredist_x86.exe 把VC8运行库安装到Windows\WinSxS目录下面

使用的时候发现,EXE文件加载DLL的时候,总是提示加载失败。DLL无法启动。我用 Process Monitor 监视了一下文件的读写操作,发现EXE文件在加载DLL的时候,CSRSS总是去读取 Windows\WinSxS 目录下的运行库文件,由于没有使用 vcredist_x86.exe 把VC8运行库安装到Windows\WinSxS目录下面,因此DLL加载失败了。

我很奇怪的问题是,为什么总是忽略了EXE目录下的manifest文件,而总是使用 Windows\WinSxS 目录下的文件呢?

以前知道manifest文件可以外置,也可以内置到PE文件的资源里面,难道是内置的问题吗?用Resource Hacker打开DLL文件,果然发现了内置的清单文件。把这个资源结点删除以后,保存退出,然后再使用EXE文件加载这个DLL文件,OK~问题解决了。这次使用的是EXE目录下的运行库文件而没有使用Windows\WinSxS目录下的文件了。

BTW:对于开发人员来说,自然不能编译以后再手工删除这个资源结点,解决方法很简单,把工程的manifest设置里面的 embedded manifest 功能关闭掉,这样编译以后就会出现编译生成的目标文件和一个额外的manifest文件。使用的时候,系统会首先尝试到Windows\WinSxS目录下面寻找文件,如果文件不存在,那么会在EXE文件所在目录下寻找,而不是去DLL所在目录下寻找文件。

问题解决以后,就需要想想问什么只有在部分系统上面出现这个问题了,检查发现:没有问题的系统都使用vcredist_x86.exe 把VC8运行库安装到Windows\WinSxS目录下面了,有问题的系统,发现WinSxS目录下没有运行库文件,自然不能使用了。

目前,很多软件都使用了VC8开发,而且都使用 vcredist_x86.exe 把VC8运行库安装到Windows\WinSxS目录下面,但是有某些软件在卸载的时候,又把这个运行库卸载了,结果就会导致类似提示“由于应用程序配置不正确,应用程序未能启动。重新安装应用程序可能会纠正这个问题”的错误的出现。这是最常见的一种现象。另外还有下面的几种可能会导致WinSxS混乱:

  • manifest文件被破坏
  • 复制了错误的manifest文件到错误的目录,导致manifest文件里面记录的内容和实际的DLL版本不符

最后,如果你碰到提示“由于应用程序配置不正确,应用程序未能启动。重新安装应用程序可能会纠正这个问题”,最佳的操作方法是看看这个文件依赖的运行库是否齐备,如果不会看,最简单的办法就是重新安装所有的运行库版本到系统里面。

下面是所有常见的32位运行库版本的下载地址:

如果你不知道你使用的程序是什么版本开发的,那么就全部安装吧,嘿嘿~

BTW:WinSxS 技术从 Windows XP 开始引入,一直发扬到 Windows Vista 系统里面,表现形式就是随着系统使用时间的增加,Windows\WinSxS 目录会越来越大,这一点在 Windows Vista 系统里面会特别突出,因为 Windows Vista 系统的系统文件都是使用 WinSxS 目录存放的,Windows\System32 目录下看到的大部分文件实际上是 WinSxS 目录下文件的一个 Hard Link 而已 :)

发表于 作者 smallfrogs | 13 评论

Windows Vista RTM BUG?

今天同事反映,我们内部开发的自动化测试平台的一个案例驱动模块在 Windows Vista RTM 机器上发生了一个奇怪的现象,同样的代码在其他的Windows 2000、XP、Server 2003、Vista SP1 上面均工作正常,但是在 Vista RTM 系统上面没法工作。

问题现象是:

  • 我们首先使用 CreateDirectory API 创建一个目录
  • 然后对这个目录使用 FSCTL_GET_COMPRESSION 控制码设置NTFS压缩属性
  • 然后在这个目录下面建立子目录
    • 由于父目录已经设置了压缩属性,因此子目录也继承了压缩属性
  • 对子目录使用 FSCTL_GET_COMPRESSION 控制码取消NTFS压缩属性
  • 结果发现在 Windows Vista RTM 机器上面取消子目录 NTFS 压缩属性的时候 DeviceIoControl API 返回成功,但是实际结果是没有被解除压缩属性。

我把这段代码抠出来写了一个小程序,在下面的操作系统上均进行了试验:

    • Windows 2000 SP4
    • Windows XP SP1
    • Windows XP SP2
    • Windows XP SP3
    • Windows Server 2003 SP1
    • Windows Server 2003 SP2
    • Windows Vista RTM
    • Windows Vista SP1

发现只有 Windows Vista RTM 系统有这个现象,其他系统均是正常的。而且发现,如果设置压缩属性完成以后,把进程退出,然后再启动一个新的进程用于取消压缩属性,也可以达到预期的效果。但是如果操作是在同一个进程里面,那么问题就肯定出现。

鉴于只有Windows Vista RTM 有这个现象,难道是 Windows Vista RTM 的 BUG?

备注:

  1. Windows Vista 已经关闭了UAC
  2. 系统是一个干净系统,没有安装任何的第三方软件
  3. 登录帐户隶属于 Administrators 组,且机器没有加入域
  4. 使用资源管理器做同样操作没有这个现象

由于 Microsoft 没有公布非常详细的 Windows Vista SP1 Changes Log,因此我只能猜测是 Windows 的 BUG 了。但是为啥资源管理器不受影响呢?抽空debug一下看看,也许就知道具体原因了。

最后,还是强烈建议升级到 Windows Vista SP1,不仅仅是改善了性能,在兼容性方面也有很多修正和改善。

发表于 作者 smallfrogs | 2 评论

RTX 2008 Beta 1 导致 Windows Vista 无法使用 Run as administrator 命令

张康宗(Smallfrogs)
http://www.KZTechs.com

昨天晚上的时候发现,当右键点击Windows Vista的开始里面的快捷方式,选择 Run as administrator 命令的时候,没有UAC提示框弹出,而且consent进程也没有工作。由于这个功能对我非常的重要,立即开始调查。

调查结果如下:

  • 所有的 LNK 文件均无法通过右键 — Run as administrator 方式启动
  • 控制面板里面的“Change Product Key”点击无效
  • 控制面板用户帐户里面的“Change My Environment Variables”点击无效
  • 控制面板用户帐户里面的“Configure Advanced User Profile Properties”点击无效
  • ……
  • 实际上所有和LNK相关的内容,只要是以Run as administrator 方式启动的,都无效,包括使用 Windows API ShellExecute (关于如何使用 ShellExecute 以 run as administrator 方式启动程序,请见《如何将自身进程运行为admin模式》一文)。

看到这个现象,用其他的文件试了试,很正常,因此感觉不是系统内核层面上的问题,而仅仅是LNK文件的文件关联或相关的Shell内容出现错误。

首先检查的是LNK的文件关联数据,但是和原始的数据对比以后,发现没有异常,只不过多了一些软件自定义的Shell扩展。

启动 Process Monitor,对 Explorer.EXE 的行为进行监视,由于内容太多,一时半会找不出头绪,好像没问题……不过没有发现有consent.exe进程创建的记录,因此可以肯定是explorer相关的问题导致的。

再仔细观察了一下LNK文件右键菜单里面的内容,发现一个新增的项目:用RTX发送文件,而且这个项目和Run as administrator 在一组,难道是他?

刚好以前自己写过一个Windows Shell Menus Manager(http://www.kztechs.com/cxtmgr),用它看了看RTX相关的内容对应的文件是 c:\Program Files\Tencent\RTXC\RTXShlMenu.dll,用regsvr32 /u “c:\Program Files\Tencent\RTXC\RTXShlMenu.dll” 命令反注册以后,再次在LNK文件上点击右键,选择 run as administrator,哈哈,UAC弹出来了。

有问题的RTX文件信息:

File Name: RTXShlMenu.dll
File MD5: E61212BD331A32CA86D6B7B81812EB29
Common File Version: 1.0.0.1
Compile Time: 2008.03.21, 09:31:19 [GMT]
Digital Sign: NO

 

安装包信息:

File Name: RTXC2008Beta01(8.0.050.201).exe
File MD5: 8C334C845B6D590E740C90356DAF2EB2
Common File Version: 8.0.50.201
Compile Time: 2007.04.09, 07:44:33 [GMT]
Digital Sign: Yes.
Signed by [Tencent Technology(Shenzhen) Company Limited]

 

希望这篇帖子能够帮助碰到类似问题的人,提供一些思路吧。

发表于 作者 smallfrogs | 5 评论
归档在:

一个奇怪的不能搜索的现象

今天有一个同事的电脑上出现了问题,表现为不能搜索特定文件服务器上的文件,详情如下:

文件服务器FS和本地客户端是通过VPN连接的(不在一个物理地区),文件服务器的操作系统应该是Windows Server 2003(未经证实)。

在客户端这边,有一台XP系统,访问文件服务器FS的一个共享目录Share,访问方式是直接使用内网的IP访问,登录帐号是一个域帐号,域控制器在文件服务器所在的物理地区。

现象是这样的:

  1. 机器A使用Explorer,在地址栏输入\\IP\Share ,登录以后,Explorer 能够列举出共享目录里面的所有文件,而且很正常。
  2. 但是列表以后,点击机器A的Explorer的搜索按钮,文件名里面输入任何内容,点击搜索,都会返回搜索到0个文件。
  3. 把文件服务器FS的共享目录映射成一个驱动器,在机器A里面的命令行下面使用dir /s 命令搜索,没有问题。但是使用机器A的Explorer搜索隐射盘还是返回0个文件。
  4. 使用机器A的Explorer搜索本地磁盘里面的文件,一切正常。
  5. 使用机器A的Explorer搜索本地局域网里面的文件,一切正常。
  6. 换一台XP机器B,使用同样的访问方式、同样的域帐号访问文件服务器FS的共享目录,使用Explorer的搜索功能搜索,也很正常……
  7. ……

折腾了半天,没有搞定。比较奇怪,先记录下来,等有空的时候研究看看 Explorer 的搜索和普通的文件遍历有啥特别之处……

简单看了看机器A的环境,很普通,没有什么不正常的,我抓狂了……

发表于 作者 smallfrogs | 1 评论
归档在:

捉鬼记:深入 Norton UAC Tool 实现原理

张康宗(Smallfrogs)
http://www.KZTechs.com

刚刚看到 Asuka 的一篇文章《Norton UAC Tool原理剖析》,文章中已经很好的解释了Norton UAC是如何做到 Don't ask me again的,从开发的角度上看,这个要实现不是很难,但是我感兴趣的地方是: Norton 是如何把 Microsoft 的 Consent.EXE 给截获的,如果能够截获 Consent.EXE,就很容易实现 Norton 的功能了。

下面就让我带领大家深入这个工具的实现细节吧:

  1. 下载安装过程很简单,不停的Next就可以了。

  2. 安装完成以后,我找了一个会启动 UAC 的软件试了试,果然出现了 Norton 的 UAC 提示框。Microsoft Windows Vista 的那个 UAC提示框不见了。当时很诧异!!

  3. 当 Norton UAC 提示框正在询问的时候,用 Process Explorer 看了看进程,惊讶发现 Process Explorer 进程列表里面显示的是 Symconsent.EXE,但是这个进程的相信信息里面 Image 指向的是 Windows Vista 的 Consent.EXE。惊讶~~!

      

    发现上述的内容,Smallfrogs 第一反应是想到碰到鬼了~
    但是根据 Smallfrogs 多年的经验分析,得出这个“鬼”一定是人为的。看来 Norton UAC Tool 这个东东有搞头,于是乎马上振作精神,开始进一步的分析。

  4. 启动 Process Monitor,开始检测进程的创建过程,果然,鬼情出现了:在触发 UAC 的时候,Consent.EXE 进程加载的时候,Consent.EXE 会执行一个 LoadImage 动作,但是发现 LoadImage 对象不是 system32\consent.exe,而是 system32\symconsent.exe,如下图:

     

    这是一个非常重要的现象,根据这个现象,Smallfrogs 当机立断,有东东做了 Hook。

  5. 使用 Image File Execution Options 技术,对 consent.exe 设置了调试器通知,确认在触发 UAC 的时候,系统的确调用了 consent.exe 进程,而且进一步发现,调试器模式下,挂接 consent.exe 进程以后,Norton UAC Tool 的提示框没有出现。

    Smallfrogs 当时想:这只鬼很神奇啊~~难道要逼迫 Smallfrogs 做复杂、烦琐的内核调试吗?Smallfrogs 环顾四周,周围只有一台用了2年的本本,看来又要伤机器了。

  6. 正在准备开启VMWare的时候,Smallfrogs 突然想起忘记看看安装程序做了什么事情了,于是乎对安装程序 NUACx86.exe 进行了一个简单的分析,发现不就是一个普通的EXE嘛,而且这个EXE不是 symconsent.exe,看来这个EXE 有隐藏的东东。在 Exescope 的帮助下,果然发现 NUACx86.exe 有附带几个资源二进制文件,解出来一看,哈哈,这只鬼终于现身了。

    Norton UAC Tool 安装了一个文件过滤驱动,叫做 SymAFR,当然,这个驱动通过了 Microsoft WHQL 认证(这只鬼做的还挺标准的),数字签名日期是 2008年2月29日 22:47:48。驱动的文件名叫做 SymAFR.sys。

    Norton UAC Tool 可能是这样实现的(有不对的地方请大家指正):

    1、当 UAC 触发的时候,Windows Vista 尝试加载 system32\constent.exe。

    2、SymAFR.sys 截获了这个操作,然后转而让系统加载 symconstent.exe。

    3、symconstent.exe 成功的代替了 Windows Vista 的 constent.exe 进程,后面的事情就简单了。

    4、验证方法很简单,执行 sc stop symafr 命令以后,再看看你还能够看到 Norton UAC Tool 的提示吗?呵呵。

Smallfrogs 评论:恩,这是一个非常巧妙的方法!实现简单,稳定,有效~

注意:Norton UAC Tool 是会把每一个触发 UAC 的程序的信息上报给 Norton 信息收集中心的。

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

20080916 Update:

1、原文写的是 IEFO 劫持技术为笔误,实为 IFEO,即 Image File Execution Options
2、Exescope 是一个查看资源文件的工具,类似的还有 Resource Hacker 等
3、细心的朋友会发现,我的第一副截图里面的参数和 Asuka 的截图的参数不一样,他的截图里面指向的是一个 XML文件,针对这个问题,我做了一些分析,发现:当Norton UAC Tool 出现的时候,如果点击 Cancel,会创建一个新的 Symconsent.exe进程,新的进程的参数就是 Asuka 发现内容。新创建的 Symconsent.exe 进程应该是用于上报数据用的。感觉Gdier的报告!!Smile

磁盘碎片整理以后出现 BOOTMGR is missing

昨天 的文章里面,我提到我的系统在处理 MFT 表的时候用了近10秒钟时间,怀疑和磁盘碎片有关。虽然我一直在定期的对磁盘碎片进行整理,但是之前整理完成以后都没有测试过实际的用处。这次有了xperf工具,能够更准确的分析数据了。

由于涉及MFT相关的内容,而系统自带的工具是不能够整理MFT表的,因此我安装了 Diskeeper 2008,用这个软件对MFT进行整理。

Diskeeper 2008 的磁盘碎片整理是用一个 Native 应用程序实现的,启动时间应该是在 smss.exe 启动之后,Win32子系统启动之前。整理的过程很顺利,整理完成以后,系统重启,结果一重启,就提示我:

“BOOTMGR is missing, Press Ctrl+Alt+Del to restart”。

Bootmgr 是 Windows Vista 引入的一个新的引导组件。很明显,我的引导程序坏了。也就是说 Diskeeper 的 Boot Defrag 弄坏了 BootMgr 相关的记录信息。因为我使用的是 MFT 整理功能,看到这个提示以后,非常担心 MFT 表损坏。因为一旦 MFT 表损坏,整个系统盘的数据就丢失了。

解决方法:

  1. 找来一张 Windows Vista 安装光盘,用这个安装光盘引导机器
  2. 选择自动修复
  3. 经过漫长的等待以后,修复完成,提示重启
  4. 拿出光盘重启,熟悉的 Windows Vista 启动界面出现了……

弄完以后,我又搜索了相关的记录,发现还是有不少人出现了这个类似的现象。导致的原因大部分是因为使用了 Diskeeper 的 Boot Defrag 功能对MFT进行整理,最不幸的人是整理以后真的导致 MFT 损坏,结果C盘无法访问了……

这个软件的这个BUG真的很可怕……以后再也不使用这个功能了。

发表于 作者 smallfrogs | 7 评论
归档在:,

Windows Vista 性能分析:如何使用 xperf 获取精确的启动性能数据

张康宗(Smallfrogs)
http://www.KZTechs.com

最近一段时间,我笔记本上Windows Vista的启动速度越来越慢了,启动时候的滚动条需要滚数十圈才能完成,而到 Explorer 显示完桌面,系统启动全部完成,需要4分多钟,已经慢的不可忍受了。本想重装系统,但是重装的代价也太大了,我需要重新配置太多东西,于是乎我就想如果找到启动性能的关键瓶颈,对这个瓶颈进行优化以后应该能够解决一些问题。

要解决问题,就需要准确的收集相关的性能信息,我们知道,在Windows XP时代,可以使用 Bootvis 工具收集相关的信息。

Bootvis:一个专门用于收集和分析 Windows XP 启动速度的工具。曾经很不幸的被错误的认为是 Windows XP 的启动速度优化工具。

但是由于 Windows Vista 内核体系的变革,加上全新的引导模式的引入,BootVis 肯定是不能胜任的,看来需要找到一个更好的获取 Windows Vista 相关性能数据的办法了。

Microsoft Windows Performance Toolkit(简称xperf),一个全新的Windows 性能分析工具在这个时候走入我的视线。

Microsoft Windows Performance Toolkit 是微软最近一段时间内推荐的丈量 Windows 性能的一个全新的工具,适合于 Windows Vista 或更高版本。最新版本是 4.1.1.1,可以在 http://www.microsoft.com/whdc/system/sysperf/perftools.mspx 免费下载到。

安装 Microsoft Windows Performance Toolkit 的过程非常的简单,安装完成以后,就需要开始收集相关的性能数据了。本次我关注的是 Windows Vista 的启动速度,因此我需要收集的是Boot阶段的数据。

用管理员模式启动 cmd.exe,然后进入 Microsoft Windows Performance Toolkit 安装目录,输入下面的命令:

xbootmgr.exe -trace boot

输入这个命令以后,xbootmgr 会自动重启系统,然后开始收集相关的启动信息数据。重启完成以后,xbootmgr 会等待 explorer 全部启动完成以后,生成一个日志文件(扩展名是:etl)到 Microsoft Windows Performance Toolkit  安装目录下面。下面我们需要对这个文件进行分析。

分析的过程有很多方法,最简单的方法就是进入命令行模式,切换到 Microsoft Windows Performance Toolkit  安装目录下,输入 xperf -i boot_BASE+CSWITCH_1.etl -o boot.xml -a boot 命令自动分析,然后输出一个 xml 的报告文件。这个

下面我要说的是一个更细致的分析过程。

  1. 打开 etl 文件:使用 xperfview boot_BASE+CSWITCH_1.etl 命令,会调用 xperfview 工具对 etl 文件进行详细的解析。etl 文件是 Microsoft Windows Performance Toolkit 原始的性能数据文件,里面记录了所有收集到的数据。
  2. xperfview 解析完成以后,会看到类似于下方的图片:
    parse1 
    找到 process lifetimes 分类(如上图),会发现到50多秒的时候,系统里面的第一个用户态进程smss.exe才启动(进程ID:748),之前的时间都花费在 system 上。换句话说,运行在内核态的各种驱动程序,包括 Windows 内核和执行体用了 50 多秒才完成启动子系统之前的初始化动作,这个时间花费的也太长了。
  3. 由于初始化 Windows 内核和执行体等动作用了 50 多秒,这个非常的不正常,因为我们需要看看在这50秒内的详情。

    在 Disk Utilization by process 里面,选择 0-50 秒这个时间段:
    parse2 
  4. 然后点击鼠标右键,选择 Detail Graph,会出现下面的图:
    parse3 在这个图片里面,可以看在 0-50 秒内磁盘访问最高的区域是什么,C盘中间部分的访问频度非常的高。更细致的数值分析就需要使用另外一张报表了。
  5. 在 Disk Utilization by process 里面,还是选择 0-50 秒这个时间段:点击鼠标右键,选择 Summary Table,xprefview 会显示如下图所示的报告,这个报告对于分析性能分析来说,会显得会更为直观一点。

    parse4 
    这张图标给了我们一个非常详细的性能分析和解释数据。在 0-50 秒时间内,system 进程花费了 42445587.434 us 的时间,其中,花费最多的时间是在处理 MFT 表的时候,尽然用了近10秒的时间。
  6. 根据上面的数据,我们已经找到了在启动最开始的50秒时间内,有10秒钟的时间花费在了出来MFT表上面,另外,读取一些字体文件的时间也非常的慢。
  7. 知道数值以后,后面就是优化过程了。根据 xperf 给出的数据初步判断:开机慢的原因和文件IO速度变慢是相关的。有人会问,而影响文件IO速度慢的原因有很多,但是请注意一点,在前50秒内,由于没有任何的用户态进程介入,因此IO速度慢的原因就很简单了,大部分原因是因为磁盘碎片导致的,也有可能是由于硬盘坏道导致的。根据 xperf 的数据,处理MFT表用了10秒钟时间,如果能够把MFT的处理时间加快,同时减小碎片数量,系统的启动速度就能加快不少了。

在进行系统性能优化和分析的过程中,数据的收集是至关重要的。业界有很多性能数据收集工具,Microsoft也出了不少类似的软件,但是易用性都不是很好。Microsoft Windows Performance Toolkit 作为一款新型的面向于Windows Vista 或更高平台的性能工具,以其简单的操作和友好的界面,希望能够得到更多的使用和更广泛使用。


在本次的 Windows Vista 性能分析里面,我介绍了一个使用 xperf 对Windows Vista 启动速度进行分析的过程,在后续的 Windows Vista 性能分析系列BLOG文章里面,我还会持续关注在更多的和 Windows Vista 性能相关的话题上面,希望能够让大家对 Windows 性能有一个更好的认识。

IE8 新特性分析:IE8的稳定性源自何处

MS宣称IE8增强了很多稳定性方面的改进,今天我抽了点时间,对这个问题进行了一个分析。

 

从Windows 2000开始,Windows提供了一种新的机制对多个进程进行统一的管理。这种机制被命名为Job(作业)。作业的一个最大特点是能够对一个进程组进行统一的管理。

对比之前IE版本的多标签页实现,之前版本的每个Tab页是基于线程的方式进行的,这种方式最大的问题是一旦某一个线程发生问题,整个IE进程都会出现问题。而且这种问题是很难彻底解决的。在IE8里面,MS终于把Job(作业)的思想进行了一次比较大规模的运用,每一个(或几个)Tab页会对应一个进程,然后有一个总的进程进行管理(如下图)

job

 

这种设计的好处就是一个Tab崩溃以后,只会影响这个Tab,对于其他的Tab是不影响的。同时,最外面的框架进程能够知道子Tab的情况,也就能够很好的实现“灾难恢复”了。

下面是父框架进程和子进程的启动参数的不同,可以看到,Job里面的进程是通过一些特殊的参数进行启动的。

job2

当然,IE8的这种结构也带来了一些问题:

  • 从开发的角度上看,带来的最大问题就是进程间的通信和管理问题,不过我相信,这一点对于恐龙级别的MS来说是小菜一碟了。
  • 从用户的角度上来看,进程对资源的消耗还是很大的。换句话说,同样的浏览模式,IE8对内存资源的消耗应该会大于IE7或者更早的版本。换来的好处是更加的稳定。

IE8,Good!

Smallfrogs
http://www.KZTechs.com

发表于 作者 smallfrogs | 18 评论

Hyper-V 网络故障存档

上周,我在公司环境里面部署的2台Hyper-V RTM服务器里面,有一台出现了问题,问题现象是:虚拟机里面的网卡无法从DHCP服务器获得IP地址,在虚拟机里面使用 ipconfig /renew 命令,报告无法找到 DHCP 服务器,重启虚拟机也无法解决问题。

整个过程是这样的:

  1. 我的一台基于Realtek 网卡的Hyper-V服务器外接的交换机出现问题,导致Hyper-V服务器断网了,同样,Hyper-V里面运行的虚拟机的网络也断了。这台Hyper-V服务器和里面的虚拟机的IP获取方式均是通过外部的DHCP服务器获取的。
  2. 经过数十分钟以后,网络恢复了,Hyper-V服务器的网络恢复正常,但是奇怪的是,3台虚拟机里面的网络都未能恢复。
  3. 我先怀疑是虚拟机的问题,于是用ipconfig/renew命令和重启,均未能维护网络。
  4. 由于Hyper-V服务器上还运行着其他自己编写的服务端程序,不能重启系统,于是我重启了Hyper-V的网络管理服务,结果无效。
  5. 最后不得已,我重启了Hyper-V服务器,重启以后,虚拟机里面的网络终于恢复了。

由于当时的时间很紧,我没有研究具体的原因,仅仅是找到了一个解决方法,今天把过程记录下面,大家可以看看具体原因是怎么回事?我目前也不知道。只不过感觉和网卡有关,因为我另外一台使用的是Intel网卡Hyper-V服务器,就没有碰到类似问题。

发表于 作者 smallfrogs | 5 评论
归档在:

AppInit_Dlls,一个特殊的注册表键值

Smallfrogs
http://www.KZTechs.com

如果你对计算机安全有所了解,那么各种各样的注册表启动项应该会有所了解,今天我会细述一个很著名的启动项:AppInit_Dlls键值。

AppInit_Dlls键值位于注册表 HKLM\Microsoft\Windows NT\CurrentVersion\Windows下面,相对于其他的注册表启动项来说,这个键值的特殊之处在于任何使用到User32.dll 的EXE、DLL、OCX等类型的PE文件都会读取这个地方,并且根据约定的规范将这个键值下指向的DLL文件进行加载,加载的方式是调用 LoadLibrary。

验证方法有很多,最容易想到的就是使用调试器,在LoadLibrary调用的时候下断点,你会发现User32.DLL读取了这个键值并且使用了LoadLibrary去调用这个键值指向的DLL文件。一个更好的方法就是看看 KB197571 的介绍了。

AppInit_Dlls的键值是一个非常危险的键值,从某种程度上来说,这是一个Windows最容易被人利用的漏洞,因为只要有任何的恶意软件在这里进行了修改,那么就意味着任何使用到User32.DLL的进程都会被AppInit_DLLs指向的DLL所注入。因为进程内部的DLL是共享整个进程空间的,因此意味着进程里面的DLL是可以控制整个进程的行为的。由于User32.DLL是一个非常非常通用的DLL,它提供了大多数Win32用户界面、消息相关的功能,只有极少数的程序不会使用User32.DLL,因此一旦有恶意软件修改了AppInit_Dlls键值,那么整个系统都有可能处于非常危险的状态。

众所周知,Windows服务程序的启动时机是可以非常早的,往往在用户登录之前就完成启动了,而这个时候最常见的Run键值还不一定被处理完,而且Windows服务程序拥有相当高的权限(默认是Local System,可以对系统里面所有的资源进行操作),因此如果一个恶意软件被加载到Windows服务里面,那么是会非常危险的。前文提到,任何进程使用了User32.DLL,都会对AppInit_Dlls键值指向的DLL进行加载,如果是一个Windows服务程序,也不例外!

由于AppInit_Dlls是一种系统全局性的Hook(system-wide hook),要规避此类的Hook的确很困难,虽然使用驱动程序进行保护能够规避此类问题,但也不是非要使用驱动程序进行处理的。前文说过,只有当使用到User32.DLL这个模块的时候才会触发读取AppInit_Dlls指向的DLL,如果不使用User32.DLL,那么AppInit_Dlls是不会被使用到的。但是要让一个程序不使用User32.DLL会变得非常困难(命令行窗口没有使用User32.DLL),因为任何的窗口、消息都和这个模块有关,为了保证有良好的用户体验,100%的窗口程序都和这个模块有关。从开发角度来说,最好的一种解决办法就是将程序功能逻辑和界面逻辑完全分离,功能逻辑模块负责功能,界面逻辑模块负责界面显示,2者之间采用IPC机制进行交互,功能逻辑模块不依靠User32.DLL,,而且作为独立进程进行处理,这样就可以规避AppInit_Dlls造成的Hook了。

类似的Windows安全相关的缺陷点其实还有很多的,这些缺陷点的来源是为了保证向下的兼容性。相信MIcrosoft已经发现并正在修补这些地方,从Windows Vista上可以看到,AppInit_Dlls的键值在Windows Vista上是不起作用的,因此在Windows Vista里面,这个键值已经被抛弃了(改用另外一个键值执行类似的功能,但是增加了基于UAC的安全防护)。

Hyper-V RC1 升级补丁安装记

惭愧啊,本blog很久不更新,都长草了。

最近几个月实在忙得厉害,今天抽出1个小时更新一下最近的流水账吧。

由于工作环境的需要和出于对新技术的追求,最近我一直在研究基于硬件级别的虚拟机,说是研究,实际上还停留在很肤浅的应用层次。研究的对象是 Windows Server 2008 里面的Hyper-V虚拟机组件。

由于今天时间的关系,关于Hyper-V虚拟机组件的一些心得今天就没有时间和大家分享了,今天提及的问题是关于 Hyper-V RC1 升级补丁的安装问题。

Hyper-V RC1 补丁放出来很长一段时间了,我在发布的第2天就下载并进行了安装,安装过程进行了重启,重启以后,当时我很惊讶的发现虚拟机启动的时候还是显示着 RC0 的字样,当时我猜想是不是MS的显示错误,也就没有多关注,认为我已经把Hyper-V RC1补丁安装成功了。

但是今天我检查 WindowsUpdate 日志的时候,居然发现有一个Fail。一查,居然是在安装 Hyper-V RC1 的时候报告的安装失败。错误代码是:0x80070020。

既然安装失败了,那好,我再来安装一次,运行RC1安装包,一切正常的操作结束以后,重启以后发现还是提示安装失败,比较奇怪哦。

第二次尝试,把正在运行的2个虚拟机关闭,运行RC1安装包,一切正常的操作结束以后,重启以后发现还是提示安装失败,大惊。

算上第一次的失败,安装Hyper-V RC1升级包连续失败了3次了,好奇心油然而生,我就不信我搞不定这个补丁的安装。也罢,祭出本人法宝:Microsoft Exchange Server Error Code Look-up Tool,查询看看 0x80070020 错误号代表的字符串含义,查询到的结果是 STIERR_SHARING_VIOLATION,恩,共享违例。

知道错误号的详情以后,我就知道安装失败的原因了:安装的时候文件没法替换成功。解决方法也很简单:

  1. 关闭虚拟机;
  2. 停止Hyper-V相关的3个服务;
  3. 将上述3个服务的启动类型从自动改为手动;
  4. 运行Hyper-V RC1 升级包安装

执行上述操作以后,重启以后,哈哈,成功升级到Hyper-V RC1,然后再把3个服务启动类型设置为自动,启动这3个服务,启动虚拟机,一切恢复正常。

再回过去看看KB知识库的描述 KB450049,上面写的是:

...

All virtual machines must be shut down correctly before you install the Hyper-V Release Candidate 1 update

...

仅仅执行上述操作好像不行啊,不知道这篇KB的作者有没有自己尝试过呢?呵呵。

顺便抱怨一点的是,Hyper-V虽然提供了上层和底层两套API接口,底层的接口层次太低了,我不需要这么低的,而对于上层的接口,功能不够,虽然是基于WMI的,但是我跟喜欢纯C的接口类型,不知道是否是因为我跟不上时代的进步了。

BTW:Hyper-V RC0 挺稳定的,我的测试环境部署了2套虚拟机(Windows XP SP3 和 Windows Vista SP1),每天这2个虚拟机里面的工作环境会执行非常复杂的任务,每天需要从6:00——24:00连续执行任务,而且有大量的重启任务和高负载任务,但是经过这么多天的试用,运行Hyper-V机器没有发生过任何的不稳定情况,还是很不错的。

下次,我会进一步把现阶段学习到的知识分享给大家,时间上我尽可能在近期完成吧,敬请期待。

Smallfrogs
http://www.KZTechs.com

发表于 作者 smallfrogs | 1 评论
归档在:

Microsoft Windows Vista UAC 之数字签名认证

Smallfrogs[张康宗]
http://www.KZTechs.com

2007年12月份的时候,我曾经撰写过一篇文章《Windows Vista UAC 和 可信任安全》(http://blogs.itecn.net/blogs/smallfrogs/archive/2007/12/31/windows-vista-uac.aspx)。文章中对4种UAC提示框分别作了一个说明,今天,我们继续这个话题,说说UAC提示框里面的数字签名认证部分的内容。

Windows Vista里面数字签名认证对于用户层和内核层是不同的,这一点我提前说明一下。

众多周知,UAC的用户态提示框是consent.exe进程触发的。UAC提示框会检查进程的数字签名信息,对于被信任的进程会显示绿色(系统模块)或者灰色(有数字签名的第三方模块),对于未知的数字签名信息显示黄色,对于被阻止的数字签名信息显示红色。

那么Windows是如何检测数字签名的呢?实际上,Windows内置了很多受信任的根证书,只要使用这些根证书对文件进行数字签名签署操作,就可以让Windows Vista这个文件所信任。

KZTechs.COM - FileDigitalSignVerify工具扫描Windows Vista Windows目录,会发现所有的系统文件都是有数字签名的,签署者可能是 Microsoft Windows,也可能是 Microsoft XXX。对于使用Microsoft Windows证书签署的模块,UAC提示框一定是绿色的。如果不行,可以运行 regedit.exe 看看 ^_^

但是,有一个特例:IExplore.EXE。如果你用 Run as Adminisrator 方式启动IExplore.EXE,你会看到一个黄色的UAC提示框。

难道是IExplore.EXE没有数字签名?不,IExplore.EXE也有数字签名的,用KZTechs.COM - FileDigitalSignVerify (http://www.kztechs.com/filedsv/)工具可以清楚的显示数字签名相关信息以及证书链信息。

下图是使用 KZTechs.COM - FileDigitalSignVerify 工具 1.2 版本对 regedit.exe和iexplore.exe这2个文件的数字签名信息进行检查:

Capture

绿色部分是对iexplore.exe检查的结果,下半部分是对regedit.exe检查的结果。-p 参数是显示证书链信息。

从上图的证书链可以看到,这2个文件都被Microsoft Windows的数字签名所签署,而且证书是有效和合法的。而 Microsoft Windows 证书是由 Microsoft Windows Verification PCA 证书颁发的,而 Microsoft Root Certificate Authority 证书颁发了 Microsoft Windows Verification PCA 证书。Microsoft Root Certificate Authority 作为根证书,是被系统所信任的。

那么为什么以Run as Adminisrator 方式启动IExplore.EXE,你会看到一个黄色的UAC提示框?

Capture3

我用google进行了相关搜索,结果是:未知

难道是Microsoft BUG?

Smallfrogs
http://www.KZTechs.COM

更多内容 下一页 »