admin 管理员组

文章数量: 887021

文章目录

  • 前言
  • 1.1 Windows操作系统的版本
  • 1.2 基础概念和术语
    • Windows API
    • 关于 .Net
    • Win32 API 历史
    • 服务、函数、例程
    • 进程、线程和作业
      • 进程
        • tlist /t 查看进程树
        • 任务管理查看进程
        • Process Explorer查看进程的细节
      • 线程
      • 纤程与用户模式调度器线程
    • 虚拟内存
    • 内核模式和用户模式
    • 终端服务及多个会话
      • 概念
      • 远程桌面连接和快速用户切换
    • 内核对象及句柄
    • 安全性
    • 注册表
    • Unicode
  • 1.3 挖掘Windows内部机理
    • 性能监视器
    • 内核调试
      • 内核调试所需要的符号(PDB)
      • windows调试工具(WinDBG)
        • 用户模式的调试
        • 实验:显示内核数据结构的类型信息
      • liveKd工具
    • Windows软件开发工具(Windows SDK)
    • Windows驱动程序开发工具(Windows Driver Kit)
    • Sysinternals工具
  • perfview
  • 总结

前言

本章将介绍Microsoft Windows操作系统的关键概念和术语,比如:

  • Windows API、
  • 进程、
  • 线程、
  • 虚拟内存、
  • 内核模式和用户模式、
  • 对象、
  • 句柄、
  • 安全性
  • 注册表等。

这些概念和术语将贯穿全书。
同时也会介绍一些可用来探查Windows内部的工具,比如:

  • 内核调试器
  • 性能监视器,
  • 以及来自Windows Sysinternals 的一些关键工具。

此外,还将说明如何以WDK (Windows Driver Kit)SDK (Platform Software Development Kit)作为资源,来找到关于Windows内部机理的进一步信息。
请一定要理解本章中讲述的所有内容,本书其余章节将以此为基础。

1.1 Windows操作系统的版本

(这个列表会持续更新)

可参考:
Windows系统历史版本简介
操作系统版本

产品名称内部版本号发布日期
Windows NT 3.13.11993.7
Windows NT 3.53.51994.9
Windows NT 3.513.511995.5
Windows NT 4.04.01996.7
Windows 20005.01999.7
Windows XP5.12001.12
Windows Server 20035.22003.3
Windows Vista6.02007.1
Windows Server 20086.02008.3
Windows 76.1 (编译版本7600)2009.10
Windows 7 SP16.1.7601 (编译版本7601)
Windows Server 2008 R26.1(编译版本7600)2009.10
Windows 86.2.9200
Windows Server 2012 R26.3
Windows 8.16.3.9200
Windows 8.1(Update1)6.3.9600
Windows Server 201610.0*
Windows Server 201910.0*
Windows 1010.0.10240
Windows Server 202210.0*
Windows 10(1511)10.0.10586
Windows 10(1607)10.0.14393
Windows 10(1703)10.0.15063
Windows 10(1709)10.0.16299
Windows 10(1803)10.0.17134
Windows 10(1809)10.0.17763
Windows 10(1903)10.0.18362

注“Windows 7”这一产品名称中的“7”并非指内部版本号,而是Windows家族的世代编号。实际上,为了使应用兼容性问题尽可能小,Windows 7的版本号其实是6.1,如表1.1所示。这使得那些检查大版本号的应用程序在Windows 7上可以像在Windows Vista上那样继续执行。事实上,Windows 7和Server 2008 R2有同样的版本号和编译版本,因为它们是从同样的Windows代码基编译而来。

1.2 基础概念和术语

Windows API

Windows应用编程接口(API)是针对Windows操作系统家族的用户模式系统编程接口。在64位版本的Windows推广以前,32位版本Windows操作系统的编程接口被称为Win32 API,以区别于原来的16位版本Windows的编程接口,即16位WindowsAPI。

术语WindowsAPI兼指Windows的32位和64位编程接口。

