標籤:讀書筆記 windows核心編程 第三章 控制代碼 安全性
最近一直沒有更新部落格,因為一直在想一個問題,核心對象這一章內容很多很重要,自己沒有掌握好也沒有把握寫好這一章,最後還是決定能寫多少寫多少,一面寫一面學,後續學到新的再更新吧;
《windows核心編程》提了幾種核心對象:
存取權杖對象:與windows的安全性有關,目前不是很懂,瞭解後再寫;
事件對象: Event對象,可跨進程同步; 由CreateEvent建立;
檔案對象: File對象,比較常見; 由CreateFile建立;
檔案對應物件: 通過檔案對應可以方便的操作檔案(如同檔案資料就在記憶體上一樣);由CreateFileMapping建立,WinObj可以看出系統建立的是Session對象;
I/O完成連接埠對象: 簡稱IOCP,經常用於通訊端編程中;
工作物件: 不是很瞭解;
郵件槽對象: 可用於進程間同步,但很少用。目前還沒有發現有其他的特殊用途;
互斥量對象: 常用於的進程同步;
管道對象: 常用於進程的資料轉送,並且進程可以在不同的電腦上;
進程對象: 作業系統 利用此對象進行進程的管理工作
線程對象: 作業系統利用此對象進行線程的管理工作;
訊號量對象: 常用於線程同步的核心對象,功能強大;
可等待的計時器對象:不是很瞭解,應該可以使用精度很高的Timer;
線程池對象: 沒用過;
幾乎所有的核心對象內部都有安全性描述元(描述哪些成員可以訪問以及何種存取權限)和使用計數(當前對象被幾個成員同時使用著,如果為0,代表已沒有成員使用了,該核心對象就沒有存在的意義了,會自動銷毀)兩個成員;
使用計數:
為什麼會有使用計數?
核心對象是作業系統而不是單個程式擁有的,這樣的話可能就會出現多個程式使用同一個核心對象,使用計數值就表示了該核心對象被引用了多少次,當該核心對象被再次開啟時計數值+1,當被Close時計數值-1,當計數值減為0時,作業系統自動銷毀該核心對象;
(當進程終止時,作業系統會逐個Close掉控制代碼表中的所有控制代碼)
安全性描述元:
安全性描述元提供了誰擁有對象,誰可以訪問對象,以何種方式訪問(DACL)以及何種審查訪問類型(SACL)等資訊。一個使用者A建立了對象ObjectA(File,Pipe等),但使用者A希望使用者B僅僅可以讀不可以寫ObjectA,這時候可以通過安全性描述元完成這一需求;
安全性描述元的結構體如下:
typedef struct _SECURITY_DESCRIPTOR { UCHAR Revision; //版本控制資訊; UCHAR Sbz1; //版本控制資訊; SECURITY_DESCRIPTOR_CONTROL Control; //unsigned short 類型,控制位; PSID Owner; // 對象的擁有者SID, 可以更改安全性描述元,而不管其他人對訪問的鎖定。 PSID Group; // Windows 通常忽略此參數(這是為了 POSIX 相容性,但它現在已經退化了) PACLSacl; //指定要對對象執行的審核的類型。如果發生了審核事件,會被儲存到審核事件的日誌中。 PACL Dacl; //這兒儲存著對象的許可(允許誰訪問對象,而拒絕誰)。 }SECURITY_DESCRIPTOR;
其中Dacl指向的是ACL的結構體:
typedef struct _ACL { UCHAR AclRevision; //版本控制資訊; UCHAR Sbz1; //版本控制資訊; USHORT AclSize; //(Bytes) ACL + ACEs+ Free Buffer 見winnt.h 注釋; USHORT AceCount; // ACE 個數 見winnt.h注釋; USHORT Sbz2; //版本控制資訊; } ACL;typedef ACL *PACL;
我們可以看到這裡有AceCount,但是沒有發現AceList這個儲存Ace資訊的欄位,我猜測Ace欄位也儲存到了這個結構體中只不過沒有進行命名不讓使用者程式去索引,實現手段類似於char acelist[0],這些僅僅是猜測,如果想知道的話,可以跟蹤GetAce或者AddAce的彙編代碼就知道了;
ACE(存取控制項目)需要關注的三個欄位是AceType,Mask和SID,AceType包括allow(允許)/deny(拒絕)/audit(審計)/ alarm(警告);Mask表示允許或者拒絕的行為組合;SID表示關聯的SID;
關於Token:
看完《深入解析windows作業系統》後再加;
當開啟一個對象時,會從線程所擁有的令牌中(如果存在模仿令牌則使用模仿令牌,否則使用主令牌)擷取使用者名稱和使用者所在組列表,與對象的安全性描述元中的DACL比較,這個時候會發生如下情況之一:
1. 對象的DACL==Null,則線程擁有完全的存取權限。
2. 對象的DACL不為Null,但是AceCount==0(ACE,存取控制項目),則拒絕任何線程訪問。
3. 遍曆DACL,找到跟令牌中使用者或組一致的Ace,如果該Ace指明沒有擁有制定的存取權限,則直接退出安全檢查函數,並拒絕該線程訪問。
4. 遍曆DACL,沒找到跟令牌中使用者或組一致的Ace,並拒絕該線程訪問。
5. 遍曆DACL,找到跟令牌中使用者或組一致的Ace,如果該Ace指明擁有制定的存取權限,則直接退出安全檢查函數,並允許該線程訪問。
安全性描述元以及其他安全性的文章可參考:
http://blog.csdn.net/hjxyshell/article/details/38502933
http://blog.csdn.net/hjxyshell/article/details/38503387
http://www.doc88.com/p-382740626684.html
《深入解析windows作業系統》第八章
核心對象是由作業系統建立、訪問、修改、銷毀的記憶體塊並且只能由核心訪問,使用者程式不應該去猜測記憶體塊的內容進行訪問和更改,使用者程式如果想操作核心對象的話,應該使用Windows提供的一組函數;當使用者程式調用函數建立(由核心執行建立的操作)或者開啟一個核心對象時,函數會返回一個控制代碼值(handle),這個控制代碼標識了該核心對象,將該控制代碼傳給對應函數可對核心對象進行操作; 32位程式下sizeof(handle) = 4; 64為程式下 sizeof(handle) = 64;
Notice:
1. handle是與進程相關的,所以控制代碼值只能在同一進程內使用,不能把該值傳給另一進程使用訪問,如果需要多進程共同訪問同一核心對象,後面會介紹多個方法
2. handle的真實含義是handle/4 = handle對應核心對象在該進程控制代碼表的索引值,也證明1。但是控制代碼的含義並沒有在windows的文檔中公開,所以將來也有可能發生變化
讀書筆記----《windows核心編程》第三章 核心對象1(控制代碼與安全性)