win32api之句柄表(三)

什么是内核对象

在Windows操作系统中,内核对象是由内核负责管理的资源,如进程、线程、文件、互斥体、事件、信号量、共享内存、管道等。

每个内核对象都对应着一个内核对象结构体,内核对象结构体包含了该内核对象的属性、状态、引用计数等信息


什么是句柄表

句柄表(Handle Table)是Windows内核中的一个重要数据结构,用于存储内核对象的句柄(Handle),包括进程、线程、文件、事件、互斥体等。

每个进程都有一个句柄表,这个表存储了当前进程所拥有的所有内核对象的句柄,通过这些句柄可以访问相应的内核对象

如下图所示, 每个进程都在内核区域都会有一个EPROCESS对象(内核进程对象), 在这个进程里执行了四个函数, 分别是CreateProcessCreateThreadCreateEventCreateFile,执行这些函数的同时, 也会在内核区创建相应的对象

EPROCESS结构体有一个成员叫ObjectTable, 此成员指向句柄表, 句柄表存放了每个内核对象的句柄

image-20230217200728294

多进程共享一个内核对象

在Windows操作系统中,不同的进程之间是相互独立的,它们各自拥有独立的虚拟地址空间和资源,进程之间不能直接访问彼此的内存空间。但有时候,不同的进程需要共享某些内核对象(如互斥体、事件等),以便它们能够协同工作。Windows内核提供了一些机制来实现多进程间共享内核对象的需求

在多进程共享一个内核对象时,可以使用内核对象的名字(例如互斥体名字、事件名字等)在不同的进程之间进行传递和共享。当一个进程创建一个具有名字的内核对象时,其他进程可以通过内核对象名字来打开这个对象,从而共享这个对象

句柄继承问题

在 Windows 操作系统中,每个进程都有一张句柄表,记录了该进程所打开的内核对象的句柄。当一个进程创建子进程时,子进程会默认继承父进程的句柄表。也就是说,子进程会复制父进程的句柄表,并与父进程共享同一份句柄表,子进程可以使用父进程打开的内核对象的句柄进行操作。

但并非所有类型的内核对象都可以被子进程继承,例如父进程打开的仅在父进程内有效的句柄,如 GDI 对象、用户对象等,子进程无法继承。另外,父进程可以在创建子进程时通过传递参数指定子进程继承哪些句柄。如果没有指定,则默认情况下,子进程将继承所有可继承的句柄。

如下图所示, 父进程调用了CreateProcess函数创建了一个子进程, 同时在内核区也会创建一个属于子进程的EPROCESS, 其实句柄表还有一列字段用于表示内核对象是否允许被继承, 1表示允许, 0表示不允许。CreateProcess函数有一个参数叫做bInheritHandles, 若此值为True, 则子进程会复制父进程的句柄表

1


什么是全局句柄表

全局句柄表是一个系统级别的内核对象,用于存储所有的内核对象句柄。在Windows操作系统中,每个进程都有一个独立的句柄表,用于存储它自己的内核对象句柄,而全局句柄表是操作系统内部用于管理所有进程的句柄的数据结构

当一个进程创建一个内核对象时,Windows操作系统会返回一个唯一的内核对象句柄。这个句柄会被存储到创建进程的句柄表中,同时也会被存储到全局句柄表中。其他进程可以通过特定的API函数获取这个句柄,并使用它来访问创建进程的内核对象

全局句柄表的作用在于提供了一种跨进程共享内核对象的方式,使得多个进程可以访问同一个内核对象,从而实现进程间的通信和协作。全局句柄表的管理和维护由操作系统负责,应用程序无法直接访问和修改它

posted @ 2023-03-19 20:42  亨利其实很坏  阅读(53)  评论(0编辑  收藏  举报