Windows对象管理:修订间差异

删除的内容 添加的内容
InternetArchiveBot留言 | 贡献
补救3个来源,并将0个来源标记为失效。) #IABot (v2.0.8.7
 
(未显示10个用户的17个中间版本)
第1行:
{{Unreferenced|time=2014-01-08T06:39:36+00:00}}
'''对象管理'''是[[Windows Executive]]的一个子系统实现,用于管理Windows资源。 资源包括物理设备、文件、文件目录、[[Windows Registry|注册表]]条目、正在运行的进程等等。所有子系统访问资源都必须通过对象管理子系统。
 
 
==体系结构==
[[Windows NT]]操作系统体系结构中,对象管理子系统管理所有的资源。资源被表示为对象。对象管理子系统保持着对每个对象的[[引用计数]]。任何访问对象的系统调用都必须通过对象管理子系统。Windows对象可分为内核对象、用户对象、GDI对象:
*用户对象(User interface object):支持窗口管理。每个对象仅有一个句柄,句柄不能复制或继承,不能引用其他用户会话中的进程的用户句柄。任何进程只要有对某个用户句柄的安全访问权限,即可以访问该用户对象,即用户对象在当前会话下是全局的。一个进程最多有 65536 个用户对象句柄。用户对象包括:快捷键表 HACCEL、插入点光标HCaret、鼠标指针 HCURSOR、DDE 会话、窗口钩子HOOK、图标 HICON、菜单 HMENU、窗口 HWND、窗口位置Window position。<ref>[{{Cite web |url=http://msdn.microsoft.com/en-us/library/windows/desktop/ms725486%28v=vs.85%29.aspx |title=User Objects] |access-date=2014-01-08 |archive-date=2017-09-18 |archive-url=https://web.archive.org/web/20170918203458/https://msdn.microsoft.com/en-us/library/windows/desktop/ms725486(v=vs.85).aspx }}</ref>
*GDI 对象:支持图形。每个对象仅有一个句柄,句柄为进程私有。一个进程最多有 65536 个 GDI 对象句柄。GDI 对象包括:位图 HBITMAP、画刷 HBRUSH、设备环境(DC)HDCHDC、[[EMF|增强型图元文件(EMF)]]、EMF 设备环境、字体 HFONT、内存 DC、图元文件Metafile、图元文件 DC、调色板 HPALETTE、画笔 HPEN、区域(Region)HRGN。<ref>[{{Cite web |url=http://msdn.microsoft.com/en-us/library/windows/desktop/ms724291%28v=vs.85%29.aspx |title=GDI Objects] |access-date=2014-01-08 |archive-date=2017-09-18 |archive-url=https://web.archive.org/web/20170918202648/https://msdn.microsoft.com/en-us/library/windows/desktop/ms724291(v=vs.85).aspx }}</ref>
*内核对象:支持内存管理、进程执行、[[进程间通信]]。内核对象句柄是进程私有的,必须创建或者打开内核对象以获取其句柄。当进程创建或打开内核对象时,进程的句柄表中增加一个条目指向内核对象实例。进程的句柄表的索引也被创建,称为'''[[句柄]]'''(handle)<ref>每个进程中都存在一个句柄表,列出了所有本进程内可以使用的句柄。句柄表实际上是一个数组,每个数组元素为一个结构,包含一个指向内核对象的指针、访问掩码、继承标识等。句柄实际上是进程句柄表数组的下标索引。因此句柄是进程私有的。进程的句柄表的表头数据结构为HANDLE_TABLE。所有进程的句柄表表头形成一个List。句柄表的表项的数据结构为HANDLE_TABLE_ENTRY,长度为8字节,其中前四个数据为内核对象地址,后四个字节为访问掩码或在当前表项为空闲时存储下一空闲表项的索引值。</ref>。对象管理子系统使用句柄与命名两种方式管理对象实例。句柄在一个进程内部是线程共享的,但在进程之间不是直接可复用,需要特别方式在进程间传递对象句柄。一个进程任何时刻最多拥有 2<sup>24</sup>,即大约 16,000,000 个句柄。句柄按照对象的分类可分为文件句柄、事件句柄、进程句柄等。一个进程对一个对象可以有多个句柄,以便按照不同权限来访问对象。
 
对象可分为'''内核对象'''(Kernel objects)与 ''Executive objects'执行对象'''(Executive objects)。内核对象表示一些基本资源,如物理设备、同步服务等等。用户态的程序不能访问内核对象。<ref>[{{Cite web |url=http://msdn.microsoft.com/en-us/library/windows/desktop/ms724485%28v=vs.13%29.aspx |title=Kernel objects] |access-date=2014-01-08 |archive-date=2017-09-18 |archive-url=https://web.archive.org/web/20170918202244/https://msdn.microsoft.com/en-us/library/windows/desktop/ms724485(v=vs.13).aspx }}</ref>用户态的系统服务与应用程序使用 ''Executive objects'', 执行对象,这是 [[Windows NT体系结构|Windows Executive]] 对外暴露的对象, 用来封装一个或多个内核对象。 Executive objects 执行对象还用于实现 NT 子系统或 POSIX 子系统的一些功能。
 
Windows NT 暴露的 Executive object 的类型执行对象包括:
当对象创建时,指向对象实例的索引也被创建,称为句柄(handle)<ref>每个进程中都存在一个句柄表,列出了所有本进程内可以使用的句柄。句柄表实际上是一个数组,每个数组元素为一个结构,包含一个指向内核对象的指针、访问掩码、继承标识等。句柄实际上是进程句柄表数组的下标。因此句柄是进程私有的。</ref>。对象管理子系统使用句柄与命名两种方式管理对象实例。句柄在一个进程内部是共享的,但在进程之间不是直接可复用,需要特别方式在进程间传递对象句柄。一个进程任何时刻最多拥有 2<sup>24</sup>,即大约 16,000,000 个句柄。句柄按照对象的分类可分为文件句柄、事件句柄、进程句柄等。一个进程对一个对象可以有多个句柄,以便按照不同权限来访问对象。
 
Windows NT 暴露的 Executive object 的类型包括:
{| class="wikitable" align="center"
|-
!类别 !!描述 !!创建 / 获取句柄[[系统调用]] !!创建 / 获取句柄函数 !!释放句柄函数 !! 未通知状态 !! 通知状态 !! 等待成功的副作用
|-
!目录
| 用来存放内核对象。多级嵌套的目录将所有内核对象组织成一个树形结构
|NtCreateDirectoryObject<br />NtOpenDirectoryObject
|无
|-
![[进程]]
| 线程的集合,拥有共同的虚拟内存空间与控制信息
|NtCreateProcess<br />NtOpenProcess
|CreateProcess<br>OpenProcess<br>GetCurrentProcess
|CloseHandle<br>TerminateProcess
第24行 ⟶ 第35行:
![[线程]]
| 进程内部,执行程序的实体。
|NtCreateThread<br />NtOpenThread
|CreateThread<br>CreateThreadEx<br>OpenThread<br>GetCurrentThread
|CloseHandle<br>TerminateThread
第32行 ⟶ 第44行:
![[作業 (電腦)|作业]]
| 进程的集合
|NtCreateJobObject<br />NtOpenJobObject
|CreateJobObject
|CloseHandle
第39行 ⟶ 第52行:
|-
![[電腦檔案|文件]]
| 一个打开的计算机文件或 I/O 设备。
|NtCreateFile<br />NtOpenFile
|CreateFile
|CloseHandle<br>DeleteFile
|当 I/O 请求正在处理时
|当 I/O 请求处理完毕时
|无
|-
![[文件映射对象]]
| 一块内存区域,映射到一个文件。
|NtCreateSection<br />NtOpenSection
|CreateFileMapping
|CloseHandle
第56行 ⟶ 第71行:
! [[访问令牌]]
| 一个对象的访问权。
|NtCreateToken<br />NtDuplicateToken<br />NtOpenProcessToken<br />NtOpenThreadToken
|CreateRestrictedToken<br>DuplicateToken<br>DuplicateTokenEx<br>OpenProcessToken<br>OpenThreadToken
|CloseHandle
第64行 ⟶ 第80行:
![[事件 (同步原语)|事件]]
| 封装了某些信息的一个对象,用于通知某些进程。
|NtCreateEvent<br />NtOpenEvent
|CreateEvent<br>CreateEventEx<br>OpenEvent
|CloseHandle
|ResetEvent,或 PulseEvent,或自动重置事件等待成功
|当调用 SetEvent,或 PulseEvent
|自动重置事件等待成功后将自动 reset重置
|-
![[信号量]]
| 用于串行化访问某些资源的对象。
|NtCreateSemaphore<br />NtOpenSemaphore
|CreateSemaphore<br>CreateSemaphoreEx<br>OpenSemaphore
|CloseHandle
第80行 ⟶ 第98行:
![[互斥锁]]
| 用于串行化访问某些资源的对象。
|无
|CreateMutex<br>CreateMutexEx<br>OpenMutex
|CloseHandle
第88行 ⟶ 第107行:
![[临界区域]]
| 使得指定的代码段被串行执行
|
|InitializeCriticalSection<br>InitializeCriticalSectionAndSpinCount
|DeleteCriticalSection
|被其他线程拥有时(试图 EnterCriticalSection)
|未被其他线程拥有时(LeaveCriticalSection)
第96行 ⟶ 第116行:
![[定时器]]
| 按照固定时间间隔通知某些进程的对象。
|NtCreateTimer<br />NtOpenTimer
|CreateWaitableTimer<br>CreateWaitableTimerEx
|CloseHandle
第104行 ⟶ 第125行:
![[Timer queue]]
|
|无
|
|
第112行 ⟶ 第134行:
![[Timer-queue timer]]
|
|无
|
|
第118行 ⟶ 第141行:
|
|-
![[注册表|注册表键值]]
| Windows 注册表条目的键值,数据类型不是 HANDLE 而是 HKEY
|RegCreateKeyEx<br>RegOpenKeyEx
|RegCloseKey
第128行 ⟶ 第152行:
![[桌面]]
| 包含 [[GUI]] 元素的一个逻辑显示面,数据类型是 HDESK
|无
|CreateDesktop<br>OpenDesktop<br>GetThreadDesktop
|CloseDesktop
第136行 ⟶ 第161行:
!WindowStation
| 包含一些桌面对象、一块剪贴板对象、以及其他对象的对象,数据类型是 HWINSTA
|无
|CreateWindowStation<br>OpenWindowStation<br>GetProcessWindowStation
|CloseWindowStation
第144行 ⟶ 第170行:
![[剪贴板]]
| 用于其它对象的临时存储空间。
|无
|OpenClipboard
|CloseClipboard
第150行 ⟶ 第177行:
|
|-
![[符号链接]]
| 对其他对象的引用
|NtCreateSymbolicLinkObject<br />NtOpenSymbolicLinkObject
|
|
第160行 ⟶ 第188行:
![[事件日志]]
|
|无
|OpenEventLog, <br>RegisterEventSource, <br>OpenBackupEventLog
|CloseEventLog
|
第168行 ⟶ 第197行:
!目录下更改通知
|若指定的目录下发生了文件名、属性等更改,则唤起本事件
|FindFirstChangeNotification
|FindCloseChangeNotification
第174行 ⟶ 第204行:
|重置事件状态;若需要监视下一次更改,使用循环搭配 FindNextChangeNotification
|-
![[堆|堆内存]]
!通信设备
|
|CreateFile("COM1") 等
|CloseHandle
|
|-
![[控制台]]输入[[缓冲区]]
|GetStdHandle(STD_INPUT_HANDLE)
|CloseHandle
|不存在任何输入时
|存在输入时
|无
|-
!控制台输出(屏幕)缓冲区
|
|GetStdHandle(STD_OUTPUT_HANDLE)<br>GetStdHandle(STD_ERROR_HANDLE)
|CloseHandle
|-
|-
![[堆|堆内存]]
|
|HeapCreate<br>GetProcessHeap<br>GetProcessHeaps
|HeapDestroy<br>不应释放进程的缺省堆
第209行 ⟶ 第215行:
![[IOCP|I/O 完成端口]]
|
|NtCreateIoCompletion<br />NtOpenIoCompletion
|CreateIoCompletionPort
|CloseHandle
第217行 ⟶ 第224行:
![[Mailslot]]
|
|NtCreateMailslotFile<br />
|CreateMailslot
|CloseHandle
第225行 ⟶ 第233行:
!内存资源通知
|
|CreateMemoryResourceNotification
|CloseHandle
第233行 ⟶ 第242行:
![[Portable Executable|模块]]
|只有自己 LoadLibrary 加载的 DLL 才需要释放;数据类型为 HMODULE;WinMain 函数的 hInstance 参数是指向 EXE 主程序的 HMODULE(数据类型为 HINSTANCE)
|无
|LoadLibrary<br>LoadLibraryEx<br>GetModuleHandle<br>GetModuleHandleEx<br>WinMain 函数的 hInstance 参数
|FreeLibrary
第240行 ⟶ 第250行:
|-
![[管道]]
|不同于 Unix 管道,Windows 连匿名管道也可以是双工(双向传输)的;创建管道的一方称为服务端,连接到已存在或将要存在的管道的一方称为客户端
|NtCreateNamedPipeFile
|CreateNamedPipe<br>CreatePipe<br>CreateFile
|CloseHandle<br>DisconnectNamedPipe
第249行 ⟶ 第260行:
![[套接字]]
|Unix 下的套接字只是普通 [[文件描述符|fd]],而 Windows 下的套接字一般而言和普通([[文件系统]])文件不一样,推荐使用专门的套接字 API 操作;数据类型是 SOCKET(UINT_PTR)
|无
|WSASocket<br>WSAAccept
|closesocket
第257行 ⟶ 第269行:
!资源更新
|使用 UpdateResource 更新某个 PE 模块中的资源(Resource,包括字符串、图标等)
|无
|BeginUpdateResource
|EndUpdateResource
第263行 ⟶ 第276行:
|
|}
 
与内核对象相对,还有用户对象与 GDI 对象。
*用户对象:每个对象仅有一个句柄,句柄不能复制或继承,不能引用其他用户会话中的进程的用户句柄。任何进程只要有对某个用户句柄访问权限,即可以访问该用户对象。一个进程最多有 65536 个用户对象句柄。用户对象包括:快捷键表 HACCEL、插入点光标、鼠标指针 HCURSOR、DDE 会话、窗口钩子、图标 HICON、菜单 HMENU、窗口 HWND、窗口位置。<ref>[http://msdn.microsoft.com/en-us/library/windows/desktop/ms725486%28v=vs.85%29.aspx User Objects]</ref>
*GDI 对象:每个对象仅有一个句柄,句柄为进程私有。一个进程最多有 65536 个 GDI 对象句柄。GDI 对象包括:位图 HBITMAP、画刷 HBRUSH、设备环境(DC)HDC、[[EMF|增强型图元文件(EMF)]]、EMF 设备环境、字体 HFONT、内存 DC、图元文件、图元文件 DC、调色板 HPALETTE、画笔 HPEN、区域(Region)HRGN。<ref>[http://msdn.microsoft.com/en-us/library/windows/desktop/ms724291%28v=vs.85%29.aspx GDI Objects]</ref>
===对象结构===
每个被对象管理子系统所管理的对象,包含头部和体部。头部是对象管理子系统使用的状态信息。体部是对象相关的数据与暴露的服务。
第310行 ⟶ 第319行:
全局命名空间使得多个客户会话间的进程可以通信。例如,一个客户/服务器使用互斥锁来同步,服务器模块在全局命名空间创建一个互斥锁对象,然后客户进程使用"Global\"前缀来打开这个互斥锁对象。 客户进程可以明示使用 "Local\"前缀来在客户会话命名空间中创建对象。<ref>[http://msdn.microsoft.com/en-us/library/aa382954%28v=vs.13%29.aspx Kernel object namespaces]</ref>
 
OBJECT_ATTRIBUTES 结构:
<syntaxhighlight lang="cpp">
typedef struct _OBJECT_ATTRIBUTES{
ULONG Length;
第318行 ⟶ 第328行:
PSECURITY_DESCRIPTOR SecurityDescriptor;
PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
}OBJECT_ATTRIBUTES;
}
</syntaxhighlight>
 
Attributes 成员域可以是 0,或下述标志的组合:
OBJ_INHERIT
OBJ_PERMANANT
第336行 ⟶ 第347行:
* {{cite book
| title = Microsoft Windows Internals
| url = https://archive.org/details/isbn_9780735619173
| edition = 4th edition
| chapter = Chapter 3: System Mechanisms
| pages = [https://archive.org/details/isbn_9780735619173/page/124 124]–149
| pages = 124–149
| last = Russinovich
| first = Mark
第350行 ⟶ 第362行:
<references/>
==外部链接==
*[httphttps://web.archive.org/web/20151201151543/https://msdn.microsoft.com/en-us/library/windows/hardware/ff557759(v=vs.85).aspx Object Manager Routines (Windows Drivers)]
*[http://channel9.msdn.com/ShowPost.aspx?PostID=73995 Channel9 Interview] {{Wayback|url=http://channel9.msdn.com/ShowPost.aspx?PostID=73995 |date=20080421160156 }}
{{Windows Components}}
[[分类Category:微软API]]
[[分类Category:Windows组件]]
[[分类Category:Microsoft Windows]]
[[分类Category:Windows NT]]