• Windows Internals 6th chap3 cont.


    Page 140 Object manager 1)提供了统一的使用系统资源的机制 2)提供一个集中的位置去保护对象 3)提供一种去管理进程配额的机制 4)提供对象命名的机制 5)对象隔离 6)对象持久化

    Page 143 Win7执行体共定义了42种对象,大部分只供执行体使用,其中一部分通过windows API暴露给用户程序使用。

    Page 145 每个对象都有对象头和对象体.对象头由object manager控制,对象体由创建改对象体的执行体组件拥有并控制.每个对象头都指向该对象的type object. Object manager利用对象头中的数据来管理对象.有5个可选的子对象头: name information header, quota information header, process information header, creator information header, handle information header.

    Page 147 所有通过win32 API创建的对象都位于BaseNamedObjects目录下,这是kernel32.dll创建对象是所选择的根对象目录.

    Page 148 对象体的格式和内容完全有创建改对象体的执行组件控制,执行体对象通常创建对象体并提供一组操作该对象体的服务(有面向对象的意思). 对象头的大小是固定的,利用指向对象体的指针可以直接找到对象头,也可以找到可选子对象头. 

    Page 149 基于对象头和可选子对象头中的信息,object manager提供了一下可以适用于所有对象的通用服务,其中一部分通过windows子系统暴露给windows应用程序实用.通用服务有:

    Close/Duplicate/Query Object/Query Security/Wait for a single object/Wait for multiple objects/etc.

    另外一些服务,比如Create/Open由每种对象自己提供(可以由object manager实现但代码过于耦合,复杂).

    Page 153 Synchronization refer to a thread's ability to synchronize its execution by waiting for an object to change from one state to another. 一个对象要支持同步,必须满足下面三个条件之一:

    1) 该对象wrap了一个分发器对象,包含了一个分发器头;

    2) 该对象类型的创建者要求一个default object, ojbect manger为其提供了一个

    3) 该对象内部嵌有一个分发器对象, 并且该对象的所有者在注册对象类型时将其偏移告诉了object manager. e.g. File objects内部有一个event分发器对象,file object type的type initializer中的default object是一个指向该event的偏移.

    Page 154 对象方法可以视为是对c++构造/析构函数的扩展,共有8种对象方法,object manager会在对象的生命周期内各个时间点调用相应的方法,对象方法由执行体重创建该对象的模块实现,是对对象操作的细化,类似于c++中的虚方法.每种对象类型可以提供这些方法,也可以不提供.

    主要方法如下: Open/Close/Delete/Query name/Parse/Dump/Okay to close/Security

    Parse(Query name)方法允许object manger在发现某个对象存在于其名字空间之外时释放控制权以便去另外的名字空间查找. 当object manager查找对象时,如果发现对象有parse/query name方法, 对象管理器会调用相应的parse方法,并将剩余的名字当作参数. 使用parse方法的例子:注册表名字空间/文件系统名字空间. 以文件系统名字空间为例: 某个进程打开文件DeviceHarddiskVolume1docs esume.doc,对象管理器会遍历自己的名字空间直到DeviceHarddiskVolume1,然后发现对象DeviceHarddiskVolume1有parse方法, 对象管理器会调用该方法并传入参数docs esume.doc, 由此IO manager的parse方法得到控制权,会调用相应的文件系统驱动去查找该文件

    Page 155 文件对象的security 方法与众不同,因为文件对象的security信息存放于文件中而非内存中.

    Page 158 对象句柄是进程句柄表的一个索引, 通过EPROCESS可以找到进程句柄表,句柄表中包含该进程曾经打开过句柄的所有对象的指针. 

    Page 159 Handle table entry的结构(以32为系统为例)

    Pointer to object header A I L
    Access mask     P

    L:该entry是否正在使用中,可用来判断该handle是否有效.

    Page 160 内核句柄表--该句柄表中的handle只有内核模块可以访问,用户程序不可访问. 内核句柄表同时也是system进程的句柄表.当使用一个句柄时,对象管理器通过句柄的值来决定该访问当前进程的句柄表还是内核句柄表---所有的内核句柄最高位都被置为1,也即句柄值>0x80000000.

    Page 163 在打开对象时必须指明所需要的访问权限,SRM会检查该对象的安全描述符来确定调用者是否有相应的权限, 然后grant相应的权限并返回句柄.后续操作SRM不会再做安全性检查,对象管理器会利用句柄表中相应entry的access mask来判断是否允许操作.如果open时只指定write权限,后续要去read,会被拒绝.

    Page 165 Most objects are temporary; they exist as long as they are in use, and then they are freed by the object manager. Objects can be created that are permanent. If an object is permanent, the object manager itself holds a reference to the object. Thus, its reference count remains greater than zero, and the object is not freed when it is no longer in use.

    A temporary object can be accessed by name only as long as its handle count is nonzero. Once the handle count decrements to zero, the object's name is removed from the object manager's namespace. Such objects can still be accessed by pointer as long as their reference count remains greater than zero.

    这是name retention, 此时,对象有可能还在,但用户态程序无法打开handle,因该名字已不在对象管理器的名字空间.

    object retention -- ref count为0时,对象被删除.

    Permanent objects can be accessed by name as long as they exist.

    Page 166 当对象的引用计数为0时,该对象管理器会从内存中删除该对象. 需要注意的是,是在合适的时机被删除,比如如果在高IRQL时引用计数变为0,如果直接删除且对象在page-pool会造成系统crash

    Page 169 给对象命名的三个目的 1) 可以区别对象 2) 便于查找 3) 可以多进程之间共享对象. 为了效率,对象管理器仅在创建对象/打开对象时做name lookup.

    Page 174 每个session都有自己的session namespace. 如果想访问全局名字空间要在对象名字前加Global.

    Page 179 高IRQL的同步: 内核必须保证跨CPU的互斥.高IRQL同步的难点是不能引入re-schedule或者page fault (不能wait)

    做法1: Interlocked操作,依赖硬件支持去保证即使在多CPU的情况下也是原子操作,在x86系统上,主要是用lock instructioin prefix去锁住多处理器总线.

    Page 180 做法2: Spinlock--约定:所有调用者在访问需要同步的数据时都要先acquire对应的spinlock,只有在拿到spinlock时才能访问数据,如果拿不到,busywait直到锁free. 每个spinlock都有一个相关联的IRQL (>=DISPATCH_LEVEL), 试图去获得spinlock回提升当前CPU的IRQL到spinlock的IRQL,因此该CPU将100% busy wait.

    当需要与ISR同步数据时调用KeAcquireInterruptSpinLock, 驱动也可以用KeSynchronizeExecution去和ISR同步整个函数

    Spinlock的实现主要靠硬件支持的test-and-set操作(lock bts),多处理器情况下会给处理器总线带来压力,因此伸缩性不好.

    Page 181 为了解决伸缩性问题而引入了Queued spinlock. 具体做法如下:当处理器试图去获得spinlock时,如果该spinlock已经被占用,该处理器在spinlock的queue中放入自己的一个标识,然后一直检查一个per-processor标记(而非spinlock本身).当spinlock的当前所有者释放该锁时,会把锁转给queue中的第一个标识锁标记的处理器(通过set该processor的per-processor标记). 

    Page 182 驱动开发者可以用Instack queued spinlock. Exclusive Interlocked操作--built on spinlock

    Page 183 低IRQL的一些同步机制: 1) 内核分发器对象 2) Fast mutexes & Guarded mutexes 3) ERESOURCES 4) Pushlocks, 还有一些用户态的同步原语 5) CondVars 6) Slim reader-writer locks 7) InitOnce 8) Critical sections

    Page 184 Windows API中的同步对象之所以有同步能力是因为内部包含了分发器对象.

    Page 185 当线程等待一个分发器对象时,内核将线程放入等待状态.当相应的分发器对象被signal时,内核会去检查是否有线程在等待该对象,若果其等待条件满足,则离开等待状态.

    Page 186 各种分发器对象进入signal状态的标准不一样:

    Object type                     Set to signal state when                          Effect on waiting threads

    ===============================================================

    Process                          Last thread terminates                             All are released

    Thread                           Thread terminates                                   All are released

    Event (notification)          Thread sets the event                              All are released

    Event (synchronization)   Thread sets the event                              One thread is released. Event is reset

    Timer (notification)           Expires                                                  All are released

    Timer (synchronization)    Expires                                                  One thread is released

    Semaphore                     Count drops by one                                One thread is released

    Mutex                            Thread release the mutex                         One thread is released and takes the ownership of the mutex

    Queue                            Item is placed on queue                           One thread is released

    Page 188 支持对象同步能力的3关键数据结构(记录"谁"在等, 等"什么", "怎么"等, 等待操作处于"哪个"状态): Dispatcher header, wait block, wait status register.

    Dipatcher header: packed 结构(union,复用某些域),记录对象类型,signal状态,已经等待该对象的线程列表.

    Wait block: represents  a thread waiting for an object, 每个等待状态的线程都有一个wait blocks列表表明该线程所等待的对象, 每个分发器对象也都有一个wait blocks列表表明所有等待该对象的线程. 所以wait block包含1) 指向被等待对象的指针 2) 指向线程的指针 3) 指向下一个wait block的指针(如果该线程同时等待多于一个对象) 4) 等待的类型(wait any/wait all) 5) 该对象在WaitForMultipleObjects的Handles数组中的位置(如果只等待一个对象则为0)

    Page 194 Keyed Event是自xp开始引入的进程内同步机制 (并没有暴露给用户态程序使用)。Basically you register a wait on a PVOID value, and you'll block until another thread in the same process signals with the same PVOID value。 Keyed Event引入的原因是为了解决低memory环境下ciritical section不可用的问题。 Critical section正常情况下用auto reset event,在低memory情况下,fallback到global的keyed event, 通常key选择为critical section的地址。 从vista开始,Keyed event被用来实现slim reader-writer lock, conditional variable, init once. http://joeduffyblog.com/2006/11/28/windows-keyed-events-critical-sections-and-new-vista-synchronization-features/

    Page 196 Holding a mutex object implicitly places the holder within a critical region. Holding a guarded mutex implicitly places the holder within a guarded region. Holding a fast mutex implicitly raises the current IRQL to APC_LEVEL.

    The system provides three mechanisms to disable APCs for the current thread:

    • Critical regions. When a thread is inside a critical region, its user APCs and normal kernel APCs are not executed. Special kernel APCs are still executed. For more information about these APC types, see Types of APCs.

    • Guarded regions. When a thread is inside a guarded region, none of its APCs are executed.

    • Raising the current IRQL to APC_LEVEL or higher. A thread that is executing at IRQL >= APC_LEVEL executes with all APCs disabled.

    Page 209 ALPC是windows实现的高速,可伸缩,安全的IPC机制,可用于在多个用户进程之间,或者内核模块和用户进程之间进行数据交换.ALPC广泛应用于操作系统组件之间,比如SRM和LSASS.exe, WinLogon.exe和LSASS.exe

    Page 210 ALPC采用经典的c/s模型,可用于server和连接该server的多个用户进程之间进行消息传递.

    连接模型

                                   client                                         server

    1.                                                                        server创建named connection port

    2.                                                                        server listen on connection port

    3.            client连接connection port

    4.                                                                        server接收connect请求,server & client communication port are created

    5. client & server利用communication port进行通信

    Page 211 通信模型 -- 支持同步和异步操作.三种交换信息方式:

    1) <= 256 bytes 双缓存机制,从源进程复制到内核,继而从内核复制到目标进程

    2) >256 bytes, 利用section object,同时映射到源进程和目标进程

    3) 特别大量的数据, server直接读写client的地址空间

    Page 213 LPC利用了同步模型,容易死锁切不易扩展.ALPC扩展了LPC,支持异步操作,有三种异步通知方式. 1) ALPC completion list  2) 完成端口 completion port 3) executive callback,主要供驱动使用

    安全

    性能

    调试

  • 相关阅读:
    【Python】格式化输出json
    【flask】处理表单数据
    【flask】使用Flask-WTF处理表单
    【html】合并单元格,并居中显示文本
    testng失败重跑
    Maven安装以及使用
    使用extentreports美化testng报告2,增加监听
    使用extentreports美化报告
    获取在控制台输入命令后的结果
    mysql的慢查询实战+sql优化
  • 原文地址:https://www.cnblogs.com/littledot/p/3462281.html
Copyright © 2020-2023  润新知