在不改变文章大意和图片位置的前提下,以下是经过伪原创处理的文章:
句柄表与内核对象之间的关系是什么?首先,我们需要了解什么是句柄表,什么是内核对象。
一、句柄表和内核对象的概念
- 句柄表的生成
当我们使用CreateProcess函数时,它会返回一个进程句柄和一个线程句柄。在调用CreateProcess时,内核会创建一个EPROCESS结构来保存进程信息。

然而,如何让三环程序使用这个EPROCESS呢?直接返回EPROCESS是不行的,因为EPROCESS位于高两G的地址空间,三环程序无法访问。为了解决这个问题,Windows创建了一个表格,并返回这个表格的索引。我们使用的就是这个索引。
- 什么是内核对象
内核对象就是我们提到的EPROCESS。内核对象有很多种,具体可以参考CloseHandle API,它可以关闭哪些内核对象:
- Access token
- Communications device
- Console input
- Console screen buffer
- Event
- File
- File mapping
- I/O completion port
- Job
- Mailslot
- Memory resource notification
- Mutex
- Named pipe
- Pipe
- Process
- Semaphore
- Thread
- Transaction
- Waitable timer
这些对象可以操作事件、文件、互斥体、线程等。
二、多进程共享内核对象
- 第一种方法:使用OpenProcess
在Windows程序中,我们操作的都是内核对象。我们可以通过OpenProcess API来打开一个已有的进程的内核对象。

每个进程的句柄表都是私有的。例如,在第一张表中,句柄索引为1,对应的内核对象为A。如果将这个索引传给B进程,是没有用的。B进程只有在使用API打开后,才能获得A内核对象。
中间的紫色表代表引用计数。每次引用内核对象,这个值会加1。CloseHandle的作用是使内核对象的引用计数减1。如果所有引用都被关闭,那么内核对象将无人使用,也没有任何引用,因此会被销毁。也就是说,当内核对象的引用计数为0时,它才会被真正销毁。
线程是一个特例:当线程的内核对象引用计数为0时,它不会被关闭。此时,必须先关闭线程,然后使用CloseHandle使引用计数减1。
- 使用继承句柄技术
在Windows程序中,A进程创建B进程,或者带有内核对象的API在创建时,都有一个SD属性,即安全属性。这个属性可以表示你创建的句柄是否可以被继承。
例如,CreateEvent()创建事件。我们先不讨论API的作用,看看它的参数:

HANDLE CreateEventA( LPSECURITY_ATTRIBUTES lpEventAttributes, // 安全属性结构体 BOOL bManualReset, BOOL bInitialState, LPCSTR lpName);
登录后复制
文章来自互联网,只做分享使用。发布者:,转转请注明出处:https://www.dingdanghao.com/article/851339.html
