Windows对象管理
此條目没有列出任何参考或来源。 (2014年1月8日) |
对象管理是Windows Executive的一个子系统实现,用于管理Windows资源。 资源包括物理设备、文件、文件目录、注册表条目、正在运行的进程等等。所有子系统访问资源都必须通过对象管理子系统。
体系结构
Windows NT操作系统体系结构中,对象管理子系统管理所有的资源。资源被表示为对象。对象管理子系统保持着对每个对象的引用计数。任何访问对象的系统调用都必须通过对象管理子系统。
对象可分为即内核对象(Kernel objects)与Executive objects. 内核对象表示一些基本资源,如物理设备、同步服务等等。用户态的程序不能访问内核对象。[1]用户态的系统服务与应用程序使用Executive objects, 这是Windows Executive对外暴露的对象, 用来封装了一个或多个内核对象。 Executive objects还用于实现了NT子系统或POSIX子系统的一些功能。
当对象创建时,指向对象实例的索引也被创建,称为句柄(handle)[2]。对象管理子系统使用句柄与命名两种方式管理对象实例。句柄在一个进程内部是共享的,但在进程之间不是直接可复用,需要特别方式在进程间传递对象句柄。一个进程任何时刻最多拥有224,即大约16,000,000个句柄。句柄按照对象的分类可分为文件句柄、事件句柄、进程句柄等。一个进程对一个对象可以有多个句柄,以便按照不同权限来访问对象。
Windows NT暴露的Executive object的类型包括:
类别 | 描述 | 创建句柄函数 | 摧毁句柄函数 | 未通知状态 | 通知状态 | 等待成功的副作用 |
---|---|---|---|---|---|---|
进程 | 线程的集合,拥有共同的虚拟内存空间与控制信息 | CreateProcess, OpenProcess, GetCurrentProcess | CloseHandle, TerminateProcess | 进程仍然活动时 | 进程终止运行时 (TerminateProcess ExitProcess) |
无 |
线程 | 进程内部,执行程序的实体。 | 线程仍然活动时 | 线程终止运行时 (TerminateThread ExitThread) |
无 | ||
作业 | 进程的集合 | CreateJobObject | CloseHandle | 当作业的时间尚未结束时 | 当作业的时间已经结束时 | 无 |
文件 | 一个打开的计算机文件或I/O设备。 | CreateFile | CloseHandle, DeleteFile | 当I/O请求正在处理时 | 当I/O请求处理完毕时 | 无 |
文件映射对象 | 一块内存区域,映射到一个文件。 | |||||
访问令牌 | 一个对象的访问权。 | CreateRestrictedToken, DuplicateToken, DuplicateTokenEx, OpenProcessToken, OpenThreadToken | CloseHandle | |||
事件 | 封装了某些信息的一个对象,用于通知某些进程。 | CreateEvent, CreateEventEx, OpenEvent | CloseHandle | ResetEvent,或PulseEvent,或自动重置事件等待成功 | 当调用SetEvent,或PulseEvent | 自动重置事件等待成功后将自动reset |
信号量 | 用于串行化访问某些资源的对象。 | CreateSemaphore, CreateSemaphoreEx, OpenSemaphore | CloseHandle | 当数量<=0时 | 当数量>0时 (ReleaseSemaphore) | 数量递减1 |
互斥锁 | 用于串行化访问某些资源的对象。 | CreateMutex, CreateMutexEx, OpenMutex | CloseHandle | 被其他线程拥有时 | 未被其他线程拥有时 | 等待成功的线程获得CPU所有权 |
临界区域 | 使得指定的代码段被串行执行 | 被其他线程拥有时(试图EnterCriticalSection) | 未被其他线程拥有时(LeaveCriticalSection) | 等待成功的线程获得CPU所有权 | ||
定时器 | 按照固定时间间隔通知某些进程的对象。 | CloseHandle | CancelWaitableTimer或自动重置定时器等待成功 | 当时间到时 (SetWaitableTimer) | 自动重置定时器等待成功将reset | |
Timer queue | ||||||
Timer-queue timer | ||||||
键值 | Windows注册表条目的键值。 | |||||
桌面 | 包含GUI元素的一个逻辑显示面。 | GetThreadDesktop | 用户不能删除这个对象 | |||
剪贴板 | 用于其它对象的临时存储空间。 | |||||
WindowStation | 包含一些桌面对象、一块剪贴板对象、以及其他对象的对象。 | GetProcessWindowStation | 用户不能删除这个对象 | |||
符号链接 | 对其他对象的引用 | |||||
事件日志 | OpenEventLog, RegisterEventSource, OpenBackupEventLog | CloseEventLog | ||||
Change notification | FindFirstChangeNotification | FindCloseChangeNotification | ||||
Communications device | CreateFile | CloseHandle | ||||
控制台输入 | CreateFile, with CONIN$ | CloseHandle | 不存在任何输入时 | 存在输入时 | 无 | |
Console screen buffer | CreateFile, with CONOUT$ | CloseHandle | ||||
文件修改通知 | FindFirstChangeNotification | CloseHandle | 没有任何文件被修改 | 当文件系统发现修改时 | 重置通知 | |
Heap | HeapCreate | HeapDestroy | ||||
I/O completion port | CreateIoCompletionPort | CloseHandle | ||||
Mailslot | CreateMailslot | CloseHandle | ||||
Memory resource notification | CreateMemoryResourceNotification | CloseHandle | ||||
模块 | LoadLibrary, GetModuleHandle | FreeLibrary | ||||
管道 | CreateNamedPipe, CreatePipe | CloseHandle, DisconnectNamedPipe | ||||
Socket | socket, accept | closesocket | ||||
Update resource | BeginUpdateResource | EndUpdateResource |
与内核对象相对,还有用户对象与GDI对象。
- 用户对象:每个对象仅有一个句柄,句柄不能复制或继承,不能引用其他用户会话中的进程的用户句柄。任何进程只要有对某个用户句柄访问权限,既可以访问该用户对象。一个进程最多有65536个用户对象句柄。用户对象包括:Accelerator table、Caret、Cursor、DDE conversation、Hook、Icon、Menu、Window、Window position。[3]
- GDI对象:每个对象仅有一个句柄,句柄为进程私有。一个进程最多有65536个GDI对象句柄。GDI对象包括:Bitmap、Brush、DC、Enhanced metafile、Enhanced metafile DC、Font、Memory DC、Metafile、Metafile DC、Palette、Pen and extended pen、Region.[4]
对象结构
每个被对象管理子系统所管理的对象,包含头部和体部。头部是对象管理子系统使用的状态信息。体部是对象相关的数据与暴露的服务。
对象头部对外暴露的信息称为Properties
, 包括:
Object Name
,用来标识对象Object Directory
,对象所属类别Security Descriptors
,对象的访问权限,一般在创建对象时传入,大多数时候传入值为NULL,表示采用默认安全属性。Quota Charges
,对象的资源使用信息Open handle count
,打开的句柄计数Open handle list
,活动引用的进程列表Reference count
,活动引用进程的计数Type
,用来标识对象体部结构
对象管理子系统所管理的对象必须提供下属服务:
Close
,关闭对象的一个句柄Duplicate
,创建对象的另一个句柄,用来给另一个进程共享访问该对象Query object
,获得对象的属性与性质等信息Query security
,得到对象的安全描述信息Set security
,改变对象的安全访问信息Wait
,同步一个或多个对象,通过特定事件。
同一类型的对象具有一些相同的属性,如类型名、是否分配在非分页内存、访问权限、同步信息等。这些由一个类型对象(type object)来表示。所有同一类型的对象实例共享这唯一的类型对象。 可以创建新的对象类型,这通过把一个对象的属性作为对外暴露的状态,把其方法作为对外暴露的服务来实现。
对象名(Object name
)是一个对象的描述性标识。对象管理子系统保持一个已经用于表示对象的名字列表,映射每个名字到对象实例。实际上大多数访问对象的行为是通过句柄;通过对象名来查找对象实例仅发生在创建对象时、跨进程共享一个对象时。
Object directories
用于按照类型来分类对象。预定义的Object directories
包括:
\??
(Win32 设备名,其中只有符号链接)\BaseNamedObjects
(互斥、事件、信号量、可等待计时器和段对象)\Callback
(回调函数)\Device
(设备)\Drivers
\FileSystem
\KnownDlls
\Nls
(language tables)\ObjectTypes
(对象类型对象)\RPC Controls
(RPC端口)\Security
(安全子系统对象)\Windows
(窗口子系统对象)
对象属于命名空间(Namespace). 每个用户会话(user session)是一个名字空间。这使得多个客户同时运行一个应用程序而不会发生干扰。在所有名字空间共享的对象属于GLOBAL命名空间。例如,在Global命名空间中创建一个事件,名字叫CSAPP:
CreateEvent( NULL, FALSE, FALSE, "Global\\CSAPP" );
全局命名空间使得多个客户会话间的进程可以通信。例如,一个客户/服务器使用互斥锁来同步,服务器模块在全局命名空间创建一个互斥锁对象,然后客户进程使用"Global\"前缀来打开这个互斥锁对象。 客户进程可以明示使用 "Local\"前缀来在客户会话命名空间中创建对象。[5]
OBJECT_ATTRIBUTES结构:
typedef struct _OBJECT_ATTRIBUTES{ ULONG Length; HANDLE RootDirectory; PUNICODE_STRING ObjectName; ULONG Attributes; PSECURITY_DESCRIPTOR SecurityDescriptor; PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService; }
Attributes成员域可以是0,或下述标志的组合:
OBJ_INHERIT OBJ_PERMANANT OBJ_EXCLUSIVE OBJ_CASE_INSENSITIVE OBJ_OPENIF OBJ_OPENLINK OBJ_KERNEL_HANDLE
参加
参考文献
- Russinovich, Mark; David Solomon. Chapter 3: System Mechanisms. Microsoft Windows Internals 4th edition. Microsoft Press. 2005: 124–149. ISBN 0-7356-1917-4.
- ^ Kernel objects
- ^ 每个进程中都存在一个句柄表,列出了所有本进程内可以使用的句柄。句柄表实际上是一个数组,每个数组元素为一个结构,包含一个指向内核对象的指针、访问掩码、继承标识等。句柄实际上是进程句柄表数组的下标。因此句柄是进程私有的。
- ^ User Objects
- ^ GDI Objects
- ^ Kernel object namespaces