内核对象是什么?
内核对象是以一个内存块,它由操作系统内核分配,并只能由操作系统内核访问。这个内存块是一个数据结构,其成员维护着与对象内相关的信息。内核对象只能由操作系统访问,所以应用程序不能再内存中定位 这些数据结构并直接修改内容。
内核对象怎么创建?
应用程序使用Windows提供的函数来访问内核对象,使用函数会返回句柄。同时可以传权限描述符,使该内核对象有访问权限的限制。内核对象生命周期?
内部使用计数会维护内核对象的生命周期,每个内核对象都有一个使用计数,再创建的时候为1,当使用计数为0时,销毁内核对象。
句柄是什么?
句柄是一个相对于目标进程的一个值,在32位系统占4位,在64位系统占8位。
怎么操作句柄?
操作句柄的函数需要传入一个句柄,在内部这个函数会查找进程的句柄表,获得内核对象的地址,然后用一种恰当的方式来操纵对象的数据结构。句柄值作为进程句柄表的索引来时,所以这些句柄于当前进程线相关,无法供其他进程使用。跨进程传递句柄值会怎么样?
如果使用,只是使用一个索引值相关的一个内核对象,可能会奔溃或发生不可预测的事情。关闭句柄:
CloseHandle函数,在内部会先检查主调进程的句柄表,验证传入句柄的是进程有访问权的内核对象,如果句柄是有效的,系统会获得内核对象的数据结构地址,并将结构中使用计数成员减一。如果句柄无效,将返回false或在调试的时候返回0xC000008.内核对象和进程普通对象有什么区别?
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函数改变。
标签:操作系统,Windows,句柄,对象,内核,使用,进程 From: https://www.cnblogs.com/zjr0/p/16986890.html