`

内核对象和句柄的介绍及注意事项

 
阅读更多

                                                               内核对象,句柄

       系统会创建几种类型的内核对象,比如访问令牌对象、事件对象、文件对象、文件映射对象、I\O完成端口对象、作业对象、邮件槽对象、互斥量对象、管道对象、进程对象、信号量对象、线程对象、可等待计时器对象、线程池工厂对象等。

       每个内核对象都只是一个内存块,它由操作系统内核分配,并只能由操作系统内核访问。这个内存块是一个数据结构,其成员维护着与对象相关的信息。

       由于内核对象的数据结构只能由操作系统内核访问,所以应用程序不能在内存中定位这些数据结构并直接更改其内容。microsoft有意识强化了这个限制,确保内核对象结构保持一致性状态。

       调用一个会创建内核对象的函数后,函数会返回一个句柄(handle),它标识了所创建的对象。可以将这个句柄想象为一个不透明的值,它可由进程中的任何线程使用。在32位 windows进程中,句柄是一个32位的值;在64位windows进程中,则是一个64位的值。

       为了增强操作系统的可靠性,这些句柄值是与进程相关的。所以,如果将句柄值传给另一个进程中的线程(通过某种进程间通信方式),那么另一个进程用我们的进程的句柄值来发出调用时,就有可能失败;甚至更糟糕的是,它们会根据该句柄在我们的进程句柄表的索引来引用另一个进程中的完全不同的内核对象。

 

       内核对象的所有者是操作系统内核,而非进程。  如果我们的进程调用了一个函数创建了一个内核对象,然后进程终止运行,则内核对象并不一定会销毁。大多数情况下,这个内核对象是会销毁的,但假如另一个进程正在使用我们的进程创建的内核对象时,那么在其他进程停止之前,这个内核对象时不会销毁的。总之,内核对象的生命周期可能长于创建它的那个进程。

 

       操作系统内核知道当前有多少个进程正在使用一个特定的内核对象,因为每个对象都包含了一个使用计数。如果一旦对象的使用计数变成0,操作系统内核就会销毁对象。

 

进程的句柄表结构

包括  索引,指向内核对象内存块的指针,访问掩码(包含标志位的一个DWORD),标志

 

       创建线程,文件,文件映射,信号量等,这些用于创建内核对象的任何函数都会返回一个与进程相关的句柄,这个句柄可由用一个进程中运行的所有线程使用。

 

       调用一个函数时,如果它接受一个内核对象句柄作为参数,就必须把Create* 函数返回的值传递给它。在内部,这个函数会查找进程的句柄表,获得目标内核对象的地址,然后以一个恰当的方式来操纵对象的数据结构。

 

       凡是用于创建内核对象的函数,在检查他们的返回值时,务必相当仔细。

       在只有调用CreateFile时,才能将它的返回值与INVALID_HANDLE_VALUE进行比较。

       而其他Create* 调用通常是返回NULL的   

       所以比较时,应注意

 

关闭内核对象

       应注意,如果传给CloseHandle函数的是一个无效的句柄,那么可能发生以下两种情况之一:

       如果进程是正常运行的,CloseHandle将返回FALSE,而GetLastError返回RROR_INVALID_HANDLE。如果进程正在被调试,那么系统将跑出0xC0000008异常(指定了无效的句柄),便于我们调试这个错误。

就在CloseHandle函数返回之前,它会清除进程句柄中对应的记录项——这个句柄现在对我们的这个进程已经无效了,不要在试图用它。无论内核对象当前是否被销毁,这个清除操作过程都会发生的! 一旦调用了CloseHandle,我们的进程就不能访问那个内核对象;但是,如果对象的使用计数还没有递减至0,它就不会被销毁。这是完全正常的;它表明另外还有一个或多个进程在使用该对象。当其他进程(通过调用CloseHandle)全部停止使用这个对象后,对象就会被销毁。

 

       如果忘记调用CloseHandle,不一定会发生对象的泄漏情况。

       在进程运行期间,进程可能发生资源泄漏的情况。

       但是,当进程终止运行,操作系统会确保此进程使用的所有资源都被释放——这是可以保证的!

       对于内核对象,操作系统执行的是以下操作:

       进程终止时,系统自动扫描该进程的句柄表。如果这个表中有任何有效的记录项(即进程终止前没有关闭的对象),操作系统会为我们关闭这些对象句柄。只要这些对象中有一个的使用计数递减至0,内核就会销毁对象。

 

       所以在应用程序运行时,它可能会泄漏内核对象;但当进程终止运行,系统能保证一切都被正确清除。

 

       如何查看内核对象?   windows任务管理器    选择  查看->选择列->选择进程页列,指定在进程选项卡中显示句柄数列。

 

分享到:
评论

相关推荐

    MFC两个线程中用事件内核对象通信

    7. **注意事项**:线程间通信需谨慎处理资源的访问和释放,以避免资源泄露。在完成通信后,别忘了关闭事件对象,使用`CloseHandle`函数释放事件对象的句柄。 8. **源码分析**:在提供的`MFCApplication1`中,可以...

    易语言源码枚举句柄关闭进程DLL模块源码.rar

    - 可能存在的限制和注意事项,例如权限要求、系统兼容性等。 通过分析和学习这个源码,你可以深入理解Windows系统中的进程管理和DLL模块操作,这对于进行系统级编程或者开发安全工具具有很大的帮助。同时,易语言的...

    Windows Kernel Programming 9781977593375.pdf

    另外,还涉及了动态内存分配、链表等数据结构在内核中的应用,以及驱动对象和设备对象等重要的内核对象。 书中对驱动程序从设计到实现的整个过程进行了详细阐述。包括驱动程序的初始化、客户端与驱动程序通信协议、...

    windows-kernel-programming 第二版 英文原版

    - **Handles(句柄)**:句柄是Windows中用于引用内核对象的一种数据类型。句柄提供了一种安全的方式来访问对象,同时隐藏了对象的实际内存位置。 - **Objects(对象)**:Windows内核支持多种类型的对象,如进程、...

    精选_NT驱动程序与用户层程序基于事件EVENT实现同步通信_源码打包

    7. **注意事项** 使用事件对象进行同步时,必须确保正确管理事件的状态,防止死锁的发生。同时,因为涉及到内核模式和用户模式的交互,需要特别注意权限问题和内存管理,以防止引发系统稳定性问题。 总之,这个...

    各种反调试技术原理与实例VC版.pdf

    - **注意事项**:现代操作系统和调试器可能会模拟这一行为。 11. **SeDebugPrivilege进程权限** - **原理**:调试器需要拥有调试特权才能调试目标进程。 - **示例**:检查当前进程是否具有`SeDebugPrivilege`...

    桌面\关于WaitForSingleObject实例分析

    下面通过一个具体的示例来分析`WaitForSingleObject`的使用方法及注意事项。 #### 示例分析 示例程序创建了两个线程,分别对应于`ThreadFunc1`和`ThreadFunc2`。其中,`ThreadFunc1`负责不断更新界面上的时间显示...

    在XP2K 任务管理器的进程列表中隐藏当前进程

    #### 注意事项 - 这种技术可能涉及潜在的安全风险,因为可以被恶意软件用来隐藏其活动。 - 修改系统级别的安全描述符需要非常谨慎,不正确的操作可能会导致系统不稳定或安全问题。 - 此外,这种做法也可能违反了操作...

    Windows API

    **注意事项:** - 关闭内核对象是资源管理的重要部分,有助于释放系统资源并防止内存泄漏。 - 如果一个对象被多个句柄引用,则只有当所有句柄都被关闭后,该对象才会真正被销毁。 - 使用 `CloseHandle` 关闭文件时,...

    windows驱动开发技术详解-part2

     5.4.5 关于运行时函数使用的注意事项  5.4.6 实验  5.5 使用C++特性分配内存  5.6 其他  5.6.1 数据类型  5.6.2 返回状态值  5.6.3 检查内存可用性  5.6.4 结构化异常处理(try-except块)  5.6.5...

    Windows驱动开发技术详解的光盘-part1

     5.4.5 关于运行时函数使用的注意事项  5.4.6 实验  5.5 使用C++特性分配内存  5.6 其他  5.6.1 数据类型  5.6.2 返回状态值  5.6.3 检查内存可用性  5.6.4 结构化异常处理(try-except块)  5.6.5...

    自写驱动保护XX进程HOOKSSDT32课.pdf

    ### 实践中的注意事项 - **权限与安全性**:进行SSDT Hook操作需要内核模式权限,这增加了开发难度和风险,因为任何错误都可能导致系统崩溃(蓝屏)。 - **兼容性问题**:修改SSDT会影响所有依赖于被钩子函数的应用...

    mapfile_Vc_

    使用内存映射文件有一些注意事项: 1. 映射文件的大小应该合理规划,过大可能导致内存不足,过小则可能无法满足大文件操作的需求。 2. 考虑并发访问:在多线程环境下,应确保对映射区域的访问是同步的,以避免数据不...

    windows下进程间通信总结

    #### 五、注意事项 尽管文件映射提供了高效的进程间通信方式,但在使用过程中还需注意以下几点: - **同步问题**:当多个进程共享同一份数据时,必须确保数据的一致性和完整性。这通常需要使用互斥量或信号量等...

    Redhat Linux下Oracle 10g安装说明

    通过上述步骤和注意事项,你可以成功地在Redhat Linux环境中安装Oracle 10g数据库。请确保在执行每个步骤时都仔细阅读提示,并根据实际情况进行调整。安装完成后,记得进行必要的性能优化和安全设置,以确保数据库...

    精彩编程与编程技巧-判断一个32位程序是否结束...

    - **`WaitForSingleObject`**:此函数等待一个内核对象变为非信号状态。如果对象处于信号状态,则函数立即返回。如果对象尚未变为非信号状态,则函数将阻塞调用线程直到对象变为非信号状态或超时。 - **`...

    CLR.via.C#.(中文第3版)(自制详细书签)Part1

    第2章 生成、打包、部署和管理应用程序及类型 2.1 .NET Framework部署目标 2.2 将类型生成到模块中 2.2.1 响应文件 2.3 元数据概述 2.4 将模块合并成程序集 2.4.1 使用Visual Studio IDE将程序集添加到项目中...

    CLR.via.C#.(中文第3版)(自制详细书签)

    27.8 APM的注意事项 27.8.1 在没有线程池的前提下使用APM 27.8.2 总是调用EndXxx方法,而且只调用一次 27.8.3 调用EndXxx方法时总是使用相同的对象 27.8.4 为BeginXxx和EndXxx方法使用ref,out和params实参 ...

    CLR.via.C#.(中文第3版)(自制详细书签)Part3

    第2章 生成、打包、部署和管理应用程序及类型 2.1 .NET Framework部署目标 2.2 将类型生成到模块中 2.2.1 响应文件 2.3 元数据概述 2.4 将模块合并成程序集 2.4.1 使用Visual Studio IDE将程序集添加到项目中...

Global site tag (gtag.js) - Google Analytics