Windows API 常用的又分为几个大类:

  • 基本服务
  • 组件服务司
  • 用户界面服务
  • 图形和多媒体服务
  • 消息和协作
  • 网络
  • Web服务

关于 .Net

关于要明白托管的代码和非托管的代码的核心区别:

  • 内存是否托管给语言的机制(java gcc)或者平台(比如)管理,比如java的gcc,c#,都有内存管理机制,而c++是非托管,因为内存需要程序员管理。

Microsoft.NET框架组成:

  • 框架类库(FCL,Framework Class Library)的类库
  • 提供了托管代码执行环境的公共语言运行库(CLR,Common Language Runtime)

托管代码执行环境包含一些特性:

  • 即时编译
  • 类型检验
  • 垃圾回收 GCC
  • 代码访问安全性等。

由于CLR具有这些特性,因此它所提供的开发环境能够提高开发人员的生产效率,减少常见的编程错误。

.NET框架的组件之间的关系

Win32 API 历史

Win32 API 第一次使用:Microsoft Windows 3.0

Win32API 使用起因:Microsoft Windows 3.0发展很好,win32api成为Windows NT启动之初,替代32位 OS/2 Presentation Manager API的替代品,并且兼容16位windows应用程序。

服务、函数、例程

windows 特定的术语的含义:

  • Windows API函数指Windows API中已被文档化的、可被调用的子例程。
    例如CreateProcess、CreateFile和GetMessage。
  • 原生的系统服务(或者系统调用)指操作系统中未文档化的、可在用户模式下调用的底层服务。
    例如,NtCreateUserProcess是一个内部系统服务,Windows的CreateProcessi函数调用该服务来创建新的进程。有关系统调用的定义,参见第3章“系统机制”的“系统服务分发”一节。
  • 内核支持函数(或例程)指位于Windows:操作系统内部且只能在内核模式下调用的子例程(关于内核模式,本章后文将给出定义)。
    例如,ExAllocatePoolWith Tag就是个这样的例程,设备驱动程序调用该例程可以向Windows系统堆(称为内存池)申请内存。
  • Windows服务指由Windows服务控制管理器启动的进程。
    例如,Task Scheduler服务运行在用户模式进程中,它支持at命令(类似于UNIX命令at或cron)。(注意,虽然注册表将Windows设备驱动程序定义为“服务”,但是,在本书中不这样使用。)
  • DLL(动态链接库)指一组可调用的子例程,合起来被链接成一个二进制文件,使用这些子例程的应用程序可以动态地加载此二进制文件。
    例如Msvcrt.dll(C运行库)和Kernel32.dl(一个Windows API子系统库)。Windowsl的用户模式组件和应用程序大量使用了DLL.

DLL比静态库的优势在于,应用程序可以共享DLL,Windows保证在内存中只有一份DLL代码,供所有引用该DLL的应用程序共享。注意,非可执行的NET程序集也被编译成DLL,但是,它们没有导出任何子例程,而是由CLR解析出编译的元数据,以便访问对应的数据类型和成员。

进程、线程和作业

进程

程序是指一个静态的指令序列,
进程是一个容器,其中包含了执行程序的特定实例时所用到的各种资源。

Windows进程是由以下元素构成的:

  • 私有的虚拟地址空间,这是指该进程可以使用的一组虚拟内存地址。
  • 可执行的程序,它定义了初始的代码和数据,并且被映射到该进程的虚拟地址空间中已打开句柄的列表,这些句柄指向各种系统资源,比如信号量、通信端口和文件,该进程内所有的线程都可以访问这些系统资源。
  • 被称为访问令牌的安全环境,它标识了与该进程关联的用户、安全组、特权、UAC
    (User Account Control,用户账户控制)虚拟化状态、会话,以及有限的用户账户状态。
  • 被称为进程ID的唯一标识符(在内部,进程ID还是标识符客户ID的一部分)。
  • 至少一个执行线程(尽管“空”进程也是有可能的,但没有用处)。
tlist /t 查看进程树

tlisk.exe 位于 C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\tlisk.exe

