Windows内核对象和句柄
内核对象是什么?
内核对象是以一个内存块,它由操作系统内核分配,并只能由操作系统内核访问。这个内存块是一个数据结构,其成员维护着与对象内相关的信息。内核对象只能由操作系统访问,所以应用程序不能再内存中定位 这些数据结构并直接修改内容。
内核对象怎么创建?
内核对象生命周期?
内部使用计数会维护内核对象的生命周期,每个内核对象都有一个使用计数,再创建的时候为1,当使用计数为0时,销毁内核对象。
句柄是什么?
句柄是一个相对于目标进程的一个值,在32位系统占4位,在64位系统占8位。
怎么操作句柄?
跨进程传递句柄值会怎么样?
关闭句柄:
内核对象和进程普通对象有什么区别?
1.存储区别:
内核对象被操作系统内核对象生成,其存储在操作系统内核,操作系统内核共享所有操作系统内核空间。32位操作系统是0x80000000-0x8F之间,64位操作系统是0x00000400 00000000-0x16F。进程普通对象创建在进程专享的线程栈或堆内存中。
2.生命周期区别:
内核对象随使用计数或进行结束销毁,进程普通栈对象随栈平衡被自动销毁,堆对象需要手动销毁,不主动销毁会造成内存泄露。
跨进程边界共享内核对象的方式:
1.进程继承(暂时没有使用到,使用到的时候补)
2.互斥量,信号量,事件(内核对象)
创建内核对象时候为该对象命名,只有部分内核对象在创建的时候提供了为其命名的参数,同时操作系统不会保证名字的唯一。
HANDLE hMutex=CreateMutex(NULL,FALSE,TEXT("test")); //进程A创建一个句柄
HANDLE hMutex=CreateMutex(NULL,FALSE,TEXT("test")); //进程B获取句柄
HANDLE hMutex=OpenMutex(NULL,FALSE,TEXT("test")); //进程B获取句柄
OPen和Create的区别:
如果对象不存在Create会创建该对象,Open不会创建对象。
为何可以跨进程:
内核被创建在操作系统内核里,新创建内核对象的时候会根据内核的名称来查找当前是否有一个对象的名称和需要被创建的内核对象相同,接着执行安全检查,验证调用者的访问权限,如果通过了验证,则返回同名内核对象,并在进程中查找一个空白的句柄记录项。目标进程中不会产生一个新的内核对象,只是引用了该内核对象,使用计数递增,两个进程分别使用自己句柄值来使用内核对象,不会产生冲突。
可以用GUID来防止同名。使用CreateMutex创建的内核对象总是返回具有完全访问权限的句柄,可以使用后最为ex的拓展版本,它们接受一个额外的DWORD dwDesiredAccess参数。
3复制对象句柄(DuplicateHandle)
什么是句柄表?
进程在初始化的时候系统会为它分配一个句柄表,这个句柄表仅供内核对象使用,不适用于用户对象或GDI对象。句柄表是一个数据结构组成,每个数据结构都包含一个内核对象指针一个访问掩码和一个标记。
进程线程创建的内核对象会发生什么?
当进程的一个线程调用一个会创建对象的函数时,内核将为这个对象分配并初始化一块内存,然后内核扫描进程的句柄表,查找一个空白的记录项,并进行初始化。数据结构的内核对象指针会被设置成新创建内核对象的内部地址,访问掩码会根据访问权限设置,标志该句柄是否可以被继承。
句柄表的标记修改:
标记可以使用SetHandleInformation函数改变。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用