windows 内核对象

以前老是分不清内核对象,用户对象。最近研究了一下这2个对象的使用,特别是内核对象的使用。

在系统中,对象分两类:内核对象和用户对象。 

内核对象:访问令牌对象,文件对象,文件映射对象,I/0完成端口对象,事件对象,互斥量对象,信号量对象,线程对象,进程对

象,作业对象,邮件槽对象,管道对象,可等待计时器对象,线程池工厂对象,使用WinObj工具可以查看有哪些内核对象。

用户对象:窗口,菜单等都是用户对象。

两者是有差别的,用于标示用户对象的句柄是系统唯一的,也就是说,一个进程完全可以对另外一个进程中的用户对象进行操作,比如两个进程间通信的方法之一,就是发送消息。正是由于窗口是用户对象,所以句柄是系统唯一,通过FindWindow(),得到另外一个进程的窗口句柄,然后用SendMessage(),让hWnd的窗口过程来处理消息,实现了进程间的通信。因此,对于用户对象,你根本不用DuplicateHandle(),直接把句柄拿来用就行了。

还有一个方法可以区分是否我内核对象:看创建对象的函数是否带有一个PSECURITY_ATTRIBUTES(安全描述符)的参数,如果有这个参数,则这个函数为创建一个内存对象的函数。

下面对内核对象做详细介绍:

1.内核对象在操作系统中是如何被进程使用的

内核对象是由操作系统内核创建的,所以内核对象也是系统级的,但是是和进程相关的。系统每创建一个进程,就会给这个进程分配一个进程句柄表,这个句柄表里面的句柄会关联到具体的内核对象。这个句柄的大致结构如下图:


由此我们可以知道,我们平时在进程里面使用的内核对象句柄,只是进程内核对象句柄表的一个索引下标。

如果要到另外一个进程里面也要使用这个内核对象,则要到对应进程的句柄表里面建立一个句柄,然后把这个句柄指向实际的内核对象,这样内核对象的使用计数会加1,开始为1,现在变成2了,当我们调用CloseHandle函数关闭内核对象句柄的时候,函数调用进程会在进程句柄表里将对应的句柄清除掉,使当前进程不能再使用该句柄,但操作系统内核并不会马上关闭内核对象,只是将对应的内核对象使用计数减1,当使用计数变成0时,操作系统内核才会关闭内核对象。

可以使用windows的任务管理和Process Explorer工具查看进程的句柄。

2.跨进程边界共享内核对象

下面介绍3种不同的机制来允许进程共享内核对象。

a.使用对象句柄继承:

这里要注意2个地方,第一个地方是创建内核对象的时候,SECRITY_ATTRIBUTES参数里面的 bInheritHandle 应该我 true.这个参数的目的是将这个句柄创建成为一个可继承的句柄。句柄表里面的继承标志项为true.

还有一个地方是调用创建子进程的函数CreateProcess的第5个参数应该为true.这里的目的是让子进程继承父进程里面可继承的句柄。

子进程继承到父进程的句柄以后,子进程自己不知道继承了哪些句柄,必须要父进程告诉子进程。这里可以通过命令行参数传递,发送消息的方式传递,环境变量继承的方式传递。

另外还有一个值得注意的地方就是,当一个内核对象已经创建完成,但是没有设置成可继承的句柄,那这样怎么让子进程继承这个句柄呢,这里有一个函数出现了 SetHandleInformation,调用这个函数可以改变一个句柄的可继承标志,使用情况如下:

打开可继承标志:SetHandleInformation(hObj,HANDLE_FLAG_INHERIT,HANDLE_FLAG_INHERIT);

关闭可继承标志:CloseHandleInformation(hObj,HANDLE_FLAG_INHERIT,0);

再追加一个函数 GetHandleInformation,检查一个内核对象句柄是否可以继承,使用如下:

DWORD dwFlags;

GetHandleInformation(hObj,&dwFlags);

BOOL bHanldeIsInheritable=(0!=(HANDLE_FLAG_INHERIT & dwFlags));

b.为对象命名

c.复制对象句柄










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值