任务管理查看进程
Process Explorer查看进程的细节

Process Expore 下载地址

线程

线程是一个进程内部的实体,也是Windows执行此进程时的调度实体。
如果没有线程,进程的程序将不可能运行。

线程包括以下一些最基本的部件:

  • 一组代表处理器状态的CPU寄存器中的内容。
  • 两个栈一一一个用于线程在内核模式下执行时,另一个用于线程在用户模式下执行时。
  • 一个被称为线程局部存储(TLS,thread-local storage)的私有存储区域,各个子系统、运行库和DLL都会用到该存储区域。
  • 一个被称为线程ID的唯一标识符(它也是内部结构客户ID〔client ID)的一部分进程D和线程D是从同一个名字空间中产生的,所以它们永远不会重叠)。
  • 有时候线程也有它们自己的安全环境,或者令牌,多线程服务器应用程序要模仿其客户的安全环境时,常常会使用线程自己的安全环境。

易失的寄存器私有存储区域合起来被称为线程的环境(context)。因为这些信息随着Windows所在机器架构的不同而有所不同,所以,此结构必须是与底层架构相关的。

Windows的GetThreadContexti函数允许程序访问这一与架构相关的信息(称为CONTEXT块)。

纤程与用户模式调度器线程

出现的原因:因为将CPU的执行从一个线程切换到另一个线程,将不可避免地涉及内核调度器,所以,这可能是一个开销昂贵的操作,如果两个线程经常频繁地来回切换则尤其如此。

Windows实现了两种机制来降低这一开销:

  • 纤程(fiber)
  • 用户模式调度(UMS,user-mode scheduling)。

虚拟内存

内核模式和用户模式

终端服务及多个会话

终端服务:指的是在单个系统中,Windows对于多个可交互用户会话的支持。利用Windows的终端服务,一个远程用户可以在另一台机器上建立一个会话,并且登录进去,在该服务器上运行应用程序。

服务器把图形用户界面(以及其他可配置的资源,比如音频和剪贴板)传送到客户机,客户机把用户的输入传回服务器。

(与X窗口系统类似,Windows允许在一个服务器系统上运行单独的应用程序,其显示部分远程传送到客户机,而非将整个桌面远程到客户机)。

概念

Session0:第一个会话被认为是服务会话,或者Session0,它包含了宿纳系统的服务的进程。

Session1: 在机器的物理控制台上的第一个登录会话为一号会话,而其他的会话可以通过远程桌面连接程序(Mstsc…exe)来建立,或者通过使用快速用户切换(后文会介绍)来建立。

远程桌面连接和快速用户切换

Windows的客户机版本允许单个远程用户连接到机器上,但如果有人已经在控制台上登录了,则工作站会被锁住(也就是说,一个人可以用本地方式或远程方式使用Windows?客户机系统,但不能同时以这两种方式来使用该系统)。包括Windows Media Center在内的Windows版本允许一个交互会话和多达四个Windows Media Center Extender会话。

Windows服务器系统支持两个并发的远程连接(这是为了方便远程管理,例如,有些管理工具要求登录到被管理的机器中才可以使用),以及两个以上的远程会话(只需经过适当的授权许可,并且系统被配置为终端服务器)。

所有的Windows客户机版本都支持通过一种被称为快速用户切换(fast user switching)的特性,在本地创建多个会话。当用户选择断开其会话,而不是注销其登录时(例如,单击“开始”菜单,从“关机”子菜单中选择“切换用户”,或者在按住Windowst键的同时按下L键,然后单击“切换用户”按钮),当前会话(即在该会话中运行的进程,以及描述该会话的所有会话范围的数据结构)仍然保留在系统中,而系统返回到主登录屏幕。如果一个新的用户登录进来,则新建一个会话。

内核对象及句柄

安全性

注册表

Unicode

如果使用了Unicode编码 还会乱码 其实多半因为系统缺少对应语言包导致的。

1.3 挖掘Windows内部机理

主要使用的工具:

