windows核心编程系列学习记录3——内核对象

简单写一些自己的总结吧,其实这一章比较务虚,概念都是抽象的,不是特别容易一下子看明白。

1、内核对象:是一个操作系统内核分配的,包含一个数据结构的内存块,具体成员与对象有关,只有少数成员是所有对象都有的。内核对象只能操作系统内核访问,应用程序需要利用Windows提供的一组函数来操作这些结构,调用创建内核函数后会返回一个句柄。

2、句柄:独立于每个进程的句柄表的索引,并不是简单的指针指向内核对象的内存块。所以将句柄传给另一个进程的线程调用是一件很危险的事情,轻则调用失败,重则是该进程的句柄表中存在该索引,导致操作到一个完全不同且你不知道的内核对象,很危险的行为。当然,后面有“跨进程边界共享内核对象”的机制可以实现多个进程成功共享一个内核对象。

3、计数机制:内核对象的所有者是操作系统内核,而非进程。也就是说多个进程可以共享一个内核对象。内核对象数据结构内有一个使用计数成员,它是所有对象都有的一个成员,标识该内核对象被引用的次数。刚创建时使用计数被初始化为1,如果有另一个进程获得对此内核对象的访问后,使用计数就会递增。一个使用此内核对象的进程终止后或是对此内核对象调用CloseHandle,操作系统内核会自动递减内核对象的使用计数。一旦计数变为0,操作系统内核就会销毁对象。

3、安全描述符:内核对象可以用一个安全描述符SD来保护,描述了谁拥有,可以使用,不能使用该内核对象。安全描述符对应一个数据结构:SECURITY_ATTRIBUTES结构,几乎内核对象在创建时都需要传入此结构,但是大部分情况下都是传入NULL,表示使用默认的安全性。除了使用内核对象,应用程序还需要使用其他类型的对象,如菜单、窗口、鼠标光标等,这些属于用户对象或GDI对象,而非内核对象。要想判断一个对象是不是内核对象,最简单的方式就是查看创建这个对象的函数,几乎所有的创建内核对象的函数都需要指定安全属性信息的参数,而用于创建用户对象的函数则都不需要。

4、句柄表:一个进程在初始化时,系统将为它分配一个句柄表,且为空。它只是一个由数据结构组成的数组,每个结构都包含一个内存对象的指针,一个访问掩码和一些标志。

5、创建内核对象:当进程内的一个线程调用创建内核对象的函数时,内核将为这个对象分配并初始化一个内存块,然后扫描进程的句柄表,查找一个空白的记录项,并对其进行初始化。指针成员将会被初始化为内核对象的地址,继承标志也会被设置。用于创建内核对象的函数都会返回一个与进程相关的句柄,此句柄可由属于该进程的所有线程引用。调用一个函数,如果它需要一个内核对象句柄的参数,就必须为它传递一个句柄。在内部,这个函数会查找进程的句柄表,获得目标内核对象的地址然后对此数据结构进行操作。如果我们直接使用其他进程的的句柄,那么实际引用的只是那个进程句柄表中位于同一索引的内核对象,我们根本不知道它会指向什么对象。创建内核对象的函数在失败时会返回NULL。但有时也有的函数会返回-1,如CreateFile,它返回的是INVALID_HANDLE_VALUE而不是NULL。失败的原因可能是内存不足或是没有权限。这在检查内核对象是否创建成功时要特别注意。

6、关闭内核对象:调用CloseHandle向系统申请关闭内核对象。在内部该函数会扫描进程的句柄表,如果句柄是有效的,系统就获得此内核对象的数据结构的地址,并将此结构的使用计数成员递减1。如果使用计数变为0,句柄表对应的记录项将会被清除,内核对象将被销毁,所占内存将会被释放。此后再在此进程内使用此句柄将会发生未知错误。即使在进程结束了对内核对象的访问后,没有调用CloseHandle,进程终止时,操作系统也会确保进程所使用的所有资源都被释放。在任务管理器的Handle列可以查看每个进程占用的内核对象数。

7、跨进程边界共享内核对象:使用对象句柄继承、命名对象、复制对象句柄。其实跨进程边界共享内核对象我到目前没有用到过,所以也不作过深的了解啦。用到的时候再做补充。

8、这章应该就这些知识点吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值