Windows内核对象

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

4. 进程的内核对象句柄表

当一个进程被初始化时,系统要为它分配一个句柄表。该 句柄表只用于内核对象,不用于用户对象或GDI对象。
当进程调用内核对象创建函数(比如CreateEvent)时, 内核负责创建内核对象,同时,内核还对该进程的句柄表 进行扫描,找出一个空项插入一条句柄纪录。 句柄值实际上是放入进程的句柄表中的索引。
); Remark: If lpEventAttributes is NULL, the event gets a default security descriptor.

SECURITY_ATTRIBUTES结构:
typedef struct _SECURITY_ATTRIBUTES {
DWORD nLength; LPVOID lpSecurityDescriptor; BOOL bInheritHandle; //If TRUE, the new process inherits the handle
举例:

假设一个进程拥有对一个文件映射对象的读和写访问权。 在某个位置上,一个函数被调用,它通过读取文件映射对 象来访问它。为了使应用程序更加健壮,可以使用 DuplicateHandle为现有的对象创建一个新句柄,并确保 这个新句柄拥有对该对象的只读访问权。然后将只读句柄 传递给该函数,这样,该函数中的代码就永远不会偶然对 该文件映射对象执行写入操作。
此时,进程句柄表中句柄纪录的标志位将被置为1,例如:

第二步,父进程调用CreateProcess创建子进程,且 bInheritHandles 参数设为TRUE,
此时,系统为子进程创建一个新的和空的句柄表,并遍历父进程的句柄表, 对于它找到的包含有效的可继承句柄的每个项目,系统会将该项目准确地 拷贝到子进程的句柄表中,系统还要递增内核对象的使用计数。该项目拷贝 到子进程的句柄表中的位置将与父进程的句柄表中的位置完全相同,例如:
} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES;

如果你想要限制人们对你创建的内核对象的访问,必须创 建一个安全性描述符SD,例如:
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa); sa.lpSecuntyDescriptor = pSD, //Address of an initialized SD sa.bInheritHandle = FALSE ; //or TRUE HANDLE hEvent = CreateEvent( &sa, TRUE, FALSE, NULL);


5、关闭内核对象

CloseHandle用于进程结束对该对象的操作:

BOOL CloseHandle(HANDLE hobj);

假如忘记调用CloseHandle函数,会不会出现 内存泄漏呢?答案是可能的,但是也不一定。 解释如下:

当进程终止运行时,系统会自动扫描进程的句柄表。如果
该表拥有任何无效项目(即在终止进程运行前没有关闭的 对象),系统将关 闭这些对象句柄。如果这些对象中的 任何对象的使用计数降为0 ,那么内核便撤消该对象。
当Process B调用CreateMutex时,系统首先要查看是否 已经存在一个名字为“chenMutex”的内核对象。 此时,系统就在Process B的句柄表中找出一个空项目, 并对该项目进行初始化,使该项目指向现有的内核对象。
调用Create *函数与调用Open *函数之间的主要差别是,如果对象并不存在, 那么Create *函数将创建该对象,而Open *函数则运行失败。
进程
进程内核对象句柄表
索引 内核对象 内存块的 指针 0x?????? 0x?????? … 访问屏蔽 标志
Win32 API_1( 句柄 , … ); Win32 API_2( 句柄 , … );
1 2 …
0x?????? 0x?????? …
0x?????? 0x?????? …
win32子系统
信号量对象
管道对象
… …
Pipe Objects,
I/O 完成端口对象
2、内核对象的使用计数

内核对象由内核所拥有,而不是由进程所拥有。那么 内核对象的存在时间可以比创建该对象的进程长。 每个内核对象都包含一个使用计数数据成员。


当一个对象刚刚创建时,它的使用计数被置为1。然后, 当另一个进程访问一个现有的内核对象时,使用计数就 递增1。当进程终止运行时,内核就自动将使用计数减1。 如果内核对象的使用计数降为0,内核就撤消该对象。
3. 安全性

内核对象能够得到安全描述符的保护。安全描述符用于描述谁创 建了该对象,谁能够访问或使用该对象,谁无权访问该对象。 用于创建内核对象的函数几乎都有一个指向SECURITY_ATTRIBUTES 结构的指针作为其参数(这也是区别一般对象的标志,用于创建 用户对象或GDI对象的函数都没有该参数),例如:
(3)复制对象句柄

