每天我们都在使用Windows系统学习、编程、听音乐、玩游戏,Windows的操作想来是很熟练了,可是你又对Windows到底了解多少呢?本系列的目的,就是让你对Windows系统有个更直观、更清楚、更彻底的认识。虽然我们大多数人看不到Windows的源码,对其内存调度算法这种最深层次的技术内幕不能明窥,但是我们可以做到比现在知道的更多,了解这些之后你会发现在Windows上面开发会轻车熟路,任何木马病毒到了你机器上不过只会成为你的试验品。
鉴于Windows 9X内核早已淘汰,技术过时,在此不予讨论。主要是针对Windows2000(Windows 5.0)以后版本,尤以2000为主。要知道xp是Windows 5.1版本,2003也才是5.2版本。那么,对于本系列提到Windows OS技术,统指Windows 5.X技术。
一、直观认识Windows
分析一个软件,最容易的入手方法就是先搞清楚它的每个文件都是干嘛的。我们先来让大家对自己正在使用的Windows 操作系统有个直观认识。请在你使用的Windows 2000或Windows XP上,于WINNT/system32或Windows/system32目录(系统目录)下,找到以下几个文件:HAL.DLL、NTOSKRNL.EXE、NTDLL.DLL、KERNEL32.dll、GDI32.DLL、USER32.DLL。这几个是Windows系统赖以执行的关键,只要你能在图形界面下操作Windows,这几个文件就肯定在发挥作用。值得一提的是Windows的图形界面子系统是在内核实现的(知道为什么Linux的图形界面怎么着都没Windows好看好用了吧)。
对这几个文件的功用给出简介如下:
HAL.DLL:Hardware Abstraction Layer,硬件抽象层。
Windows 2000也是一个软件系统,与我们平时从事的项目开发工作一样,项目初期需要确定开发目标。而Windows2000开发当初制定的开发目标之一就是要能够在多种硬件平台上移植(Windows2000支持单处理器、多处理器、Compaq SystemPro),不同的硬件平台上有不同的硬件抽象层实现。在我们通常使用的标准PC上这个文件就是HAL.DLL(在Compaq SystemPro上是HALSP.DLL,满足不同硬件平台的硬件抽象层文件在Windows安装盘上都有,安装时根据计算机的平台类型只复制相应的文件)。
HAL是可加载的内核模式模块(DLL动态链接库文件),它为Windows系统所运行的硬件平台提供低级接口。它隐藏硬件相关的细节,如I/O接口、中断控制器和多处理器通信机制等这些与特定硬件结构机密相关的内容,而向操作系统内核提供统一的硬件接口函数。
NTOSKRNL.EXE:NT OS Kernel,毋庸置疑,这就是Windows系统的内核,确切说内核是在这里面实现的,只有1.6兆,与目前Linux2.4版本内核编译后的大小差不多。
这个文件实际上提供两部分的主要的功能:
一是系统内核,这在硬件抽象层之上,提供系统的基本机制(线程调度和同步、内存分配等等一切你在操作系统原理书上可以看到的最复杂的那一部分,如果你觉得操作系统课程学得太抽象又有点跟自己过不去,试着把这个NTOSKRNL.EXE反汇编了读一读吧,不多,也就300多万行汇编码,只是找不着确切的入口点)。同时内核还提供硬件支持,实际上是将驱动程序等上层程序的调用对硬件进行具体化,反过来讲就是硬件抽象层再抽象一次,暴露给上层一个统一的接口,写过Windows驱动程序或是看过DDK的同学一定对Windows WDM驱动的固定编写模式有很深的印象。
二是执行程序(称为Executive)。这个执行程序的东东可真是多啊,我在捣腾的时候都有点让它搞得晕晕的,不过现在来看呢其实也就一句话:执行程序是开发者与Windows之间交互的窗口,再直观点说执行程序对外暴露Windows开发函数,经过几次封装后供开发者使用。我们先不管这些函数的功能分类,按功能分类的话东西有点多有点乱,容易让人puzzled。按开发者的角度来看,有这么几类:Win32 API函数,这是做应用开发用的,我们常说的MFC、ATL是对其进行的面向对象化及封装;DDK API函数和IFS kit函数,这是供驱动开发用的,DDK还耳熟些,不过如果你浏览过DDK并且够细心的话就会觉得奇怪为啥OS很重要的一部分——文件系统驱动的开发没有提供,IFS(Installable File System) Kit就是做这个的啦。
我们前面说过Windows把图形界面处理放在了内核态来执行,因此不得不提一个比较特殊的驱动:Win32k.sys,你看到的漂亮的Windows桌面就是这个文件画出来的。
讲到这里,前述内容是Windows系统在内核态运行的基本功能,也就是说,这是运行于CPU ring0级别的(不懂什么是ring的话赶紧去Intel的网站download Intel CPU的系统开发参考看,甭翻你手头的微机原理课本了,那上面没有)。还有一大堆驱动也是运行在这个级别。在内核级别上,组件之间功能的调用等等与用户态不同,常用的是LPC,这个我们以后慢慢再讲。
继续下面的内容之前,要先说明一点事实:Windows的功能比我们平时所见的要强大的多。通常我们讲Win32,实际上这只是Windows的一个子系统而已,Windows还有另外的两个子系统:POSIX和OS/2。这么一说的话似乎Linux上的程序可以在Windows上运行了,其实没那么简单,还需要移植库以及重新编译连接,最终还得依赖Win32子系统的实现来完成其功能,意义不大,基本上算是被用户们喀嚓掉了吧,我们也是只讲Win32子系统。点明一点:不同的子系统有专门的子系统支持环境,POSIX子系统是POSIX.EXE,Win32子系统是Csrss.EXE(全称是Client/Server Run-time SubSystem)。所以,你的机器上总有Csrss.exe这样一个进程在运行,别无聊的以为它是木马没事就Kill着玩。
下面是用户级别的内容。为了方便理解,内核级别的分层介绍我们是从下往上(由硬到软)开始,在用户级别,我们从上往下开始介绍,这样更直观些。
我们先举一个应用程序的例子(尽管用户级别的程序远不止应用程序这么多),从IE讲起。如果你装了VC,并且顺带安装了Depends这个工具,用它打开IE(或是任何一个windows可执行文件都可),你会发现IE主程序(IEXPLORE.EXE)调用了Kernel32.DLL,而Kernel32.DLL又调用了NTDLL.DLL,同时,IE主程序还调用了USER32.DLL,USER32.DLL又有对GDI32.DLL、KERNEL32.DLL、NTDLL.DLL的调用,期间还有循环调用。
去繁从简,Win32应用程序要调用Win32 API函数,这些函数正是有KERNEL32.DLL提供的,而KERNEL32.DLL这个文件其实并不实现具体的功能,只是做了一个简单的地址指针转换,把函数入口点又跳到NTDLL.DLL里去了,对应到了相应的本机API(NATIVE API)函数上,NTDLL.DLL也不做具体的处理,通过系统功能调用将用户级的函数调用转换成内核模式的真正的系统功能调用,由内核执行完毕后返回应用程序进程。也许有人要问Windows为什么要通过Kernel32.DLL和NTDLL.DLL对执行程序Executive暴露的编程接口做两次封装,其实这也是Win32 API和NATIVE API的区别。Win32 API又称为存档的API,是供用户使用的,必须保持一致性和兼容性,不能随随便便修改函数命名,新函数的增加必须保持对老函数的兼容,否则使用老版本的Win32 API开发(直观的就是我们使用win32 SDK或MFC开发)的程序在新版本的系统上可能就要运行出错。而NATIVE API则是在系统更新时可能需要进行修改的函数,比如函数名、函数参数的类型和个数等,都有可能随着系统升级而变更,因此是留给MS自己人来用的,当然不能直接给用户使用。但这不是说就我们作为开发者就不能使用NATIVE API,如果你自己定位NTDLL.DLL中的函数并进行调用,只要这个函数未被MS修改,可以肯定这种调用是成功的,你的程序运行也没有任何问题。与KERNEL32.DLL类似的还有一个ADVAPI32.DLL,提供一些比较高级的应用编程函数。
GDI32.DLL和USER32.DLL提供存档的Win32图形编程接口,它们也是通过NTDLL.DLL来完成对系统绘图功能(在win32k.sys中实现)的调用。
KERNEL32.DLL、ADVAPI32.DLL、USER32.DLL和GDI32.DLL统称为Win32子系统DLL。Win32子系统DLL将存档的Win32 API函数“翻译”为相应的对本机API函数调用,NTDLL.DLL将本机API“翻译”为NTOSKRNL.EXE和Win32k.sys的内核模式系统服务调用,来完成用户级别功能需求的实现。
讲过应用程序之后,再看看用户级别的其它程序。环境子系统(Win32子系统、POSIX子系统、OS/2子系统),这个前面提过了;服务进程,也就是你在服务管理器里可以看到的那一堆东东,包括Services.EXE这个比较特殊的服务程序、svchost.exe等等,这些以后慢慢谈;再就是系统支持进程,如SMSS.EXE(会话管理器)、WINLOGON.EXE(登陆程序)、LSASS.EXE(本机安全权限子系统)等,这些都是专门的内容,有机会将做专题研究。在这里提到的进程都是Windows系统正常运行必要的一些进程,也就是说它们是安全的,大家不必对其有疑心(当然了,有漏洞那是例外)。大部分用户级别应用程序的执行要调用KERNEL32.DLL,然后再间接调用NTDLL.DLL,系统支持进程等程序有的是直接调用NTDLL.DLL。
Windows的基本架构大致如此,下面是Windows 2000的系统架构图,可作为阅读上述文字时的参考。
每天我们都在使用Windows系统学习、编程、听音乐、玩游戏,Windows的操作想来是很熟练了,可是你又对Windows到底了解多少呢?本系列的目的,就是让你对Windows系统有个更直观、更清楚、更彻底的认识。虽然我们大多数人看不到Windows的源码,对其内存调度算法这种最深层次的技术内幕不能明窥,但是我们可以做到比现在知道的更多,了解这些之后你会发现在Windows上面开发会轻车熟路,任何木马病毒到了你机器上不过只会成为你的试验品。
鉴于Windows 9X内核早已淘汰,技术过时,在此不予讨论。主要是针对Windows2000(Windows 5.0)以后版本,尤以2000为主。要知道xp是Windows 5.1版本,2003也才是5.2版本。那么,对于本系列提到Windows OS技术,统指Windows 5.X技术。
本文地址:http://com.8s8s.com/it/it22495.htm