工具映像名来源
Startup Programs ViewerAUTORUNSSysinternals
Access CheckACCESSCHKSysinternals
Dependency WalkerDEPENDSwww.dependencywalker
Global FlagsGFLAGS Windows调试工具
Handle ViewerHANDLESysinternals
Kernel debuggersWINDBG,KDWindows调试工具,Windows SDK
Object ViewerWINOBJSysinternals
性能监视器(Performance Monitor)PERFMON.MSCWindows内置工具
Pool MonitorPOOLMONWindows Driver Kit
Process Explorer 下载地址PROCEXPSysinternals
Process MonitorPROCMONSysinternals
Task(Process)ListTLISTWindows调试工具
任务管理器(Task Manager)TASKMGRWindows内置工具
DebugView 下载地址Sysinternals

性能监视器

在本书中,我们经常会提到性能监视器,你可以在“开始”菜单的“管理工具”文件夹中找到该工具(也可以通过“控制面板”找到它);特别地,我们将主要关注性能监视器和资源监视器。性能监视器有三项功能:系统监视、查看性能计数器日志,以及设置报警(利用一组数据采集器,这些数据采集器也包含性能计数器日志,以及跟踪数据和配置数据)。为简化起见,我们在提到性能监视器的时候,实际是指该工具内部的系统监视功能。

性能监视器所提供的有关操作系统当前运行状况的信息,比任何其他单个工具所能提供的信息都要多得多。它针对各种各样的对象提供了数百个基本的和扩展的计数器。本书中所讲述的每一个主要话题, 都附有一张相关的Windows性能计数器表格。
性能监视器为每个计数器提供了一份简要描述。想要查看这些描述信息,请在“添加计数器(Add Counters) ”窗口中选择计数器, 然后选中“显示描述(Show Description) ”复选框。
尽管我们在本书中所做的低层系统监视功能都可以通过性能监视器来完成,但是,Windows还包含了一个实用工具――资源监视器(可以通过开始菜单来访问, 或者通过任务管理器的“性能”选项卡访问到) , 它可以显示四种主要的系统资源:CPU、磁盘、网络和内存。

在基本的状态下,关于这些资源所显示的信息与你在任务管理器中看到的相仿。然而,资源监视器还为这些资源提供了更多的显示区域,以扩展到更多的信息。

展开以后,CPU选项卡显示了有关每个进程CPU使用率的信息,如同任务管理器一样。然而,它加入了显示平均CPU使用率的一栏,这可以让你更好地知道哪些进程最为活跃。CPU选项卡还包含了一个单独的关于Windows服务及其关联的CPU使用率和平均CPU使用率的显示区。如同ProcessExplorer一样,选择某个进程(单击其相应的复选框)将显示出该进程所打开的有名称句柄的列表,以及被加载到该进程地址空间中的模块(比如DLL)的列表。“搜索句柄(Search Handles)”框可用来搜索哪些进程已经打开了某个指定名称的资源。

“内存”部分显示了与任务管理器所展示的同样多的信息,但它针对整个系统进行了组织。物理内存条状图将当前的物理内存,按照“为硬件保留的内存”、“正在使用”、“已修改”、“备用”和“可用”进行组织。关于这些术语的确切含义,参见本书下册第10章。
另一方面,“磁盘”部分显示了基于每个文件的I/O信息,这样可以很容易地识别出当前系统中哪些文件被访问最多、被写得最多,或者被读得最多。这些结果可以被进一步按照进程来过滤。

“网络”部分显示了活动的网络连接、哪些进程拥有这些网络连接,以及在这些连接上传输了多少数据。利用这些信息,有可能看到通过其他途径很难检测到的后台网络活动。而且,有关在当前系统中活动的TCP连接的信息也显示出来了,它们按进程组织,诸如远程的和本地的端口与地址、包延迟之类的数据都显示在其中。最后,正在监听的端口也按进程显示出来了,这使得管理员可以看到哪些服务(或应用程序)当前正在指定的端口上等待连接。针对每个端口和进程的协议和防火墙策略也显示在其中。
注意,通过编写程序可以访问所有的Windows性能计数器。第4章“HKEY PERFORMANCE_DATA”一节简要介绍了通过WindowsAPI来获得性能计数器这种做法所涉及的一些组件。

