1 .1内核对象的概念
内核对象是内核分配的一个内存块,这种内存块是一个数据结构,表示内核对象的各种特征。并且只能由内核来访问。应用程序若需要访问内核对象,需要通过操作系统提供的函数来进行,不能直接访问内核对象(Windows从安全性方面来考虑的)。
内核对象通过Create*来创建,返回一个用于标识内核对象的句柄,这些句柄(而不是内核对象)可在创建进程范围内使用,不能够被传递到其他进程中被使用。
1 .2内核对象使用的计数
因为内核对象的所有者是内核,而不是进程,所以何时撤销内核对象由内核决定,而内核做这个决定的依据就是该内核对象是否仍然被使用。那么如何判断内核对象是否被使用呢?可以通过内核对象的“使用计数”属性,一旦这个值变成0了,内核就可以释放该对象了。
1 .3创建内核对象
1 .3.1进程与句柄表
每个进程在初始化的时候,将被分配一个句柄表,该句柄表中只存储内核对象的句柄,不存储用户对象的句柄。句柄表的详细结构微软没有公布,但是大致包含三个内容:内核对象句柄,内核对象地址,访问屏蔽标志。
微软为何要将内核对象的句柄设置为进程相关的呢?理由有:
l 不同的进程对内核对象的访问权限是不同的,有必要区分对待
l 如果句柄是全局的,则一个进程可以控制另外一个进程的句柄,破坏另外一个进程的句柄。
1 .3.2创建内核对象及操作系统内部机制
利用CreateSomeObject的函数来创建内核对象。调用该函数的时候内核就为该对象分配一个内存块,并进行初始化,然后内核再扫描该进程的句柄表,初始化一条记录并放在句柄表中。
1 .3.3进程中使用内核对象的内部机制
假设函数F使用某个内核对象,其参数为Handle1,则该函数内部需要查找该进程的句柄表,找出参数句柄对应的记录,然后才能使用该内核对象。
1 .4关闭内核对象
无论进程怎样创建内核对象,在不使用该对象的时候都应当通过Bool CloseHandle(HANDLE hobj)来向操作系统声明结束对该对象的访问。为什么叫声明呢?是因为此时也许还有其他进程对该对象的访问,操作系统可能并不立即释放该对象。操作系统需要做的是:从进程的句柄表中删除该内核对象的记录,另外再考察该内核对象的使用计数以决定是否需要释放该对象。