WINDOWS內核對象

  首先說一下什麼是內核對象,之所以叫內核對象就是這個對象是由內核創建,由內核維護,不屬於某一個進程,而是屬於整個系統的。比如互斥對象,文件印象對象等等。。內核對象有兩個比較重要的特性:

  1. 每個內核對象都不屬於某個進程,而屬於整個系統,幾乎每個內核對象都有一個計數器,計數正在使用這個對象的進程數
  2. 每個內核對象都會有一個安全描述符,描述了誰創建了這個對象,誰能訪問它,誰不能訪問它。

既然內核對象由系統維護,那麼某個進程是怎麼維護它已經創建的內核對象呢?是通過一個進程內核對象句柄表,這個表是進程被初始化時,系統分配給他的。(這個表只記載着內核對象的使用情況,而不記載用戶對象和GDI對象)。先給出一個內核對象表的模型

Index Pointer to Kernel Object Memory Block Access Mask (DWORD of Flag Bits) Flags (DWORD of Flag Bits)
1 0x???????? 0x???????? 0x????????
2 0x???????? 0x???????? 0x????????

下面通過進程創建一個內核對象和銷燬一個內核對象來說明進程是怎麼維護這個表的。。。。

創建內核對象:

  1. 進程調用Create*()創建了某個內核對象kObject,調用了Create*()後,內核就爲kObject分配一個內存塊,這時,內核對進程的句柄表進行掃描,找出一個空項,然後進行初始化。這個函數返回一個HANDLE(注意這個HANDLE是於進程相關的,其他進程調用這個HANDLE很可能出錯!)其實這個HANDLE就是進程內核對象表中kObject所在的項目索引。
  2. 當操作系統給kObject進行初始化的時候,將kObject的計數器加1,如果計數器等於1就創建一個新的kObject,如果大於1則不會創建一個新的,而是用一個已經有的。

銷燬內核對象:

  1.  只需要調用CloseHandle(HANDLE hObj)就可以了。進程會找到對應的索引,然後刪除這一項。
  2. 通過句柄表的項目找到內核的實際內存地址,然後將它的計數器減1,如果等於0,就釋放這個內核對象所佔用的空間

說到這裏,我們發現內核對象雖然是屬於系統的,但是,進程之間卻還是不能共享某個內核對象。因爲每個進程所擁有的僅僅是一個HANDLE,而這個HANDLE卻是於進程相關的。其實要想進程間共享內核對象也是有辦法的,下面就來介紹3種:

1.對象句柄的繼承:

           首先說一下,這種方法只能用於父子進程之間。上面的句柄表中有一個項目Flags ,這個項目的值就表示這個內核對象是否可以被子進程所繼承(1表示可以繼承)。然後父進程在調用CreateProcess()的時候,只要將一個參數設置爲可繼承句柄表,那麼父進程中的所有可繼承句柄都將複製到子進程的句柄表中。注意,是複製,所以可繼承的內核對象的條目在兩個進程的句柄表中將是一模一樣的,HANDLE也是一樣,所以,子進程纔可以使用這個HANDLE。但是注意,子進程在創建之後,它自己並不知道已經擁有了這個內核對象的句柄,所以,一般通過命令行將句柄傳遞給子進程,這是最常用的方法。當然還有其他的方法,但是我還沒學到。。lol

           在對對象進行繼承的時候,可能會遇到這種情況,你想把句柄表中的某一個項目繼承給子進程A,但是卻不希望將它傳遞給B。這個時候就可以調用SetHandleInformation(HANDLE hObj,DWORD dwMask,DWORD dwFlag)改變繼承的屬性。

2.命名對象:

           在調用Create*()創建內核對象時,可以將這個內核對象命名。下面來看下創建互斥對象的函數原形CreateMutex(PSECURITY_ATTRIBUTE psa,BOOL bInitialOwner,PCTSTR pszname);最後一個參數就是給這個互斥對象進行命名所用到的字符串指針(這個字符串一定要是以0結尾的)。當一個進程通過這個函數創建對象的時候,就會去查找名字空間,看是否已經有一個相同名字的內核對象,如果有,先檢查是否是相同的對象,如果不是就調用失敗,如果是,再檢查安全性,看是否有響應的訪問權,有就將這個內核對象的計數加1,並在進程的內核對象表中添加項目。有一點需要說明下,就是所有的內核對象都在一個名字空間裏面。所以在命名的時候最好使用GUID。

3.複製對象句柄:

將一個進程的句柄表中的項目複製給另外一個。方法就是調用DuplicateHandle()。具體怎麼調用查看MSDN。

 

發佈了48 篇原創文章 · 獲贊 2 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章