内核对象与句柄的关系
来源:互联网 发布:淘宝上的ica麦片真货 编辑:程序博客网 时间:2024/05/24 01:08
一:一个对象是不是内核对象,通常可以看创建此对象API的参数中是否需要:PSECURITY_ATTRIBUTES 类型的参数。
二:内核对象只是一个内存块,这块内存位于操作系统内核的地址空间,内存块中存放一个数据结构(此数据结构的成员有如:安全描述符、使用计数等)。
三:每个进程中有一个句柄表(handle table),这个句柄表仅供内核对象使用,如下图:
四:解开此中的秘密
比如调用创建一个线程的API:
HANDLE hThread ;
DWORD threadId;
hThread = CreateThread(... , &threadId);
此时发生的事情是:系统查找句柄表,找到一项可用的分配给以上创建的线程;,hThread >> 2 得到句柄在句柄表中的索引(Windows操作系统内部使用hThread最后两位,所以
右移两位得到真正的索引);也是此时内核对象被创建,其数据结构中的引用计数初始为1(这样理解:只要内核对象被创建,其引用计数被初始化为1),这里实则发生两件事:创建了一个内核对象和创建线程的函数打开了此对象,所以内核对象的引用计数加1,这时引用计数就为2了。
当调用CloseHandle(hThread); 时发生这样的事情:系统通过hThread计算出此句柄在句柄表中的索引,然后把那一项处理后标注为空闲可用的项,内核对象的引用计数减1即此时此内核对象的引用计数为1,之后这个线程句柄与创建时产生的内核对象已经没有任何关系了。
问题:我们知道只有当内核对象的引用计数为0时,内核对象才会被销毁,而此时它的引用计数为1,那它什么时候会被销毁?
答:当此线程结束的时候,它的引用计数再减1即为0,内核对象被销毁。此时又有一个新问题产生:我们已经关闭了线程句柄,也就是这个线程句柄已经和内核对象没有瓜葛了,那么那个内核对象是怎么又可以和此线程联系起来了呢? 我觉得是创建线程时产生的那个线程ID,接下来我就证明那个ID与内核对象是有联系的:
请看如下简单的程序:
#include <stdio.h>#include <windows.h>#include <WinBase.h>DWORD WINAPI ThreadProc( LPVOID lpParameter){printf("I am comming...");while (1){} return 0;}int main(){HANDLE hThread;HANDLE headle2;DWORD threadId;hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, &threadId);CloseHandle(hThread); // 关闭了线程句柄headle2 = OpenThread(THREAD_QUERY_INFORMATION, FALSE, threadId);headle2= OpenThread(THREAD_QUERY_INFORMATION, FALSE, threadId);headle2 = OpenThread(THREAD_QUERY_INFORMATION, FALSE, threadId);return 0;}
图1:
图2:
调试此程序观察headle2的值,可以发现headle2的值是有效的,即函数调用是成功的,证明了线程ID与线程创建当初产生的内核对象是有关系的。
可以猜想:当线程结束时,系统通过线程ID与内核对象联系,使其引用计数减1,为0内核对象被销毁。
ps:观察以上两图,当把CloseHandle(hThread)这一句注释掉,以上程序三次调用OpenThread(),返回值是不相同的,说明返回的句柄不是原来句柄表中原来
的索引项,而是新建了一个内容一样的索引项。让CloseHandle(hThread); 这句也执行,再看看结果:hThread与headle2 的值是一样,证明了系统
管理句柄表的规则:我们把hThread关闭之后,它所在的索引项就被标记为可用;当需要向句柄表中加入新项时会查找第一项可用的索引项,这就是
hThread与headle2 的值是一样的原因。
- 内核对象与句柄的关系
- 内核对象与用户对象的句柄
- 内核对象与句柄
- MFC 对象与Win32 SDK 句柄的映射关系
- 深入解析MFC -- 句柄与对象的关系
- 深入解析MFC -- 句柄与对象的关系
- 深入解析MFC -- 句柄与对象的关系
- 深入解析MFC -- 句柄与对象的关系
- 内核对象句柄的继承
- 句柄与指针的关系
- FILE,文件句柄,打开文件列表和内核文件对象的关系
- 进程的内核对象句柄表
- 进程的内核对象句柄表
- -进程的内核对象句柄表
- 进程的内核对象句柄表
- 3.2 进程的内核对象句柄表
- 内核对象及句柄的本质区别
- 内核对象句柄表
- Hibernate 的 10 个常见面试问题及答案
- 最牛B的编码套路
- 深入分析一道基础面试题
- SCANV团队:警惕邮编区号查询工具的高危漏洞
- poj 3278 Catch That Cow
- 内核对象与句柄的关系
- linux input 子系统分析 一
- sbull在新内核编译
- [Linux] 防火墙配置
- Linux shell中函数的定义和使用
- 离散傅立叶变换之听声音破解电话号码
- linux input 子系统分析 二
- 长点心吧
- lvs+ldirectord+pacemaker+corosync+mysql实现高可用负载均衡(二)