内核调试

内核调试意味着检查内核的内部数据结构,以及/或者跟踪内核中的函数。这是一条很有用的探查Windows内部机理的途径,因为你可以显示那些通过其他任何工具都无法得到的内部系统信息,并且对于内核内部的代码流有一个更加清晰的认识。
在介绍各种调试内核的方法前,我们先来看一组在执行任何内核调试时都需要的文件。

内核调试所需要的符号(PDB)

符号文件包含了函数和变量的名称,以及数据结构的布局和格式。它们是由链接器产生的,在调试会话中被调试器用来引用和显示这些名称。这些名称信息通常并不存储在二进制映像文件中,因为在执行代码的时候并不需要用到它们。这意味着,二进制映像文件更加小巧,也更加快速。然而这也意味着,在调试的时候,你必须确保在一个调试会话中,调试器能够访问到与当前引用的映像文件相关联的符号文件。

要使用任何一个内核调试工具来检查Windows内核的内部数据结构(比如进程列表、线程块、已加载的驱动程序列表、内存使用信息,等等),你必须至少得到了内核映像Ntoskrnl.exe 的正确符号文件(第2章“总体架构”一节介绍了有关这个文件的更多信息)。符号表文件必须与这些符号表所在的映像文件的版本完全匹配。例如,如果你安装了Windows的一个更新内核的服务补丁(Service Pack)或者热补丁(HotFix),那么,你必须获得匹配的、更新过的符号文件。
为Windows的各种版本下载并安装符号是有可能做到的,但是,热补丁的更新符号则并不总是可以获得。要想获得当前调试所需符号的正确版本,最容易的办法是,利用Microsoft的按需符号服务器,只需在调试器中用一种特殊的语法来指定符号路径即可。例如,下面的符号路径将使得调试工具从该Internet符号服务器上加载所需要的符号,并且在本地的C:lsymbols文件夹中维护一份副本:
srvc:\symbolshttp://msdl.microsoft/download/symbols

有关如何使用符号服务器的更详细的指令,请参考调试工具帮助文件或者Web页面http://msdn.microsoft/en-us/windows/hardware/gg462988.aspx。

windows调试工具(WinDBG)

Windows调试工具(Debugging Tools for Windows)包含了本书中用于挖掘Windows内部机理的高级调试工具。最新的版本也被包含在Windows软件开发工具(SDK)中,作为其一部分。这些工具既可以用于调试用户模式的进程,也可以调试内核(参见下面的辅助内容)。

注 Windows调试工具的版本更新非常频繁,其发布独立于Windows操作系统的版本,所以请时常检查最新的版本。

用户模式的调试

实验:显示内核数据结构的类型信息

liveKd工具

LiveKd是Sysinternals出品的一个免费工具,可用于使用前面刚刚介绍的标准Microsoft内核调试器来检查正在运行的系统,而无须按调试模式引导系统。当需要在一台并非按调试模式引导的机器上进行内核级故障排除时,这种方法可能会非常有用。有些问题可能难以确定地重现,打开调试选项以后再重新引导机器可能无法让错误重现。
可以像运行WinDbg或者Kd那样运行LiveKd.LiveKd会把指定的所有命令行选项传递给你所选择的调试器。在默认情况下,LiveKd运行命令行内核调试器(Kd).要想让它运行WinDbg,请指定-w开关。要想查看有关LiveKd开关的帮助文件,请指定-?开关。
LiveKd将模拟的崩溃转储文件展示给调试器,所以,在LiveKd中可以执行任何可用于崩溃转储的操作。因为LiveKd依赖于物理内存来支持模拟的崩溃转储,所以内核调试器有可能会运行到这样一种状态:有些数据结构正处于被系统修改的过程中,因而是不一致的。每当调试器被启动起来时,它都会获得当前系统状态的一个全新视图。如果你想要刷新系统快照,可以退出调试器(用g命令),LiveKd将问你是否要再次启动起来。如果调试器进入一个打印

