Windows 之 跨進程邊界共享內核對象

跨進程邊界共享內核對象

在很多情況下,我們需要跨進程邊界共享內核對象。實現的方法有三種,繼承對象句柄,給對象命名,複製對象句柄。

1.繼承對象句柄

只有當進程具有父子關係時,纔可以使用對象句柄的繼承性。想要父進程生成一個子進程,並且賦予子進程對父進程內核對象的訪問權,父進程必須完成以下幾個操作:
當父進程創建內核對象時,必須向系統指明,它希望對象的句柄是個可繼承的句柄,也就是 SECURITY_ATTRIBUTES的 bInheritHandle 置爲 TRUE。並且創建子進程時,bInheritHandles參數同樣只置爲TRUE。這樣,子進程在創建出來的時候,也會由一張空的句柄表,系統會遍歷父進程的句柄表,將可繼承的項拷貝進子進程句柄表的相同位置。這樣同一個句柄值在父進程和子進程中就可以代表同一個內核對象了。
(這個操作滿足上述內核對象的所有特性,相應的計數器會加1)。需要注意的是,繼承的是句柄而不是對象。 若要改變內核對象句柄的繼承標誌,可以調用SetHandleInformation函數。

2.給對象命名

許多(雖然不是全部)內核對象都是可以命名的。名字的長度最多可以達到MAX_ PATH(定義爲2 6 0)個字符。
起名字要帶有特點,因爲Windows下的內核對象沒有命名的指導原則,也就是可能創建了一個內核對象的名字與已經存在的其他類型內核對象重複,這樣就會出錯。(名字與同一類型內核對象重複是可以的,這也是共享內核對象的方法)。
舉個例子來說明,用命名對象的方法來共享內核對象的:
在進程A中調用函數創建一個內核對象並起名爲 object。然後在B進程中調用函數創建同一個類型的內核對象並起名爲 object。這時,系統首先要查看是否已經存在一個名字爲 object的內核對象,由於確實存在一個名字爲object的內核對象,因此內核要檢查對象的類型,由於試圖創建的對象與已有的對象爲同一類型的對象,系統會執行一次安全檢查,以確定調用者是否擁有對該對象的完整的訪問權。如果擁有這種訪問權,系統就在進程B的句柄表中找出一個空項目,並對該項目進行初始化,使該項目指向現有的內核對象,如果該對象類型不匹配,或者調用者被拒絕訪問,創建對象的函數將運行失敗(返回NULL)。
進程B如果創建成功實際上並不是真的創建了一個內核對象,只是被賦予了一個進程相關的句柄,用於標識內核中已有的名爲object對象。這時內核對象的計數器會加1。
值得注意的是,當以這種方式創建成功內核對象時,創建對象函數的傳入的安全屬性將被忽略(因爲在內核中生成該對象的時候已經確定了它的安全屬性)。

除了調用函數(Create*)創建相同名字的內核對象以外,還有使用(Open*)函數來打開已有的內核對象。同樣需要擁有相同類型和相同名字的的對象纔可以成功被打開,否則返回NULL。
調用(Create )函數與調用(Open)函數之間的主要差別是,如果對象並不存在,那麼(Create)函數將創建該對象,而(Open)函數則運行失敗。**

3.複製對象句柄:

使用DuplicateHandle函數可以複製對象句柄。該函數取出一個進程的句柄表中的項目,並將該項目拷貝到另一個進程的句柄表中。先來看一下DuplicateHandle函數原型:

BOOL  DuplicateHandle(
HANDLE hSourceProcessHandle,
HANDLE hSourceHandle,
HANDLE hTargetProcessHandle,
PHANDLE phTargetHandle,
DWORD dwDesiredAcess,
BOOL bInheritHandle,
DWOED dwOptions); 

當調用DuplicateHandle函數時,第一和第三個參數hSourceProcessHandle和hTargetProcessHandle是內核對象句柄。
這些句柄本身必須與調用DuplicateHandle函數的進程相關。這兩個參數必須標識進程的內核對象,第二個參數hSourceHandle是任何類型的內核對象的句柄。
該句柄必須與hSourceProcessHandle句柄標識的進程相關。四個參數phTargetHandle是HANDLE變量的地址,它將接收穫取源進程句柄信息拷貝的項目索引,返回的句柄值與hTargetProcessHandle標識的進程相關。也就是說,第一個參數爲源進程的句柄,第二個參數爲源進程中的源句柄,第三個參數爲目標進程的句柄,第四個參數爲目標進程中的目標句柄的地址,用來接收內容的。
DuplicateHandle的最後3個參數用於指明該目標進程的內核對象句柄表項目中使用的訪問屏蔽值和繼承性標誌。
dwOptions參數可以是 0(零),也可以是下面兩個標誌的任何組合:
DUPLICATE _ SAME_ ACCESS和DU PLICATE_ CLOSE_ SOURCE。
如果設定了DUPLICATE _ SAME_ ACCESS標誌,則告訴DuplicateHandle函數,你希望目標進程的句柄擁有與源進程句柄相同的訪問屏蔽。使用該標誌將使 DuplicateHandle忽略它的dwDesiredAcess參數。
如果設定了DU PLICATE_ CLOSE_ SOURCE標誌,則可以關閉源進程中的句柄。該標誌使得一個進程能夠很容易地將內核對象傳遞給另一個進程。當使用該標誌時,內核對象的使用計數不會受到影響。

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