内核对象

本文转载 

https://blog.51cto.com/12731497/2123554

https://blog.csdn.net/zhanghuiyi222/article/details/9844699 

什么是内核对象?

内核对象是操作系统为一些系统级的对象(像进程,线程,信号量)维护的一些数据结构。这些数据构保存了与系统级对象相关的系统级信息。例如:所有内核对象都会保存该对象的引用计数。进程对象会保存进程ID。文件对象会保存当前字节偏移量,共享模式,打开模式等。操作系统中所有内核对象对是保存在一块内存空间中,系统上所有的进程都共享这一块内存空间。内核对象使用计数器, 当计数器减为0时,内核释放此内核对象资源。一般创建内核对象都有SECURITY_ATTRIBUTES(安全属性)这个参数,传NULL使用默认安全属性。主要的内核对象有:访问令牌(access token)对象、事件对象、文件对象、文件映射对象、I/O完成端口对象、作业对象、mailslot对象、mutex对象、pipe对象、进程对象、semaphore对象、线程对象、waitable timer对象以及thread pool worker factory对象等等。作为Windows开发人员,我们经常都要创建、打开和处理内核对象。当我们在会话中启动一个应用程序,那么当应用程序载入内存,就会生成一个进程(这是一个主调进程)。每个进程对应都有一个虚拟地址空间,然后由内存管理程序对虚拟地址空间和物理地址空间的转换。进程的虚拟内存空间分为内核层和应用层,每个内核对象,其实就是一块内存块,这个内存块位于操作系统的内核地址空间(内核层),而用户的应用程序运行在应用层,注意:这里都是说明在虚拟地址空间,然后会映射到真正的物理地址空间中。而内核对象是由操作系统内核分配的,并只能由操作系统内核访问。因此,应用程序不能直接操作内核对象,需要用Windows系统给定的函数来操作。每一个内核对象都有特定的创建函数和操作函数。所以,当一个主调进程里调用了创建一个内核对象函数,那么这个内核对象(内存块)就会在进程的虚拟内存空间的内核层里,实际映射到物理内存的操作系统内核区域。内核对象这个内存块是一个数据结构,其成员维护着与对象相关的信息。

使用计数和安全描述符

我们上节说到,内核对象这个内存块实际是一个数据结构,内核对象的结构分为两个部分:公用部分(安全描述符(security descriptor,SD),使用计数)和特有部分。其中特有部分,例如:进程内核对象有一个进程ID、一个基本的优先级和一个退出代码。使用计数是每一个内核对象都有的一个数据成员,当有一个内核对象被创建时,使用计数被设为1,当另一个进程获得对现有内核对象的访问后,使用计数就会递增,进程终止运行后,操作系统内核将自动递减此进程仍然打开的所有内核对象的使用计数,如果一旦内核对象的使用计数为0,操作系统内核就会销毁该内核对象。安全描述符描述了谁拥有内核对象,哪些组和用户被允许访问或使用此对象,哪些组和用户被拒绝访问或使用此对象。用于创建内核对象的所有函数几乎都有一个指向SECURITY_ATTRIBUTES结构的指针作为参数

内核对象句柄表

一个进程在初始化时,系统为进程分配了一个内核对象句柄表。下图显示了一个进程的句柄表。可以看出内核对象句柄表是一个由数据结构组成的数组,每个结构都包含索引、指向一个内核对象内存块的指针、一个访问掩码和一些标志(例如:是否可被继承的标志,在创建内核对象就被指定了)。

创建内核对象

一个进程首次初始化的时候,其内核对象句柄表为空。然后,当进程中的线程调用创建内核对象的函数时,比如CreateFileMapping,操作系统内核就为该对象分配一个内存块,并对它初始化。这时,操作系统内核对进程的句柄表进行扫描,找出一个空项。操作系统内核找到索引1位置上的结构并对它进行初始化。该指针成员将被设置为内核对象的数据结构的内存地址,访问屏蔽设置为全部访问权,同时,各个标志也作了设置。我们可以看到这些创建内核对象的函数签名,参数都有一个SECURITY_ATTRIBUTES结构参数,然后返回一个内核对象句柄,这个句柄值其实就是作为内核对象句柄表的索引来使用的,所以这些句柄是与当前这个进程相关的,无法供其他进程使用,如果我们真的在其他进程中使用它,那么实际引用的只是那个进程的句柄表中位于同一个索引的内核对象----只是索引值相同而已。

关闭内核对象

无论怎样创建内核对象,都要向系统指明将通过调用CloseHandle函数来结束对该对象的操作,调用这个函数,函数内部会先检查主调进程的句柄表,看下主调进程对这个内核对象句柄是否有权访问。如果内核对象句柄是有效的,系统将获得内核对象的数据结构的地址,并将结构中的使用计数成员递减。如果使用计数变成0,内核对象将被销毁,并且清除对应内核对象句柄表中对应的记录项;如果使用计数递减后不为0,说明其他进程还在使用该内核对象,那么只清除对应内核对象句柄表中对应的记录项,不销毁内核对象。

 

 

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值