精华内容
下载资源
问答
  • Windows内核原理与实现》终于完成了
    2010-04-19 23:55:00

    Windows内核原理与实现》终于完成了

    经过将近两年的努力,终于完成了《Windows内核原理与实现》一书。2008年春天,我有了写一本关于Windows内核的书的想法,然后联系出版社并付诸实施。这就把两年的业余时间搭了进去,至少有一半的夜晚迟至2点才睡觉。

    按原来的计划,期望在2009年秋天完成全书并出版。其实到20096月份,这本书的主体内容,即进程和线程管理、内存管理、同步与并发,以及I/O,已经完成了,但考虑到系统的完整性,又花了不少笔墨来描述Windows系统的其他部件,到200912月初终于完成所有的章节。接下来用4个月时间复查一遍,于20104月初完成所有内容,包括文前文后的文字。

    在此之前,我只写过一本书,即1998年写了《COM原理与应用》,199911月出版。写作COM这本书我花了大约9个月时间。现在回想起来,描述COM技术基本上还只是停留在表面上,并没有深入到COM的核心。如果我今天再来写COM,相信可以写得透彻很多。即使不参考COM的实现代码,也可以通过各种途径挖掘到COM的实现细节。当然,这需要足够多的时间投入。

    写作Windows内核这本书,其实也是一个学习过程。虽然事先已经了解Windows内核中的许多细节,但为了准确地、系统地描述Windows内核中的各种机制,仍然有大量的细节需要搞清楚。有时候,一个很小的细节,可能要花上一两个晚上。我常常在思考,Windows内核中有这么多精巧的设计,内核开发人员和设计师是如何想到并构造出来的呢。每次想通了一个问题,总会有一种豁然开朗的感觉。这种乐趣,我相信很多程序员都有体会。

    从上一本书到这本书,隔了10年,并不等于写作这本书需要10年的积累。我没有刻意要写这样的技术图书,写作这本书纯粹是机缘巧合,兴趣所致。WRK2006年发布的,我等待了两年,一直期望有这样的书出现,两年后终于决定自己写这本书。现在,这本书完成了,感觉轻松了很多。

    更多相关内容
  • 本书从操作系统原理的角度,详细解析了windows如何实现限贷操作系统的额各个关键组件。在介绍各个组件时,本书以WRK为参照。
  • Windows内核原理与实现.rar
  • windows内核原理和怎么实现的,作为一个典型的现代操作系统,Windows 有着广泛的用户群体,并且自诞生以来就一直备受关注。在讲述了 Windows 基本结构以后, 本章将简要地介绍 WRK(Windows Research Kernel),这...
  • WINDOWS内核原理与实现(带书签版)
  • Windows内核原理与实现高清pdf

    热门讨论 2011-10-27 10:42:33
     在内容选取方面,本书侧重于Windows内核中最基本的系统部件,同时也兼顾到作为一个操作系统的完整性,所以,本书也介绍了像存储体系、网络、Windows环境子系统等,这些虽然并不位于内核模块但却支撑整个Windows...
  • Windows内核原理与实现

    2014-01-02 22:59:18
    Windows内核原理与实现pdf电子书的下载地址,真实有效。
  • Windows内核安全与驱动开发(随书光盘),windows内核原理与实现pdf,CC++源码.zip
  • Windows内核安全驱动开发(随书光盘)
  • Windows内核原理与实现》书内工具

    热门讨论 2012-01-02 15:31:32
    Windows内核原理与实现》书内的工具,从电子工业出版社网站上下载下来的,但是原来的工具是嵌在docx文档中的,需要下载一个package.exe程序来提取。所以索性都提取出来重新压缩,方便大家使用。
  • WINDOWS内核原理与实现(jb51.net).pdf
  • Windows内核原理与实现.pdf Windows内核原理与实现.pdf Windows内核原理与实现.pdf
  • 潘爱民大师的著作,本人看过后感觉对于操作系统的理解有了很大的提高,结合windows的内核的WRK源代码来解释windows内核原理 很好的书籍 分享给大家
  • Windows内核原理与实现.part2 第二部分,如有侵权行为,请联系原作者。
  • 如图Windows内核分三层,硬件直接打交道的是硬件抽象层HAL,这一层把所有硬件相关代码逻辑隔离到一个专门模块中,从而是上层尽可能独立于硬件平台。HAL是一个独立动态链接库,windows带了多个如Hal.dll,halacpi....

    Windows内核结构

    上图是windows内核的组成结构

    如图Windows内核分三层,与硬件直接打交道的是硬件抽象层HAL,这一层把所有与硬件相关代码逻辑隔离到一个专门模块中,从而是上层尽可能独立于硬件平台。HAL是一个独立动态链接库,windows带了多个如Hal.dll,halacpi.dl等,这是根据高级配置和电源接口高级可编程中断控制器之类的区别,只有一个会被选中选中之后拷贝改名为hal.dll,hal才是真正的硬件抽象层,例如自旋锁和中断是在hal实现。内核只需简单实用其导出函数。

    HAL之上是内核层,有时候成为微内核,这是大内核中的小内核,是ntoskrnl.exe的下层部分,上传是执行体,接近HAL层,这层是包含了基本的操作系统原语和功能,如进程线程,线程调度,中断和异常处理,同步对象和各种机制,还负责同步处理器直接行为。windows内核实现了抢占式线程调度机制,就是线程按优先顺序,分配到处理器上,每个线程有基本优先级,也有动态优先级,高优先级线程可抢断低优先级线程,windows内核按面向对象思想,管理两种对象,分发器对象(dispatcher object)和控制对象,分发器对象实现各种同步功能,这些对象状态会影响线程电镀。分发器对象包括event,mutant,Semaphore,process,thread,queue,gate,timer。控制设备对象被用于控制内核操作,不影响线程调度,包括异步过程调用APC,延迟过程调用DPC,中断对象等。

    在内核层之上是执行体层,这一层是提供上层应用程序或内核驱动程序直接调用的功能和语义,Windows内核的执行体包含一个对象管理器,用于一致地管理执行体中的对象。执行体层和内核层位于同一个二进制模块中,即内核基本模块,其名称为ntoskrnl.exe。执行体是ntoskrnl上层,包含进程线程管理器,内存管理器,安全引用监视器,IO管理器,缓存管理器。配置管理器。即插即用管理器。电源管理器。

     

    既然在同一个模块,内核层和执行体层分工是,内核层实现操作系统基本机制,而所有策略决定则留给执行体。执行体中的对象绝大多数封装了一个或者多个内核对象,并通过某种方式比如对象句柄,暴露给应用程序。这种设计体现了机制与策略分离的思想。

    Windows内核为用户模式代码提供一组系统服务,供应用程序使用内核中的功能。应用程序通常并不直接调用这些系统服务,而是通过一组系统DLL,最终通过ntdll.dll切换到内核模式下的执行体API函数中,以调用内核中的系统服务,ntdll.dll是链接用户模式代码和内核模式系统服务的桥梁,对于内核提供的每个系统服务,该DLL都提供一个相对应的存根函数,这些存根函数的名称以NT作为前缀,比如NtCreatProcess等,此外ntdll.dll还提供了很多系统的支持函数,比如映像加载器函数(以Ldr)为前缀,WIndows子系统进程通信函数(以Csr为前缀),调试函数(以Dbg为前缀),系统事件函数(以Etw为前缀),以一般的运行支持函数(以Rtl为前缀)和字符串支持函数。

    执行体API函数若果先前模式时用户模式要做参数检查,指针还要做内存校验。比如probeforwrite(long)。

    每个线程都维护着一个状态值,说明它以前的处理器模式是用户模式还是内核模式。

    即插即用管理器

    这类模型驱动程序称为WDM,一用三种类型,总线驱动,功能驱动,过滤驱动程序。

    windows原生文件系统NTFS(NT File System),驱动是ntfs.sys。另一个是FAT,windows支持两种形式的过滤驱动程序:一种直接插入到设备栈中,能够看到每一个经过设备栈文件的I/O请求,另一种基于Windows提供的过滤管理器驱动程序(FltMgr)的I/O过滤框架,称为文件系统小过滤驱动程序,并不出现在文件系统设备栈,通过回调方式响应FltMgr的事件。

    分区是存储设备上连续存储区域,卷是值扇区逻辑集合,卷内部扇区可能是来自一个分区,或者多个分区,文件系统是卷内部的逻辑结构。

    所以从应用程序-->存储设备应该是,文件系统,卷管理部分,分区管理,磁盘驱动。

    磁盘设备是典型的即插即用,最下层总线驱动程序,最上层分区管理器驱动程序,负责通知即插即用管理器当前磁盘有哪些分区,因而系统中的磁盘管理器可以接收到有个分区创建和删除。

    网络

    有Windows套接字,Winsock,WinInet(高层网络API,包括FTP,HTTP).

    命名管道(named pipe)和油槽(mailslot)。用于不同进程间通信,支持不同机器上进程通信,前者连接方式,后者非连接方式通信,可以广播。

    NetBIOS是早期网络API,支持有连接,无连接通信。

    RPC是网络通信标志,分布式系统基础组件,RPC建立在其他网络API上,比如命名管道Winsock。Windows的RPC支持异步通信。

    这些网络API提供了用户模式的dll,通过dll发出网络请求,将接收到的请求给驱动,通常要么通过系统服务如油槽管道等给,要么是I/O管理器对象给驱动。

    winsock是windows最重要的网络API,用户模式包含了一个dll,即ws2_32.dll,还定义了一个可扩展的框架,允许第三方插入传输服务提供者和名字空间服务提供者。以支持更多的传输服务和名称解析或地址映射能力。Winsock默认支持TCP/IP,IPX/SPX,AppleTalk和ATM协议,提供的传输服务和名字空间服务通过内核驱动afd.sys实现网络通信。

    在内核模式网络API驱动通过传输驱动程序接口(TDI),与协议驱动通信。TDI实际上预定了一组I/O请求,如名字解析,建立连接等。网络API驱动程序是TDI客户,传输协议驱动实现了TDI接口,称为TDI传输器。TDI用户和TDI传输器之间松耦合,多对一。

    Windows中,网络协议与网络适配器驱动是分开的,协议驱动程序独立于任何一个网络适配器,真正发送和接收数据是通过网络适配器进行。协议驱动通过统一结构与适配器去哦多功能进行通信就是NDIS(Network Driver Interface Specification)

    符合NDIS的网络适配器驱动称为NDIS驱动,或NDIS小端口驱动。Windows提供了NDIS库即ndis.sys,作为协议驱动和NDIS驱动程序桥梁,随系统发行。

    NDIS客户即TDI传输器利用NDIS提供的功能,对将要发送给NDIS驱动程序格式化,并发给NDIS驱动,而NDIS驱动程序则利用NDIS库,接收请求和送回应答。NDIS驱动被封标准设备驱动程序,通过NDIS库与NDIS客户通信,I/O管理器不介入。

    Windows子系统

    其中windows子系统包含内核模式和用户模式,内核模式部分核心是Win32k.sys,包含2部分,窗口管理和图形设备接口,窗口管理负责收集分发消息,控制窗口显示和管理屏幕输出。图形设备接口部分包含各种形状绘制及文本输出功能。用户模式部分包括Windows子系统csrss.exe以及一组动态链接库。csrss.exe进程主要负责控制台窗口的功能,以及创建或删除进程和线程等。子系统dll则被直接链接到应用程序进程中,包括kernel32.dll,use32.dll,gid32.dll,advapi.dll等,负责实现已经文档化的Windows API函数。

    Win32k向用户代码提供系统服务,另一方面也跟Windows内核紧密融合在一起,通过向内核注册一组callout函数,介入到内核的线程进程管理处理逻辑中,同时接受电源事件。对于每个线程,一旦调用win32k.sys的任何一个服务,就变成了GUI线程,从而纳入Windows子系统的线程和进程管理范畴。

    以下1模式这些系统进程在Windows操作系统扮演重要角色:

    系统空闲进程(Idle),PID为0,每个处理器有一个

    System进程,xp,server2003PID为4,包含了内核模式系统线程

    会话管理器(Session manager smss.exe),这是Windows系统创建的第一恶搞用户模式进程。承担创建环境变了等,启动了子系统进程csrss.exe和winlogon.exe。

    登陆进程winlogon.exe

    windows子系统进程csrss.exe,负责提哦给你子系统环境,包括提供控制台窗口功能,以及创建删除进程和线程。

    本地安全权威子系统进程Isass.exe。负责本地系统安全策略。

    shell进程explorer.exe。windows默认Shell,提供了系统与用户打交道的各种节目包括开始菜单,任务栏等。

    服务控制管理器services.exe,负责管理windows的系统服务。

     

    在windows内核结构中,进程线程的核心机制是在微内核中实现,而管理机制在执行体中实现,符合机制与策略分工的原则。

    如线程调度由微内核来完成,线程进程创建各种管理属性设置由执行体完成。因此关于进/线程数据结构和函数属于微内核范畴,另外一些属于执行体范畴。比较典型的例子是KPROCESS和KTHREAD是微内核中进程和线程的数据结构,EPROCESS和ETHREAD是执行体中进程和线程的数据结构。KeAttachProcess/KeStackAttachProcess是微内核中将线程附载到指定进程的函数,而PspCreateThread/PspCreateProcess是执行体中创建线程/进程的函数。

    windows实现了基于优先级的抢占式线程调度算法,每个线程有一个基本优先级和动态优先级。

    中断是外部设备/异常是CPU内部产生的打断指令流。所以区别在于中断发生于当前指令流并无实质联系,异常则是当前指令流执行的直接结果。而且中断是异步的,异常是同步的。

    windows使用0-31来表示IRQL,中断请求级别,数值越大,优先级越高,如果发生中断时,IRQL等于或者低于当前级别,则该中断被屏蔽,直到IRQL降下来,IRQL=0表示普通线程,称为PASSIVE_LEVEL或被动级别,它的优先级最低,可被任意其他级别中断打断,IRQL=1表示异步过程调用(APC),成为APC_LEVEL,它仅比PASSIVE_LEVEL高,因此,在一个线程插入一个APC对象可以打断该线程执行,IRQL=2表示处理器正在做两件事情之一:正在进行线程调度,比如选择新的线程;正在处理一个硬件中断的后半部分,在windows中称为延迟过程调用(DPC Deferred Procedure Call),因此IRQL为2也被称为DISPATCH/DPC级别,或者简单称为DISPATCH_LEVEL。

    DPC是一个重要概念,IRQL等于DISPATCH_LEVEL,高于PASSIVE_LEVEL,和APC_LEVEL,因此优先于任何一个线程相关函数,屏蔽了线程调度。低于所有的硬件中断,所以不屏蔽任何一个硬件中断。之所以称为延迟的,过程调用,因为它往往被用来执行一些相对于当前优先级别的任务不那么紧急的事情,比如硬件中断的后半段,典型的用法是timer定时器。比如在时钟中断服务例程中,负责更新中断时间,系统时间判断西戎的定时器是否有定时器到期有发出DISPATCH_LEVEL的软中断请求(中断线程和APC)。

    与DPC不同,APC属于线程相关,只能在特定线程环境中被执行。所以也在特定地址空间执行,而且APC高于PASSIVE_LEVEL,所以优于线程本身指令流,当一个线程获得执行权,APC例程会立即执行,所以APC适合实现各种异步通知事件,例如I/O的完成通知可以使用APC实现。

    异常既可以处理器硬件产生,也可以软件流产生。内核模式用户模式都可能发生异常,根据异常时处理器模式不同,异常分发(exception dispatch)过程也不同:

    内核模式下,异常分发器首先将异常交给内核调试器处理,若不存在内核调试器或者内核调试器没有处理该异常,则尝试分发到一个基于帧的异常处理器(frame-based exception handler),基于帧的异常处理器是一种异常处理技术,他将异常处理器与“栈帧(stack frame)”关联起来,当发生异常时,异常分发器将根据当前栈帧来查找与之关联的异常处理器,如果未能找到这样的异常处理器,则异常分发器将该一次再次交给内核调试器,若这次该异常仍未能被处理,则认为是一个严重错误,系统奔溃。

    用户模式下,异常分发器首先判断进程的调试端口是否有效,有效则发送消息至调试端口,然后等待应答,否则将异常给内核调试器。如果异常仍未得到处理,则将控制转到用户模式下,由用户模式的异常分发器(ntdll.dll中的KeUserExceptionDispatcher函数)寻找一个基于帧的异常处理器。如果仍未得到处理,则再次回到内核模式下,这次,内核模式异常处理器首先尝试调试端口,若异常仍未被处理,则再次尝试当前进程的异常端口。连接进程异常端口的是windows子系统,因此,windows子系统在异常处理最后时刻有机会处理他所属进程的异常,如果它也不能处理此异常,则该进程被终止。

    同步

    同步是为了解决并发访问。windows操作系统提供多种多种同步机制,根据执行环境中的IRQL值大于APC_LEVEL或者等于PASSIVE_LEVEL,可以将同步分为“不依赖线程调度的同步机制”和“基于线程调度的同步机制”两类。

    当IRQL大于APC_LEVEL时,Windows提供了一些方便的同步保护机制,供内核自身或设备驱动程序使用。IRQL大于APC_LEVEL时典型的同步机制如下:

    提升IRQL。根据IRQL的定义,当处理器在某个IRQL上运行时,他只能被更高IRQL的中断打断,意味着,不用担心低IRQL的过程会抢占掉当前执行过程。这种做法在单处理器系统上可以做的更好,但是多处理器系统上,提升IRQL还不够,往往还需要其他同步机制(如自旋锁)。

    互锁操作。利用Intel X86处理器提供的lock指令前缀,可以实现基于整数操作的保护,确保一个操作以原子方式进行。这种操作只能在小粒度数据上(可以达到64位内存单元)进行同步保护,而且是指令级保护。

    无锁的单链表。windows利用64位互锁指令来实现无锁的单链表数据结构,支持多核,多处理器环境。

    自旋锁(spin lock)。自旋锁本身是一种忙等。为了获得自旋锁,处理器持续监测锁状态。直至可用。此时即使有线程调度执行,APC排队,也没机会执行。所以自旋锁通常用于IRQL大于等于DISPATCH_LEVEL的代码。windows还提供一些自旋锁的扩展:执行体自旋锁(支持共享和独占的语义),排队自旋锁(queued spin lock)和栈内排队自旋锁(in-stack queued spin lock)。

    另一种同步是PASSIVE_LEVEL上线程之间的同步。当一个线程的执行条件不满足,进入等待状态。系统将控制权交给满足执行条件单没有得到处理器资源的线程。以后当该线程执行条件满足时,有机会继续执行。这里的执行条件正是windows提供的线程同步机制中的语义。windows定义了统一的机制支持各种线程同步原语:分发器对象(dispatcher object),其数据结构头部为DISPATCH_HEADER。

    windows使用等待块(wait block)来描述“一个线程正在等待一个分发器对象变成有信号状态”。对于每个处于等待状态的线程,它由一个等待块链表。链表中的每个节点代表该线程正在等待一个分发器对象,而对于每个分发器对象,它也有一个等待块链表。链表中每个节点代表了正在等待该对象的一个线程。所以当一个分发器对象变成有信号状态时,系统循着此对象的等待块链表,就知道该解除那个或者哪些线程,唤醒他们。线程进入等待的条件(若等待多个对象,则须指明等待任何其中之一或者等待所有对象)及分发器对象的状态(解除一个线程或者所有线程),决定了等待条件该如何被满足。

    windows 实现了以下分发器对象:

    事件(event):分为事件通知对象和事件同步对象,区别在于,当事件对象变成有信号状态时,是解除所有正在等待该对象的线程,还是只唤醒第一个以WaitAny方式等待该对象的线程。

    突变体(mutant):突变体是Windows内核中互斥体的实现,如果推按体对象为无信号状态,则一定被某个线程“占有”,否则可满足任何一个线程的等待要求。突变体记录了“所有者”线程信息,通常可用于实现“锁”。

    信号量(semaphore):信号量有一个计数器,用于控制最多可以有多少个线程共享一个资源。当计数器达到预定最大值时,信号量将变成无信号状态。

    队列对象(queue):这是Windows内核中用于支持线程池的机制,其数据结构为KQUEUE,通常可以用于控制一项任务的并发程度。它的典型用途是I/O完成端口。

    进程对象:Windows的内核进程对象本身也是一个分发器对象,当进程对象被初始创建时,为无信号状态,进程结束为有信号状态。

    线程对象:同理如上。

    定时器对象:定时器对象既是一个像DPC一样的例程,也是个可等待的分发器对象,当设定的时间到期时,定时器变成有信号状态。

    门对象(gate object):在windows中,门对象和门等待时线程调度器的特殊支持,它绕过了以上分发器对象同步过程中的很多步骤。唤醒一个门等待的线程几乎是以最快捷的方式进行,线程调度器会直接将线程插入到某个处理器的就绪队列中。

    除此之外,还有更丰富的同步机制:包括,快速互斥体(fast mutex),守护互斥体(guarded mutex),执行体资源(executive resource)和推锁(push lock)。

    Windows内核中的公共管理设施

    Windows内核中的对象管理

    Windows中资源管理采纳了面向对象的思想。

    每个对象都分为对象头对象体。对象头包含对象管理所需要的基本信息,包括名称类型,引用计数,安全描述符等,每种对象需要一个对应的类型对象(OBJECT_TYPE),通常在初始化过程调用ObCreateObjectType函数构建这种对象类型,完成相应全局变量的初始化。

    第二个参数

    可以看到在调用ObCreateObjectType创建对象类型,除了数据,还指定了基本的增删改等基本操作。之后内核就可以调用ObCreateObject来创建此种对象了。

    参数ObjectType只是确定了对象头,对象体大小在ObjectBodySize。这个函数返回时,指向对象体开始位置(不是对象头),对象体格式特定于某种对象类型,由相应类型对象的诸多过程来维护。

    对象管理器使用对象头中包含的信息管理这些对象,在对象头中除了对象名称和对象类型,有两个重要信息,指针计数,记录了内核本身(也包括驱动程序)引用该对象的次数。句柄计数,记录了有多少个句柄引用此对象。这些句柄可能出现在不同进程中。

    对象管理器提供了一些通用服务,可以应用在任何类型的对象上,所以类型对象不需要为此种类型的对象提供所有在OBJECT_TYPE_INITIALIZER定义中出现的方法。

    对象构造由两部分完成(1)调用ObCreateObject,根据指定的类型对象来完成对象头初始化,并且按指定大小分配对象体内存(2)完成对象体的初始化。前者统一完成,猴子根据不同类型对象有自己的初始化逻辑。

    Windows允许以名称的方式管理对象。为了这样,Windows必须维护一套全家的名称查询机制,ObpDirectoryObjectType类型对象就说实现这一机制的关键。

    Windows内部维护了一个对象层次目录(系统全局名字空间),其根目录对象是由全局变量ObRootDirectoryObject来定义。在WRK中,通过查询NTCreateDirectoryObject函数被调用情况,可以看到一系列ObjectTypes等对象子目录创建情况。

    对象管理器提供一些基本操作用于在名字空间增删改查比如ObpLookupDirectoryEntry(指定目录查找一个名字),另外一个重要操作是ObpLookupObjectName,从指定目录或根目录,递归找一个对象。管理器的打开和引用对象,插入对象(ObOpenObjectByName)等都是通过ObpLookupObjectName实现。

    在ObpLookupObjectName的代码逻辑中,可以看到进程设备表(DeviceMap),而且在目录对象的数据结构OBJECT_DIRECTORY中也有一个名为DeviceMap的成员,指向一个DEVICE_MAP。DEVICE_MAP的含义是,它定义了一个DOS设备名字空间,比如驱动器字母(C:/D:)和一些外设(com1),当对象管理器看到一个以“\??\”这样的名称,它会利用进程DeviceMap来获得相应的对象目录,然后进一步解析剩余名称字符串。

    对象管理器中的对象是执行体对象,位于系统地址空间中,因而所有进程都可以访问这些对象,但是在进程地址空间中运行的用户模式代码不能用指针的方式引用这些对象,而是在调用系统服务时通过句柄来引用执行体对象。句柄时进程范畴的概念。在内核中将一个句柄转换成对应的对象。可通过ObReferenceObjectByHandle函数来完成。该函数负责从当前进程环境或内核环境句柄表中获得指定的对象引用。

    关于对象的内存结构和生命周期,对象分为对象头对象体,头部结构是OBJECT_HEADER,对象体因对象而异,所以看到很多函数在接受对象作为参数时,类型为PVOID,而对象头和体通过ObpAllocateObject函数可知在同一块内存中。

    从对象体转换到对象头,可以通过

    对象是通过引用计数实现管理生命周期,一旦计数为零,则生命周期结束,对象的引用计数来源于2个方面,第一个来源是内核中的指针引用,一旦内核中新增了以恶搞对象引用,则对象引用计数需要增1,如果不在引用,则减1。第二个来源是进程打开一个对象获取一个句柄,它以后通过此句柄来引用此对象。对象头信息中准确记录有多少个句柄指向该对象,当1句柄不再被使用时,句柄计数减一。两种作用是在函数ObpIncrementHandleCount/ObpDecrementHandleCount中完成的。

    注册表和配置管理器

    Windows系统很多组件都是可以配置的,内核组建通常支持一些参数,甚至有些完全依赖于系统配置信息。例如I/O管理器和即插即用管理器在初始化阶段根据系统设置来例句和加载设备驱动程序。Windows操作系统提供了一个称为“注册表”的中心存储设施来作为系统的配置和管理中心。应用程序和捏合通过访问注册表来读写设置Windows同时提供API供访问注册表,API接到注册表访问请求,转发给系统服务。在内核中,执行体包含一个称为“配置管理器(configuration manager)”组件,是注册表的真正实现。注册表由一组称为储巢(hive)的文件构成,每个储巢内部包含一个树形层次结构,每个储巢可以想象成一个文件系统。

    windows注册表是树状结构,每个节点是一个键值。注册表值可以多种类型,绝大多说注册表值类型为REG_DWORD(32位整数),REG_BINARY(二进制数据)和REG_SZ(字符串)。还有REG_LINK(符号链接,执行另一个键或值)。

    除了HKEY_PERFORMANCE_<XXX>以外,在其他的5个根键中,真正存放系统设置信息的子树是HKLM和HKU。HKLM存放有关系统全局的信息,包括5个子键,分别为HARDWARE(硬件设置)、SAM(本地账户和组的信息)、SECURITY(系统全局范围的安全策略和用户权限设置)、SOFTWARE(系统中的全局配置信息,在系统引导时不需要)和SYSTEM(系统中的全局配置信息,在系统引导时需要,包括设备驱动程序和系统服务等)。HKU为系统中每个加载过的用户轮廓包含一个子键,也包含一个名为.DEFAULT的子键,这是系统的默认轮廓,当登录进程winlogon.exe为第一次登录到系统中的用户创建轮廓时将以此为基础。

    关于注册表存储结构,注册表是由一组储巢构成的,每个储巢包含了一个由键和值构成的层次结构。上图列出了Windows Server 2003系统中各个储巢的注册表路径和文件路径。一个系统的储巢列表存放在HKLM\SYSTEM\CurrentControlSet\Control\hivelist键下,如下图所示。当系统初始化时,HKLM\SYSTEM总是先被加载进来,然后配置管理器找到hivelist键,继而加载其他储巢,并创建注册表根键,将这些储巢链接起来,从而建立起完整的注册表结构。

     储巢的内部结构类似于一个文件系统,而储巢相当于是一个磁盘分区。储巢的基本分配单元称为块(block),类似于文件系统定义的簇(cluster)。当储巢为了存储新的数据而需要扩展时,它总是按照块的粒度来增长。在Windows中,注册表的块的大小为4KB(4096B)。储巢的第一个块称为基本块,它包含了储巢文件标识、最新序列号、最后一次写操作的时间戳、储巢格式的版本号、校验和,以及储巢的内部文件名。储巢中的注册表数据是按照巢室(cell)来组织的。巢室可大可小,具体取决于它的类型和数据,每个巢室可以存放一个键、值、安全描述符、子键列表或者值列表,对应的巢室分别称为键巢室、值巢室、安全描述符巢室、子键列表巢室和值列表巢室。巢室在储巢文件中的偏移称为该巢室的索引(cell index),其他巢室可以利用此巢室索引来引用它,从而建立起巢室之间的关系。

    配置管理器使用了一种类似于Intel x86处理器的页表映射的做法来解决巢室地址转译,一个32位的巢室索引被分成四个组成部分:存储类型、巢室目录索引、巢室表索引和块内偏移。存储类型有两种可能:稳定的(stable,最高位用0表示)和易失的(volatile,最高位用1表示)。每个储巢在内存中有两个巢室目录,分别对应于稳定的和易失的配置数据;每个巢室目录有1024项,每一项指向一个巢室表;每个巢室表包含512个表项,每一项指向一个块。由于配置管理器用巢箱来管理内存分配,而巢箱总是以块为边界(4KB),所以,巢室索引的最后12位指定了一个巢室在块内的偏移。基于这样的巢室索引结构,配置管理器将只为每个储巢映射那些需要用到的巢箱,而不是所有的巢箱。巢室目录和巢室表仍然占用换页内存池的空间,但通常情况下,相比于整个储巢文件,它们要小得多。配置管理器通过这种巢室映射的做法,可有效地降低注册表数据的内存使用量。

    Windows内核中配置管理器的实现

    配置管理器是执行体中的组件,它的实现依赖于内存管理器和缓存管理器(以及文件系统),这意味着它必须要在这些组件初始化以后才能正常工作;然而,在系统初始化的早期(比如I/O子系统的初始化),Windows已经需要使用注册表中的配置信息了,但此时配置管理器尚未被初始化。Windows的做法是,在内核初始化以前,内核加载器(ntldr)已经将整个HKLM\SYSTEM储巢作为一个只读文件加载到了内存中,因而配置管理器在完全初始化以前只需直接把巢室索引加上该储巢的内存映像地址,就可以得到巢室的内存地址。这一做法有一个限制,即,在配置管理器完全初始化以前,系统只能访问HKLM\SYSTEM中的设置,换句话说,Windows必须把初始化早期用到的各种设置存放在HKLM\SYSTEM中。

    配置管理器和注册表的初始化过程

    配置管理器建立起完全的注册表视图分三个阶段来完成:第一,在内核初始化阶段,建立起HKLM\SYSTEM和HKLM\HARDWARE储巢;第二,由会话管理器(smss.exe进程)建立起HKLM\SAM、HKLM\SECURITY、HKLM\SOFTWARE和HKU\.DEFAULT储巢;第三,当加载用户轮廓时建立起HKU\<用户的SID>储巢,这是由登录进程(winlogon.exe)来完成的。这里第一阶段可以看做配置管理器的初始化,以及注册表的临时初始化;第二阶段可以看做注册表中系统部分的初始化;第三阶段可以看做注册表中用户部分的初始化。

    首先来看第一阶段的初始化,它发生在一个关键点上:在内核初始化过程中,在对象管理器和缓存管理器初始化以后,但在I/O子系统初始化以前。内核在这个点以前,不能访问注册表中的任何信息;而在这个点以后,可以访问HKLM\SYSTEM和HKLM\HARDWARE中的设置。执行这一初始化过程的函数为CmInitSystem1,它是在内核初始化过程中由Phase1InitializationDiscard函数调用的。

    CmInitSystem1函数(参见base\ntos\config\cmsysini.c文件)负责完成以下事项:

    初始化配置管理器的全局变量,包括各种链表和同步对象。

    创建注册表键的类型对象CmpKeyObjectType,CmInitSystem1通过调用CmpCreateObjectTypes函数来完成。

    创建主储巢CmpMasterHive,这是一个易失储巢,代表了注册表的根。创建储巢的函数为CmpInitializeHive。

    用CmpCreateRegistryRoot函数建立起注册表的根:在主储巢中创建节点“\REGISTRY”,并创建一个键对象指向该节点,然后将该对象插入到对象名字空间的根下面。

    调用NtCreateKey函数创建“\REGISTRY\MACHINE”和“\REGISTRY\USER”节点。

    调用CmpInitializeSystemHive函数创建系统储巢。在CmpInitializeSystemHive函数中,它根据ntldr传递进来的已加载的原始SYSTEM储巢映像,来初始化内存中的SYSTEM储巢。CmpInitializeSystemHive函数调用CmpInitializeHive来初始化SYSTEM储巢,并调用CmpLinkHiveToMaster将它链接到主储巢中。

    调用CmpCreateControlSet函数,根据加载信息创建符号链接“\Registry\Machine\System\CurrentControlSet”。

    调用CmpInitializeHive,创建HARDWARE储巢,这是一个易失储巢。然后调用CmpLinkHiveToMaster将它链接到主储巢中。

    接下来,利用加载块参数,将有关当前这次引导的信息写到注册表中:

    • 调用CmpInitializeHardwareConfiguration,创建“\Registry\Machine\Hardware”节点,并且把硬件信息设置到注册表中。
    • 调用CmpInitializeMachineDependentConfiguration函数,把与机器相关的配置数据设置到注册表HARDWARE储巢中。
    • 调用CmpSetSystemValues,将这次系统启动的信息写到注册表中。
    • 调用CmpSetNetworkValue,将这次启动的网络信息写到注册表中。

    因此,CmInitSystem1函数将注册表结构初步建立起来,它构造了主储巢、HKLM\SYSTEM和HKLM\HARDWARE三个储巢,并且也建立起与这次启动有关的符号链接和配置信息,为系统的进一步初始化提供了基本的配置信息。

    再来看注册表的进一步初始化。数组CmpMachineHiveList包含6个储巢,对应于表2.6中的前6个储巢。这些储巢(包括HKLM\SYSTEM和HKLM\HARDWARE)是由会话管理器进程(smss.exe)通过NtInitializeRegistry系统服务加载和初始化的。在一次正常启动过程中,它调用CmpCmdInit函数执行注册表的进一步初始化。在正常启动情形下,CmpCmdInit函数调用CmpInitializeHiveList来初始化储巢列表中的指定储巢,以及建立相应的符号链接。

    由于CmpInitializeHiveList是在会话管理器进程环境中执行的,而加载和初始化储巢的动作必须在System进程中完成,因此,CmpInitializeHiveList会为储巢列表中的每一个储巢创建一个系统线程,由该系统线程来初始化该储巢。系统线程的主例程为CmpLoadHiveThread,参数为每个储巢在CmpMachineHiveList数组中的索引。

    在CmpLoadHiveThread函数中,对于尚未加载的储巢,包括HKLM\SAM、HKLM\SECURITY、HKLM\SOFTWARE和HKU\.DEFAULT,它会调用CmpInitHiveFromFile来完成储巢的加载和初始化;而对于已经被初始化的非易失储巢,即HKLM\SYSTEM,则调用CmpOpenHiveFiles打开系统储巢文件,因为在此之前系统储巢文件实际上一直没有被通过文件系统打开过。经过这一步以后,系统储巢被完全初始化。

    随着系统的进一步引导,当需要特定于用户的配置信息时,注册表的HKU子树下的用户储巢也必须建立起来。这些储巢是按需加载和初始化的,由登录进程(winlogon.exe)在建立起用户运行环境时完成,譬如当用户登录到系统中,或者系统以特定的用户身份来启动一个进程或服务时。Winlogon通过NtLoadKey系统服务将一个储巢文件链接到注册表中,而NtLoadKey又进一步调用CmLoadKey来完成实际的加载和链接操作。

    以上讨论了配置管理器的初始化以及Windows注册表的建立过程。储巢是配置管理器的核心概念,也是注册表存储结构中的文件实体。WRK包含了配置管理器的完整代码,储巢的数据类型为CMHIVE,其内嵌的HHIVE成员是它的数据管理结构。

    巢内部的数据管理类似于一个文件系统,它的数据存储单元按照巢箱来分配,而巢箱以块(4KB大小)为边界;储巢内部的逻辑数据结构为巢室,巢室有不同的类型,其大小亦不尽相同。在配置管理器的实现中,巢室的数据结构为HCELL,巢箱的数据结构为HBIN。空闲的巢箱形成一个空闲链表。实际上,HHIVE数据结构包含两个Storage成员,分别对应于稳定的储巢和易失的储巢;在Storage成员中,有空闲巢箱链表,以及一套用于转译巢室索引的巢室目录和巢室表。

    注册表的层次结构形成了一个名字空间,配置管理器定义了一个以“Key”命名的对象类型,从而将该名字空间与对象管理器的全局名字空间整合起来。配置管理器在初始化阶段调用CmpCreateObjectTypes函数,创建了类型对象全局变量CmpKeyObjectType。配置管理器充分利用了对象管理器提供的对象管理框架,让注册表中的每个键自动成为对象管理器中的一个对象。对于每个打开的注册表键,配置管理器分配一个键控制块(key control block),其数据结构为CM_KEY_CONTROL_BLOCK,它包含了该控制块所引用的键节点所在的储巢和巢室索引。配置管理器将所有的键控制块放在一张散列表(全局变量CmpCacheTable)中,因而可以快速地根据名称来搜索已有的键控制块。散列表CmpCacheTable实际上是一个包含2048个元素的数组,散列表的键ID是由键控制块所引用的键对象的名称通过计算而获得。每个键控制块然后被放到散列表的相应桶中,放到同一个散列桶中的所有键控制块形成一个链表。

    当内核或应用程序访问一个注册表键时对象管理器和配置管理器的名称解析过程。这涉及两个常用的操作:系统服务NtOpenKey和NtQueryValueKey,或者ZwOpenKey和ZwQueryValueKey。根据内核函数的命名约定,我们知道,Nt<Xxx>函数供用户模式应用程序使用,而Zw<Xxx>函数供内核代码直接调用。NtOpenKey和NtQueryValueKey函数,其原型如下:

     这两个函数的代码位于base\ntos\config\ntapi.c文件中。NtOpenKey系统服务接收到的对象名称位于ObjectAttributes.ObjectName中,它检查KeyHandle和对象名称参数是否可以正确地访问,然后将打开注册表键对象的操作全盘交给对象管理器的ObOpenObjectByName函数来完成。从这里也可以看出,注册表的接口与实现,都跟对象管理器的框架融合在一起。

    ObOpenObjectByName函数通过ObpLookupObjectName函数来完成对象打开操作,它层层递进解析一个名称串,若碰到目录对象,则在目录中查询剩余的名称串;若碰到支持Parse方法的对象,则交给Parse方法来解析剩余的名称串。在NtOpenKey的情形中,它的ObjectAttributes参数可能已经指定了一个搜索根目录,即RootDirectory;也可能直接从全局名字空间的根下开始查找,此时调用者应该指定注册表键的全路径名。注册表键的全路径名以“\Registry”作为开始,例如,HKLM\SYSTEM\CurrentControlSet\services的全路径名为“\Registry\Machine\System\CurrentControlSet\services”。

    由于配置管理器已经在全局名字空间的根下创建了一个名为“REGISTRY”的键对象,所以,当ObpLookupObjectName函数解析一个注册表键的全路径名称时,它首先在根目录下找到“REGISTRY”键对象,然后调用键对象类型的Parse方法来解析剩余的名称字符串。键对象类型的Parse方法CmpParseKey函数。CmpParseKey函数的实现并不难理解,它首先调用CmpBuildHashStackAndLookupCache函数,在散列表中查找已经打开的键对象,若能直接找到,则无须进一步名称解析;否则,需要顺序解析剩余的名称串,对于路径上的每一个子键,逐个为它们创建键控制块(通过调用CmpCreateKeyControlBlock函数)。最后,CmpParseKey调用CmpDoOpen函数打开此注册表键,并根据需要创建一个键控制块。

    ObOpenObjectByName函数接收到一个指向键对象的句柄,键对象的数据结构为CM_KEY_BODY,其内部指向一个键控制块。如果两个应用程序打开同一个注册表键的话,它们都会接收到一个键对象,但这两个键对象指向一个公共的键控制块。键控制块有一个引用计数用于跟踪一个键被多少个客户引用。当引用计数为零时,表明该键控制块已不再被使用了,于是配置管理器将它从散列表中移除,并且回收该键控制块。

    NtQueryValueKey函数相对要简单得多,因为它的参数KeyHandle已经指示了要查询哪个键,所以,它只需调用ObReferenceObjectByHandle函数即可获得目标键的键对象。然后它调用CmQueryValueKey函数从目标键中读取指定的值的信息。

    最后值得一提的是,配置管理器提供了注册表键的变化通知机制。应用程序通过调用NtNotifyChangeKey或NtNotifyChangeMultipleKeys系统服务,可以监视一个或多个注册表键的创建、删除和修改动作。实现注册表键变化通知机制的关键在于,每个键对象都有一个类型为CM_NOTIFY_BLOCK的通知块成员,它描述了一个键对象的哪些事件以何种方式被通知到注册方。由于配置管理器提供了这种变化通知能力,因而对于想要监视注册表行为的应用程序,它们无须频繁地检查注册表来判断感兴趣的键是否已被修改。这对于一些安全保护或者注册表行为分析等程序有显著的意义。

     

    展开全文
  • Windows内核原理与实现附带工具

    热门讨论 2012-03-27 19:49:22
    书中提到的所有工具, DPerfLite IRPMon MemMon ProcMem STDViewer EventHandler
  • 开发篇介绍了在实际工作中可能遇到的各种开发需求的技术实现,包括:串口的过滤、键盘的过滤、磁盘的虚拟、磁盘的过滤、文件系统的过滤监控、文件系统透明加密、文件系统微过滤驱动、网络传输层过滤、Windows过滤...
  • 1.3.5 设置Windows内核符号表 12 1.3.6 实战调试first 13 第2章 内核编程环境及其特殊性 16 2.1 内核编程的环境 16 2.1.1 隔离的应用程序 16 2.1.2 共享的内核空间 17 2.1.3 无处不在的内核模块 18 2.2 数据...
  • 稍显枯燥的是,它们和Windows内核无关,是纯C语言汇编语言的关系的章节。如果读者已经精通汇编语言,并能顺利阅读汇编代码,请直接跳过本部分。  第1章 汇编指令C语言 2  1.1 上机建立第一个工程 4  1.1.1 用...
  • 085155 Windows 安全原理与技术 学分 3 学时 48 先修课程 高级语言程序设计操作系统 课程性质 专业选修限选课程 适用专业 信息安全专业 内容简介 Windows 安全原理与技术是信息安全专业网络安全方向专业选修限选课 ...
  • 目录 概述 ·什么是PATCH GUARD? ·PATCH GUARD 执行流程分析 突破手段 ·各系统版本 - 静态突破 ·各系统版本 - 动态突破 ·利用硬件支持进行攻击 ...·安全厂商PATCH GUARD ·关注新机制:HYPER GUARD
  • 打印机驱动在windows中存在已久,它的功能分别由内核模式图形代码和用户空间的打印驱动共同组成。本议题,将会讲述如何在古老的代码中挖掘出新颖的攻击面。专门为用户模式打印驱动设计了一个Fuzz框架,它有效地在...
  • 但是想完成一些特殊的功能,如内核级隐藏进程等,Windows的这些框架就没什么用处了,程序员就需要对Windows内核有全面的了解,通过直接修改Windows内核实现这些目的。往往黑客对这种技术乐此不疲,通过修改Windows...
  • windows 内核 pdf

    2010-05-18 14:17:25
    想学习windows内核的人来看下吧, 里面有官方英文原版和 潘爱民 版的
  • Windows内核调试器原理浅析.doc
  • 寒江独钓-Windows内核安全编程(完整版).pdf 编写Windows内核程序,就意味着这个程序可以执行任意指令,可以访问计算机所有的软件、硬件资源。因此,稍有不慎就有可能将系统变得不稳定。Windows的设计者设计了各种...
    寒江独钓-Windows内核安全编程(完整版).pdf
     
    编写Windows内核程序,就意味着这个程序可以执行任意指令,可以访问计算机所有的软件、硬件资源。因此,稍有不慎就有可能将系统变得不稳定。Windows的设计者设计了各种驱动模型或者框架,如NT式内核驱动模型、WDM框架和新推出的WDF框架。在这些模型框架下编程,就使内核编程变得简单,同样也降低了内核程序崩溃的机会。其实,Windows驱动程序员和黑客都在写内核程序,唯一不同的是驱动程序员按照微软设计的模型写程序,而黑客可以不按照这些框架写。Windows设计的这些框架,可以将操作系统的原理隐藏起来,只暴露一些接口,驱动程序员只要把这些接口写好就可以了。从这个角度看,驱动开发并不难,尤其是读完本书后,更会觉得不难了。但是想完成一些特殊的功能,如内核级隐藏进程等,Windows的这些框架就没什么用处了,程序员就需要对Windows内核有全面的了解,通过直接修改Windows内核来实现这些目的。往往黑客对这种技术乐此不疲,通过修改Windows内核,你会发现你的程序几乎无所不能。
      编写内核程序是一件很痛苦的事情,回想起这些年学习内核程序开发的经历,真是感慨万千。就如同谭文所说:编写内核程序的人从某种程度讲是孤独的。当一个经验并不丰富的小程序员面对庞大复杂的并且不开源的Windows框架时,那是一种怎样的无助感啊!谭文是我比较钦佩的程序员之一,他对技术非常执着,并且精力充沛。内核程序的知识涉及面非常广,不同类别的内核程序差别也特别大,他几乎都有所涉猎。相信读者在读完这本书后,能对Windows内核开发有比较详细的了解,同时也能结合书中的实例写出很优秀的内核程序了

    本书从Windows内核编程出发,全面系统地介绍了串口、键盘、磁盘、文件系统、网络等相关的Windows内核模块的编程技术,以及基于这些技术实现的输入密码保护、防毒引擎、文件加密、网络嗅探、网络防火墙等信息安全软件的核心组件的具体编程。主要知识重点包括:Windows串口与键盘过滤驱动、Windows虚拟存储设备与存储设备过滤驱动、Windows文件系统过滤驱动、文件系统透明加密/解密驱动、Windows各类网络驱动(包括TDI过滤驱动及3类NDIS驱动),以及最新的WDF驱动开发模型。有助于读者熟悉Windows内核驱动的体系结构,并精通信息安全类的内核编程技术。本书的大部分代码具有广泛的兼容性,适合从Windows 2000一直到目前最新的Windows 7 Beta版。

     本书则基本上介绍的是正统的内核编程技术,是微软在内核编程中给信息安全软件开发者提供的相关接口的大集合,是名门正派的技术,不沾邪气。一个好的内核程序员,“正邪兼修”是有必要的。
      本书既适合于有志于成为软件程序员的学生使用,也适合于希望加强自己的技术实力的Windows程序员阅读,同时更适合于从事信息安全行业的Windows软件的开发者作为手头参考。
    第一部分 基础篇 
    第1章 前置要求与环境搭建 
    1.1 驱动编程的语言 
    1.2 开发环境搭建 
    1.2.1 Visual Studio 2005/2008的安装与配置 
    1.2.2 WDK的安装与配置 
    1.2.3 VisualDDK的安装与配置 
    1.3 常用工具介绍 
    第2章 内核编程基础知识 
    2.1 Windows主要系统组件 
    2.1.1 对象管理器 
    2.1.2 内存管理器 
    2.1.3 进程和线程管理器 
    2.1.4 I/O管理器 
    2.1.5 PnP管理器 
    2.1.6 电源管理器 
    2.1.7 配置管理器 
    2.1.8 安全引用监视器 
    2.2 常见名词解释 
    2.2.1 内核名词 
    2.2.2 文件名词 
    2.2.3 网络名词 
    2.3 常见内核数据结构 
    2.3.1 驱动框架常见数据结构 
    2.3.2 进程与线程数据结构 
    2.3.3 存储系统数据结构 
    2.3.4 网络数据结构 
    2.3.5 其他一些常见的数据结构 
    第3章 基本编程方法 
    3.1 简单的NT式驱动模型 
    3.1.1 驱动模型的选择 
    3.1.2 NT式驱动程序基本结构 
    3.1.3 编译驱动程序 
    3.1.4 加载驱动及查看输出信息 
    3.2 应用层与内核的通信方法 
    3.2.1 访问数据的I/O方式 
    3.2.2 读写驱动程序 
    3.2.3 发送I/O控制码 
    3.2.4 内存共享 
    3.3 同步技术 
    3.3.1 事件对象 
    3.3.2 信号灯对象 
    3.3.3 互斥体对象 
    3.3.4 定时器对象 
    3.3.5 自旋锁 
    3.3.6 回调对象 
    3.3.7 原子操作 
    3.4 IRP处理 
    3.4.1 简单的IRP流动图 
    3.4.2 IRP的创建 
    3.4.3 IRP的发送 
    3.4.4 为IRP设置完成函数 
    3.4.5 IRP的完成 
    3.4.6 多种典型的 IRP处理示例 
    3.5 字符串操作 
    3.5.1 STRING、ANSI_STRING和UNICODE_STRING 
    3.5.2 初始化和销毁 
    3.5.3 复制和添加 
    3.5.4 比较 
    3.5.5 转换 
    3.6 内存管理 
    3.6.1 分配系统空间内存 
    3.6.2 运行时库管理函数 
    3.6.3 使用内核栈 
    3.6.4 使用Lookaside快速链表 
    3.6.5 访问用户空间内存 
    3.6.6 内存区对象和视图 
    3.6.7 MDL的使用 
    3.7 注册表编程 
    3.7.1 注册表对象管理函数 
    3.7.2 注册表运行时库函数 
    3.7.3 注册表调用过滤 
    3.8 文件编程 
    3.8.1 打开文件句柄 
    3.8.2 执行相关文件操作 
    3.9 其他 
    3.9.1 本地系统服务函数的Nt 
    和Zw版本 
    3.9.2 NTSTATUS返回值 
    3.9.3 双向链表的使用 
    3.9.4 异常处理 
    第二部分 提升篇 
    第4章 进程 
    4.1 进程监控实现原理 
    4.2 Windows 7系统下的进程 
    监控软件实例 
    4.2.1 内核模块程序实现 
    4.2.2 用户模式程序实现 
    4.3 安装与使用 
    第5章 磁盘 
    5.1 存储驱动体系结构 
    5.2 设备树示例 
    5.3 diskperf磁盘过滤驱动 
    5.3.1 diskperf介绍 
    5.3.2 diskperf的过滤框架 
    5.3.3 diskperf的PnP支持 
    5.3.4 diskperf的硬盘访问监控和性能数据捕获 
    5.3.5 diskperf的电源支持 
    5.3.6 diskperf的安装与测试 
    第6章 键盘 
    6.1 原理跟踪 
    6.1.1 自下而上的过程 
    6.1.2 自上而下的过程 
    6.2 几种常见的键盘记录行为 
    6.2.1 应用层的消息钩子 
    6.2.2 键盘过滤驱动 
    6.2.3 键盘类驱动的分发函数Hook 
    6.2.4 DKOM技术 
    6.2.5 其他方法 
    6.3 反键盘记录 
    6.3.1 实现原理 
    6.3.2 反键盘记录示例 
    第7章 文件 
    7.1 原理跟踪 
    7.1.1 Windows存储栈 
    7.1.2 不涉及缓存的数据存储 
    7.1.3 涉及缓存的数据存储 
    7.2 简单的文件隐藏 
    7.2.1 文件隐藏的原理 
    7.2.2 文件隐藏的实现 
    7.3 scanner扫描程序 
    7.3.1 过滤管理器与微过滤驱动概念 
    7.3.2 使用过滤管理模型的优势 
    7.3.3 微过滤驱动的加载和卸载 
    7.3.4 用户模式和内核模式的交互 
    7.3.5 scanner介绍 
    7.3.6 scanner驱动程序 
    7.3.7 scanner应用层程序 
    7.3.8 scanner的安装与使用 
    第8章 网络 
    8.1 原理跟踪 
    8.2 NDIS协议驱动 
    8.2.1 DriverEntry 
    8.2.2 绑定 
    8.2.3 数据发送 
    8.2.4 数据接收 
    8.2.5 数据流动总结 
    8.3 OPEN_BLOCK的展示 
    8.3.1 原理知识 
    8.3.2 相关代码 
    第三部分 辅助篇 
    第9章 安全编码 
    9.1 蓝屏的概念 
    9.2 创建可靠的驱动程序 
    9.2.1 验证设备对象 
    9.2.2 使用安全字符串 
    9.2.3 验证对象句柄 
    9.2.4 支持多CPU 
    9.2.5 确认驱动状态 
    9.2.6 IRP安全检查 
    9.3 使用驱动验证程序 
    9.3.1 驱动验证程序的测试选项 
    9.3.2 使用驱动验证程序 
    第10章 调试与逆向 
    10.1 静态调试 
    10.1.1 静态调试驱动程序 
    10.1.2 静态调试应用程序 
    10.2 动态调试 
    10.2.1 双机调试的基本方法 
    10.2.2 WinDbg的常用命令 
    10.2.3 WinDbg的使用技巧 
    10.3 逆向与调试相结合 
    10.3.1 示例

    2018.8.13链接已补
    点击下载:寒江独钓-Windows内核安全编程(完整版).pdf
    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,946
精华内容 2,378
关键字:

windows内核原理与实现pdf