共享跨越进程边界的内核对象的最后一个方法 是使用DuplicateHandle函数:
——该函数取出一个进程的句柄表中的项目,并将该项目拷贝到另一个 进程的句柄表中。
例如,Process S拥有对一个内核对象的访问权,并且想要让Process T 能够访问该对象。可以像下面这样调用DuplicateHandle :
(2)为对象命名

共享跨越进程边界的内核对象的第二种方法是给对象命名。 许多(虽然不是全部)内核对象都是可以命名的。例如:
所有这些函数都有一个共同的最后参数pszName。


例如:Process A启动运行,并调用下面的函数: HANDLE hEventA=CreateMutex(NULL, FALSE, “chenMutex”); Process B执行以下代码: HANDLE hEventB=CreateMutex(NULL, FALSE, “chenMutex”);或者 HANDLE hEventB=OpenMutex(NULL, FALSE, “chenMutex”);

因此,应用程序在运行时有可能泄漏内核对象,但是当进 程终止运行时,系统将能确保所有内容均被正确地清除。
6、跨越进程边界共享内核对象

许多情况下,在不同进程中运行的线程需要共享内核 对象。 Windows提供3种机制允许进程共享内核对象。


对象句柄继承
为对象命名 复制对象句柄
(1). 对象句柄继承:
作业:

1. 理解常用内核对象的意义和相关API用法。 2.理解内核对象的概念。 3.理解跨越进程边界共享内核对象的3种方法。
要求:写出报告,并用举例说明。

HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, // reset type BOOL bInitialState, // initial state LPCTSTR lpName // object name // SD,
范例:实现程序的唯一进程实例 CreateMutex(NULL,TRUE, “chenmutex"); if(GetLastError()==ERROR_ALREADY_EXISTS) { MessageBox(NULL,“软件已经运行!” , ,“提示" ,0); return FALSE; }
用户态 对象管理器组件 核心态
1 内核 3
2 4 内核对象

常用内核对象:
进程对象 Process Objects
线程对象
事件对象
Thread Objects
Event Objects File-Mapping Objects
文件映射对象
文件对象
互斥对象
File Objects
Mutex Objects Semaphore Objects , I/O Completion-Port Objects
专题:Windows内核对象
chensq8808@126.com
来自百度文库
准确地理解内核对象对于想要成为一名 windows软件开发能手的人来说至关重要。

作为一个windows软件开发人员,经常需要创建、打开 和操作各种内核对象。

内核对象可以供系统和应用程序使用来管理各 种各样的资源,比如进程、线程和文件等。

只有当进程具有父子关系时,才能使用对象句柄的继承性。父进程必 须执行若干个操作步骤: 第一步,当父进程创建内核对象时,必须向系统指明,它希望对象的句柄是 个可继承的句柄。例如,
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa); sa.lpSecuntyDescriptor = pSD, //Address of an initialized SD sa.bInheritHandle = TRUE; //可继承的 HANDLE hEvent = CreateEvent( &sa, TRUE, FALSE, NULL);
注解:

应用程序无法在内存中找到这些数据结构并直接改变 它们的内容。Microsoft规定了这个限制条件,目的 是为了确保内核对象结构保持状态的一致。 应用程序如何才能操作这些内核对象呢?




解决办法是:通过win32 API。 当进程调用一个用于创建内核对象的函数时,该函数就返回 一个用于标识该对象的句柄。进程中的任何线程都可以使用 这个句柄。 可将这个句柄传递给windows的各个函数,这样,系统就能 知道你想操作哪个内核对象。 为了使操作系统变得更加健壮,这些句柄值是与进程密切相 关的。
Windows 2000/XP/2003的关键系统组件
1、什么是内核对象

DEF: 内核对象是由windows内核分配的一个内存块, 并且只能由内核访问。该内存块是一种数据结构, 它的成员负责维护该对象的各种信息(如对象名 称、安全描述、使用计数等)。
用户态 核心态 内核 1 3 2 4 内核对象
相关文档
最新文档