【Windows內核原理與實現】讀書筆記(三)

Windows內核中對象管理

Windows對象管理器的基本設計意圖是:

  • 爲執行體的數據結構提供一種統一又可擴展的定義和控制機制。
  • 提供統一的安全訪問機制。
  • 在無需修改已有系統代碼的情況下,加入新的對象類型。
  • 提供一組標準的API來對對象執行各種操作。
  • 提供一種命名機制,與文件系統的命名機制集成在一起。

每一個對象都由兩部分構成:對象頭和對象體,所有對象的對象頭都具有統一的格式,對象頭包含了對象管理所需要的基本信息,包括對象名稱、類型、引用計數以及安全描述符等。在Windows中,每一種對象都需要一個對應類型的類型對象(即OBJECT_TYPE對象)。系統定義的對象種類是有限的,WRK支持31種對象(內置),各有一個全局的POBJECT。TYPE變量指向其類型對象。

WRK限定不超過48個類型對象,系統全局變量ObpObjectTypes數組記錄了所有已創建的類型對象。

對象的構造是由兩部分來完成的:(1)調用ObCreateObject,根據指定的類型對象來完成對象頭的初始化,並且按照指定的大小來分配對象體的內存;(2)完成對象體的初始化。前者可以統一完成,而後者不可以,因爲各種類型的對象有自己不同的初始化邏輯。

類型對象可以跟蹤記錄當前所有此種類型的對象。因爲所有的對象都是在ObpAllocateObject和ObpFreeobject中分配和釋放的。

對象管理器的兩個接口函數ObOpenObjectByName和ObReferenceObjectByName,正是通過ObpLookupObjectName來完成其打開對象或引用對象的功能的,另一個接口函數ObInsertObject,它的作用是把一個對象插入到一個進程的句柄表中,它也通過ObpLookupObjectName來驗證待插入的對象是否在全局名字空間中並不存在。

ObpLookupObjectName的基本執行邏輯:

  • 參數檢查
  • 如果調用者指定了RootDirectoryHandle參數,則利用此RootDirectory的Parse方法來解析對象,直到解析成功或者不成功,或者指示從頭解析。
  • 如果調用者沒有指定RootDirectoryHandle參數,則系統從全局的根目錄ObpRootDirectoryObject開始解析。這種情況下,傳遞進來的對象名稱必須以"\"開始。如果待查找的名稱僅僅是"\",則執行特殊處理。否則,執行下面的邏輯:(1)首先判斷名稱是否以"\??\"開頭,是的話,需要拿到當前進程的DeviceMap(設備表),以進一步查詢。(2)如果名稱正好是"\??",則直接返回當前進程的DeviceMap作爲結果。(3)調用ObpLookupDirectoryEntry函數,層層遞進,或者碰到具有Parse方法的對象,由它來解析餘下的名稱字符串,或者碰到子目錄對象,從而可以在子目錄對象中進一步查詢下一級名稱。

進程如果需要使用對象,必須通過句柄來完成。在內核中,將一個句柄轉換成對應的對象,可以通過ObReferenceObjectByHandle函數來完成。

對象的聲明週期由對象的引用計數來管理,一旦引用計數爲零,則對象的聲明週期結束,它所佔用的內存也可以被回收。對象的引用計數來源於兩個方面:(1)內核中指針引用;(2)進程打開一個對象並獲得一個句柄,它以後通過此句柄來引用此對象。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章