Windows對象管理

這是本頁的一個歷史版本,由Low power對話 | 貢獻2015年1月21日 (三) 15:33 (对象目录的描述)編輯。這可能和目前版本存在着巨大的差異。

對象管理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 ControlsRPC端口)
  • \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

參加

參考文獻

  1. ^ Kernel objects
  2. ^ 每個進程中都存在一個句柄表,列出了所有本進程內可以使用的句柄。句柄表實際上是一個數組,每個數組元素為一個結構,包含一個指向內核對象的指針、訪問掩碼、繼承標識等。句柄實際上是進程句柄表數組的下標。因此句柄是進程私有的。
  3. ^ User Objects
  4. ^ GDI Objects
  5. ^ Kernel object namespaces

外部連結