Windows API
Windows API 是针对Windows操作系统家族的用户模式系统编程接口。
.NET
.NET框架是由一个被称为框架类库(FCL)的类库和一个提供了托管代码执行环境的公共语言运行库(CLR)组成的,后者提供的托管代码执行环境包含以下一些特性:即时编译、类型检验、垃圾回收和代码访问安全性等。
CLR的具体实现形式是一个典型的COM服务器,它的代码位于一个标准的用户模式Windows DLL中。实际上,.NET框架中所有组件的实现形式都是标准的用户模式Windows DLL,它们建立在非托管的Windows API函数上(.NET框架没有一个组件运行在内核模式下)
Windows API函数 指Windows API中已被文档化的、可被调用的子例程,例如CreateProcess、CreatFile、GetMessage
原生系统服务(系统调用) 指操作系统中未被文档化的、可在用户模式下调用的底层服务。例如,NtCreateUserProcess是一个内部系统服务,Windows的CreateProcess函数调用该服务来创建新的进程。
内核支持函数 指位于Windows操作系统内部且只能在内核模式下调用的子例程。例如,ExAllocatePoolWithTag就是一个这样的例程,设备驱动程序调用该例程可以向Windows系统堆(称为内存池)申请内存
Windows服务 指由Windows服务控制管理器启动的进程。例如,Task Scheduler服务运行在用户模式进程中,它支持at命令(类似于UNIX命令at或cron)。
DLL(动态链接库) 指一组可调用的子例程,合起来被链接成一个二进制文件,使用这些子例程的应用程序可以动态地加载此二进制文件。例如Msvcrt.dll(c运行库)和Kernel32.dll(一个WindowsAPI子系统库)。Windows的用户模式组件和应用程序大量使用了DLL。DLL比静态库的优势在于,应用程序可以共享DLL,Windows保证在内存中只有一份DLL代码,供所有引用该DLL的应用程序共享。注意,非可执行的.NET程序集也被编译成DLL,但是,它们没有导出任何子例程,而是由CLR解析出编译的元数据,以便访问对应的数据类型和成员。
进程、线程和作业
程序是指一个静态的指令序列,进程是一个容器,包含了执行程序的特定实例时所用到的各种资源。从最高层次的抽象来看,Windows进程由以下元素构成:私有的虚拟地址空间,这是指该进程可以使用的一组虚拟内存地址;可执行的程序,定义了初始代码和数据,并且被映射到该进程的虚拟地址空间中;已打开句柄的列表,指向各种系统资源,比如信号量、通信端口和文件、该进程内所有的线程都可以访问这些系统资源;被称为访问令牌的安全环境,标识了与该进程关联的用户、安全组、特权、UAC虚拟化状态、会话,以及有限的用户账户状态;被称为进程ID的唯一标识符;至少一个执行线程。任何一个进程都不必依赖于父进程信息的有效性。
线程是一个进程内部的实体,也是Windows执行此进程时的调度实体。包括:一组代表处理器状态的CPU寄存器中的内容;两个栈,一个用于线程在内核模式下执行,另一个用于线程在用户模式下执行;一个称为线程局部存储的私有存储区域,各个子系统、运行库和DLL都会用到该存储区域;一个称为线程ID的唯一标识符;有时候线程也有自己的安全环境,或者令牌。
易失的寄存器、栈和私有存储区域合起来被称为线程的环境。此结构与底层架构有关,Windows的GetThreadContext函数允许程序访问这一架构相关的内容。
因为将CPU的执行从一个线程切换到另一个线程,将不可避免地涉及内核调度器,所以,这可能是一个开销昂贵的操作。Windows实现了两种机制降低这一开销:纤程和用户模式调度(UMS)。纤程使得一个应用程序可以调度它自己的线程执行过程,而不必依赖于Windows内置的基于优先级的调度机制。纤程对于内核是不可见的,调用Windows的ConvertThreadToFiber函数,将当前线程转变成一个正在运行的纤程,之后,调用CreateFiber函数,又可以创建额外的纤程(每个纤程可以有它自己的一组纤程)。纤程不会自动执行,必须由SwitchToFiber函数手工选中,才能执行。
UMS线程仅在64位Windows可用,基本提供了与纤程同样的好处。UMS线程有自己的内核线程状态,因此对于内核是可见的,这使得多个UMS线程可以发出阻塞的系统调用,对资源进行共享或竞争。环境切换在用户模式下完成,无需涉及内核调度器。
一个进程内的所有线程可以完全的读写该进程的虚拟地址空间,但不可能无意的引用另一个进程的地址空间,除非第二个进程将一部分私有地址空间变为共享内存区或者第一个进程有权打开第二个进程。
每个进程有一个安全环境,存储在一个称为访问令牌的对象中,进程的访问令牌包含了该进程的安全标识和凭证。默认情况下,线程没有自己的访问令牌,但也可以获得一个访问令牌。虚拟地址描述符(VAD)是指一些数据结构,内存管理器使用这些数据结构来记录进程正在使用的虚拟地址。Windows在进程模型上提供了一个扩展,称为作业。作业使一组进程被当做一个整体来管理和维护。通过作业对象,可以对特定的属性进行控制,也可以对所有与作业相关联的进程进行限制。
虚拟内存
程序运行时,内存管理器借助于硬件的支持,将虚拟地址转译或者映射成真正存放数据的物理地址。操作系统通过控制这一保护和映射机制,可以确保一个进程不会闯入到另一个进程中,也不会改写操作系统的数据。
内存管理器会将内存中的有些内容转移或者翻到磁盘上,可以释放出这部分物理内存。当线程访问一个已经被翻到磁盘上的虚拟地址时,虚拟内存管理器会将磁盘上的信息装回内存中。
32位系统中,总的虚拟地址空间理论上最大值为4GB,默认情况下,Windows将这部分地址空间的较低的一半分给进程,较高的一半用作自己的被保护的操作系统内存。Windows支持一些引导选项,可以使那些运行带有特殊标记的程序(在可执行映像文件的头部设置了大地址空间感知标志)的进程可以使用多达3GB的私有空间。针对32位系统上的大地址需求,Windows提供了一种称为地址窗口扩展(AWE)的机制,使得32位应用程序可以申请多达64GB物理内存,然后将内存视图映射到它的2GB虚拟地址空间中。
内核模式和用户模式
Windows使用两种处理器访问模式:用户模式和内核模式。用户程序代码运行在用户模式下,而操作系统代码运行在内核模式下。内核模式允许访问所有的系统内存和CPU指令。通过让操作系统比应用有更高的特权,处理器为操作系统提供了一层必要的保护,确保行为不正常的应用程序不会破坏系统整体的稳定性。
终端服务及多个会话
终端服务指在单个系统中,Windows对于多个可交互用户会话的支持。利用Windows的终端服务,一个远程用户可以在另一台机器上建立一个会话,并且登录进去,在该服务器上运行应用程序。第一个会话被认为是服务会话,或者零号会话,它包含了宿纳系统服务的进程。在机器的物理控制台上的第一个登录会话为一号会话,而其他的会话可以通过远程桌面连接程序来建立,或者通过使用快速用户切换来建立。
Windows服务器系统支持两个并发的远程连接,以及两个以上的远程会话。所有的Windows客户机版本都支持通过一种被称为快速用户切换的特性,在本地创建多个会话。当用户选择断开其会话,而不是注销其登录时,当前会话仍然保留在系统中,而系统返回到主登录屏幕。如果一个新的用户登录进来,则新建一个会话。
对象和句柄
在Windows操作系统中,内核对象是指某个静态定义的对象类型的单个运行时实例。对象类型由系统定义的数据类型、在该数据类型的实例上进行操作的一组函数,以及一组对象属性构成。
对象属性是对象中的数据域,每个对象属性定义了对象的一部分状态。对象方法,即操纵对象的手段,通常用于读取或者改变对象的属性。对象和普通数据结构之间最根本的区别是,对象的内部结构是不透明的。你必须调用一个对象服务才可以获得对象内部的数据,或者把数据放到对象内部。不能直接读取或者改变一个对象内部的数据。
借助于一个被称为对象管理器的内核组件,Windows中的对象提供了一种便捷的途径来实现下列四个重要的操作系统任务:为系统资源提供可供人读的名称;在进程之间共享资源和数据;保护资源,避免未授权的访问;引用跟踪,这使得系统能够知道一个对象何时不再有用,从而可以自动被释放。
并非Windows操作系统中的所有数据结构都是对象,只有确实需要被共享、保护、命名或者让用户模式程序看得到的数据才被放到对象中。仅仅被操作系统的某一个组件用来实现其内部函数的数据结构并不是对象。
安全性
Windows核心安全功能包括:针对所有可共享系统对象的自主保护和强制完整性保护,安全审计,登录时候的用户认证,以及禁止用户通过访问未初始化资源的做法来访问其他用户已释放的资源。
Windows有三种对对象的访问控制形式。第一种形式称为自主访问控制,由对象的所有者授权或者拒绝其他人访问这些对象;自主访问不能满足需求时,应该使用特权访问控制;最后,当需要额外的一层安全控制以实现在同一个用户账户内部的对象访问保护时,需要使用强制完整性控制。
注册表
注册表是系统数据库,包含了引导和配置系统所必须的信息,全系统范围内控制Windows操作的软件设置、安全数据库,以及针对某个用户的配置设置。
同时,注册表也是一个反映内存中易失数据的窗口,比如系统的当前硬件状态以及Windows的性能计数器。注册表包含了许多会影响系统性能和行为的设置。
Unicode
Windows区别于大多数其他操作系统的一个方面是,它的大多数内部文本串是以16位宽度的Unicode字符来存储和处理的。
因为许多应用程序只处理8位ANSI字符串,所以,接受字符串参数的Windows函数都有两个入口点:一个Unicode(宽字符,16位)版本和一个ANSI(窄字符,8位)版本。
无论哪个语言版本的Windows,都包含同样的参数。Windows不再使用多种不同的语言版本,而是使用一份全球统一的二进制代码。
性能监视器
性能监视器所提供的有关操作系统当前运行状况的信息,比任何其他单个工具所能提供的信息都要多得多。它针对各种各样的对象提供了数百个基本的和扩展的计数器。
性能监视器为每个计数器提供了一份简要描述。可以在“添加计数器”窗口中选择计数器,然后选中“显示描述”复选框。
内核调试
内核调试意味着检查内核的内部数据结构,以及跟踪内核中的函数。这是一条很有用的探查Windows内部机理的途径。
符号文件包含了函数和变量的名称,以及数据结构的布局和格式。它们由链接器产生,在调试会话中被调试器用来引用和显示这些名称。这些名称信息通常并不存储在二进制映像文件中,因为在执行代码的时候不需要用到它们。
要使用任何一个内核调试工具来检查Windows内核的内部数据结构,必须至少得到了内核映像的正确符号文件。符号表文件必须与这些符号表所在的映像文件的版本完全匹配。可以使用符号路径:srv*c:\symbols*http://msdl.microsoft.com/download/symbols,使得调试工具从该Internet符号服务器上加载所需的符号,并在本地的C:\symbols文件夹中维护一份副本。
用户模式的调试。Windows调试工具可以被用于附载到一个用户模式进程上,然后检查和改变进程的内存。在附载到进程时有以下两种选择:侵入式的,除非另行指定,否则,将调试期附载到一个正在运行的进程上时,将通过Windows函数DebugActiveProcess,在调试器和被调试的程序之间建立一个连减,这使得可以检查和改变该进程的内存;非侵入式的,这种选择方式下,调试器只是简单利用OpenProcess函数打开被调试的进程,这使得你可以检查或改变进程中的内存,但是不能设置断点。
连接到内核调试模式后,可以使用众多的内核扩展命令(以!开头的命令)来显示内部数据结构的内容,比如线程、进程、I/O请求包,以及内存管理信息。
Windows软件开发工具(Windows SDK)
Windows软件开发工具,除调试工具外,还包含了编译和链接Windows应用程序所必须的文档、C头文件和库文件。从考察内部机理的角度来看,Windows SDK中令人感兴趣的项目包括Windows API头文件,其中有些工具的源代码也包含在Windows SDK和MSDN Library的示例代码中。
Windows驱动程序开发工具
Windows驱动程序开发工具(WDK)也可以通过MSDN订阅程序获得,如同Windows SDK一样,也可以免费下载。虽然WDK针对的是设备驱动程序开发人员,但它也是Windows内部信息的一个丰富来源。
WDK除了包含文档以外,还包含了相应的头文件(特别是ntddk.h、ntifs.h和wdm.h),这些头文件定义了关键的内部数据结构和常量,以及许多内部系统例程的接口。
网友评论