Windows软件开发工具(Windows SDK)

Windows软件开发工具(SDK)可通过MSDN订阅程序获得,也可以从msdn.microsoft 免费下载。除调试工具外,它还包含了编译和链接Windows应用程序所必需的文档、C头文件和库文件。(虽然Microsoft Visual C++也附带了这些头文件的一份副本,但是,Windows SDK 中包含的头文件版本总是符合Windows操作系统的最新版本,而VisualC++附带的头文件可能是老的版本,只符合Visual C++刚刚发布时的系统版本)。从考察内部机理的角度来看,Windows SDK中令人感兴趣的项目包括Windows API头文件(\Program Files\Microsoft SDKs\Windowslv7.0A\Include)。其中有些工具的源代码也包含在Windows SDK和MSDN Library的示例代码中。

Windows驱动程序开发工具(Windows Driver Kit)

Windows驱动程序开发工具(WDK,Windows Driver Kit)也可以通过MSDN订阅程序获得。如同Windows SDK一样,它也可以免费下载。Windows驱动程序开发工具的文档包含在MSDN Library中。

虽然WDK针对的是设备驱动程序开发人员,但它也是Windows内部信息的一个丰富来源。
例如,虽然本书下册第8章描述了1/0系统架构、驱动程序模型,以及基本的设备驱动程序数据结构,但是它并没有详细地描述各个内核支持函数。WDK文档包含了所有用于设备驱动程序的Windows内核支持函数和各种机制的详细说明,而且有两种形式:教程和参考资料。

WDK中除了包含文档以外,还包含了相应的头文件(特别是ntddk.h、ntifs.h和wdm.h),这些头文件定义了关键的内部数据结构和常量,以及许多内部系统例程的接口。在用内核调试器来挖掘Windows内部数据结构时,这些文件非常有用,因为尽管本书中给出了这些数据结构的一般性布局形式和内容,但是域(field)一级的详细描述(比如大小和数据类型)并没有给出。然而,在WDK中,许多数据结构(比如对象分发器的头、等待块、事件、突变体(mutant)、信号量,等等)都有完整的描述。

所以,如果你想在阅读本书的基础上,进一步钻研1/O系统和驱动程序模型,可以阅读WDK 的文档(特别是Kernel-Mode Driver Architecture Design Guide和Kernel-Mode Driver Reference)你也可以找到另外两本很有用的参考书: Walter Oney著的Programming the Microsoft Windows Driver Model, 2nd Edition (Microsoft Press, 2002),以及Penny Orwick和Guy Smith 合著的Developing Drivers with the Windows Driver Foundation (Microsoft Press, 2007).

Sysinternals工具

本书中的许多实验用到了一些可从Sysinternals下载的免费软件工具。这些工具中的绝大部分是由本书的作者之一Mark Russinovich编写的。最为流行的工具包括Process Explorer和Process Monitor。请注意,这些工具中有许多要安装和执行内核模式设备驱动程序,因此需要(提升至)管理员权限;若它们运行在标准的(非提升的)用户账户下,则只有很有限的功能和输出。

由于Sysinternals工具的更新很频繁,所以,尽可能确保使用了这些工具的最新版本。若想获得有关工具更新的通知,可以订阅(follow)Sysinternals站点博客(此博客有RSS源)。

关于这些工具的说明、如何使用这些工具,以及使用这些工具来解决问题的实例,请参考Mark Russinovich 和Aaron Margosis 合著的Windows Sysinternals Administrator's Reference (Microsoft Press,2011)。
有关这些工具的问题和讨论,请访问Sysinternals的论坛。

perfview

解析etw事件文件的工具

下载地址 csdn 资源中

总结

本文标签: 操作系统 概念 笔记 工具 Windows