第一章 概念和工具
本章將介紹Microsoft Windows操作系統(tǒng)的關鍵概念和術語腰吟,比如Windows API,進程徙瓶,線程毛雇,虛擬內存,內核模式和用戶模式侦镇,對象灵疮,句柄,安全性和注冊表等壳繁,這些概念和術語將貫穿全書震捣。同時也會介紹一些可以用來探查Windows內部的工具荔棉,比如內核調試器,性能監(jiān)視器蒿赢,以及來自Windows Sysinternals的一些關鍵工具润樱。此外,還將說明如何以WDK(Windows Driver Kit)和SDK(Platform Software Development Kit)作為資源羡棵,來找到關于Windows內部機制的進一步信息壹若。
請一定要理解本章中講述的所有內容,本書其余章節(jié)將以此為基礎
1.1 Windows操作系統(tǒng)的版本
本書涵蓋了Microsoft Windows客戶機和服務器操作系統(tǒng)的最新版本:Windows 7(32位和64位)和Windows Server 2008 R2(64位)皂冰。除非特別聲明舌稀,否則本書中的講解適合用于所有版本。
1.2 基礎概念和術語
在本書講解過程中灼擂,我們會提到一些對于某些讀者來說可能并不熟悉的結構和概念壁查。在這一節(jié)中,我們將界定貫穿全書的術語剔应。在閱讀后續(xù)章節(jié)前睡腿,你應該熟悉這些術語。
Windows API
Windows應用編程接口(API)是針對Windows操作系統(tǒng)家族的用戶模式系統(tǒng)編程接口峻贮。在64位版本的Windows推廣以前席怪,32位版本Windows操作系統(tǒng)的編程接口被稱為Win32 API,以區(qū)別于原來的16位版本Windows的編程接口纤控,即16位Windows API挂捻。在本書中,術語Windows API兼指Windows的32位和64位編程接口船万。
注 :
Windows軟件開發(fā)工具(SDK)文檔描述了Windows API刻撒。這份文檔可以在www.msdn.microsoft.com在線免費查閱。關于如何在Windows基礎API上編寫程序耿导,有一份極好的資料---Jeffrey Richter和Christophe Nasarre所寫的Windows via C/C++ 一書声怔。
Windows API包含數千個可調用的函數,它們可以被分成以下一些大類:
- 基本服務
- 組件服務
- 用戶界面服務
- 圖形和多媒體服務
- 消息和協(xié)作
- 網絡
- Web服務
本書主要關注關鍵基本服務(比如進程和線程舱呻,內存管理醋火,I/O和安全性)的內部機理。
關于.NET
Microsoft.NET框架是由一個被稱為框架類庫(FCL,Framework Class Library)的類庫和一個提供了托管代碼執(zhí)行環(huán)境的公共語言運行庫(CLR,Common Language Runtime)組成的箱吕,后者提供的代碼執(zhí)行環(huán)境包含以下一些特征:
- 即時編譯
- 類型檢驗
- 垃圾回收
- 代碼訪問安全性
由于CLR具有這些特性芥驳,因此它所提供的開發(fā)環(huán)境能夠提高開發(fā)人員的生產效率,減少常見的編程錯誤茬高。
關于.NET框架及其核心架構的精彩描述兆旬,參見Jeffrey Richter的CLR via C#
Win32 API的歷史
有意思的是,Win32并不是Windows NT最初預定的編程接口雅采。因為Windows NT項目在啟動之初爵憎,目的是代替OS/2第2版慨亲,所以,它的主要編程接口是32位OS/2 Presentation Manager API宝鼓。
然而刑棵,項目進行了一年后,Microsoft Windows 3.0 進入市場愚铡,并且呈現(xiàn)出很好的發(fā)展勢頭蛉签。于是,Microsoft轉變了方向沥寥,使Windows NT成為未來Windows產品家族的替代品碍舍,而不是用來替代OS/2译打。也正是這個時候喜庞,才真正有必要定制Windows API---在此之前惩琉,在Windows 3.0 中盒粮,只有16位接口的API。
盡管當時在Windows API中將引入很多在Windows 3.1 上還無法使用的新函數痊远,但是稼跳,Microsoft還是決定讓新的API與16位Windows API在函數名稱酪术,語義和數據類型用法上盡可能兼容骤星,以便減輕將已有的的16位Windows應用程序移植到Windows NT上的負擔经瓷。這也是許多函數名稱和接口看起來并不一致的原因:為了確保當時新的Windows API與老的16位Windows API保持兼容,這是必須的洞难。
服務舆吮,函數和例程
在Windows的用戶文檔和程序設計文檔中,有幾個術語在不同的上下文環(huán)境中有著不同的含義队贱。例如色冀,服務可以指操作系統(tǒng)中可以被調用的例程,設備驅動程序或者服務器進程露筒。下面的列表描述了一些特定的術語在本書中的含義:
- Windows API函數 指Windows API中已被文檔化的呐伞,可以被調用的子例程敌卓,例如*CreateProcess慎式,CreateFile 和 GetMessage。
- 原生的系統(tǒng)服務(或者系統(tǒng)調用) 指操作系統(tǒng)中為文檔化的趟径,可在用戶模式下調用的底層服務瘪吏。例如,NtCreateUserProcess 是一個內部系統(tǒng)服務蜗巧,Windows的CreateProcess函數調用該服務來創(chuàng)建新的進程掌眠。
- 內核支持函數(或例程) 指位于Windows操作系統(tǒng)內部且只能在內核模式下調用的子例程。例如幕屹,ExAllocatePoolWithTag就是一個這樣的例程蓝丙,設備驅動程序調用該例程可以向Windows系統(tǒng)堆(稱為內存池)申請內存级遭。
- Windows服務 指由Windows服務控制管理器啟動的進程。例如渺尘,Task Scheduler服務運行在用戶模式進程中挫鸽,它支持at命令。
- DLL(動態(tài)鏈接庫) 指一組可調用的子例程鸥跟,合起來被鏈接成一個二進制文件丢郊,使用這些子例程的應用程序可以動態(tài)地加載此二進制文件。例如Msvcrt.dll(C運行庫)和Kernel32.dll(一個Windows API子系統(tǒng)庫)医咨。Windows的用戶模式組件和應用程序大量使用了DLL枫匾。DLL比靜態(tài)庫的優(yōu)勢在于,應用程序可以共享DLL拟淮,Windows保證在內存中只有一份DLL代碼干茉,供所有引用該DLL的應用程序共享。注意很泊,非可執(zhí)行的.NET程序集也被編譯成DLL等脂,但是,它們沒有任何子例程撑蚌,而是由CLR解析出編譯的元數據上遥,以便訪問對應的數據類型和成員。
進程争涌,線程和作業(yè)
盡管表面上看起來程序和進程非常相似粉楚,但本質上它們卻是截然不同的。程序是一個靜態(tài)的指令序列亮垫,而進程是一個容器模软,其中包含了執(zhí)行程序的特定實例所需的各種資源。從最高層次的抽象來看饮潦,Windows進程是由以下元素構成的:
- 私有的虛擬地址空間燃异,這是指該進程可以使用的一組虛擬內存地址。
- 可執(zhí)行的程序继蜡,它定義了初始化的代碼和數據回俐,并且被映射到該進程的虛擬地址空間中。
- 已打開句柄列表稀并,這些句柄指向各種系統(tǒng)資源仅颇,比如信號量,通信端口和文件碘举,該進程內所有的線程都可以訪問這些系統(tǒng)資源忘瓦。
- 被稱為訪問令牌的安全環(huán)境,它標識了與該進程關聯(lián)的用戶引颈,安全組耕皮,特權境蜕,UAC虛擬化狀態(tài),會話凌停,以及有限的用戶賬戶狀態(tài)汽摹。
- 被稱為進程ID的唯一標識符
- 至少一個執(zhí)行線程
每個進程也指向它的父進程或者創(chuàng)建者進程。如果父進程不再存在苦锨,子進程中的這一信息并不會被更新逼泣。
關于進程和線程的信息,Sysinternals出品的Process Explorer提供了比其他任何工具都要多的細節(jié)舟舒,正因為如此拉庶,你將會在本書的許多實驗中看到這個工具的運用。
線程是一個進程內部的實體秃励,也是Windows執(zhí)行此進程時的調度實體氏仗。如果沒有線程,進程的程序將不可能運行起來夺鲜。線程包括以下一些最基本的部件:
- 一組代表處理器狀態(tài)的CPU寄存器中的內容皆尔。
- 兩個棧---一個是用于線程在內核模式下執(zhí)行時,另一個用于線程在用戶模式下執(zhí)行時币励。
- 一個被稱為線程ID的唯一標識符的一部分慷蠕。
- 有時候線程也有它們自己的安全環(huán)境,或者令牌食呻,多線程服務器應用程序要模仿其客戶的安全環(huán)境時流炕,常常會使用線程自己的安全環(huán)境。
易失的寄存器仅胞,棧和私有存儲區(qū)域結合起來被稱為線程的環(huán)境(context)每辟。因為這些信息隨著Windows所在機器架構的不同而有所不同,所以干旧,此架構必須是與底層架構相關的渠欺。Windows的GetThreadContext函數允許程序訪問這一與架構相關的信息(稱為CONTEXT塊)。
纖程與用戶模式調度器線程
因為將CPU的執(zhí)行從一個線程切換到另一個線程椎眯,將不可避免地涉及內核調度器挠将,所以,這可能是一個開銷昂貴的操作盅视,如果兩個線程經常頻繁來回切換則尤為如此捐名。Windows實現(xiàn)了兩種機制來降低這種開銷:纖程(fiber)和用戶模式調度(UMS)
纖程使得一個應用程序可以調度它自己的"線程"的執(zhí)行過程,而不必依賴Windows內置的基于優(yōu)先級的調度機制闹击。纖程也常被稱為"輕量"線程:從調度的角度來看,它們對于內核是不可見的成艘,因為它們是在用戶模式下在Kernel32.dll中實現(xiàn)的赏半。使用方法參考Windows SDK文檔贺归。
UMS線程僅在64位Windows長可用,它基本上提供了與纖程同樣的好處断箫,沒有更多的壞處拂酣。UMS線程有它們自己的內核線程狀態(tài),因此對于內核是可見的仲义,這使得多個UMS線程都可以發(fā)出阻塞的系統(tǒng)調用婶熬,對資源進行共享或競爭,并且有每個線程特有的狀態(tài)(per-thread state)
雖然線程有自己的執(zhí)行環(huán)境埃撵,但是赵颅,同一個進程內部的所有線程共享該進程的虛擬地址空間(以及同屬于該進程的其他資源),這意味著暂刘,一個進程內的所有線程都可以完全地讀或寫該進程的虛擬地址空間饺谬。然而,一個進程中的線程不可能無意識地引用另一個進程的地址空間谣拣,除非兩種情況:第二個進程將它的一部分私有地址空間變成共享內存區(qū)(shared memory section)(在Windows API中稱為文件映射對象(file mapping object))募寨;或者,第一個進程有權打開第二個進程森缠,從而可以使用諸如ReadProcessMemory 和 WriteProcessMemory 等跨進程的內存函數拔鹰。
除了私有地址空間和一個或者多個線程以外,每個進程還有一個安全環(huán)境和一個已打開句柄的列表贵涵,這些句柄指向諸如文件格郁,共享內存區(qū),或者像互斥體独悴,事件或者信號量等某個同步對象
每個進程都有一個安全環(huán)境例书,存儲在一個稱為訪問令牌(access token)的對象中。進程的訪問令牌包含了該進程的安全標識和憑證刻炒。在默認情況下决采,線程沒有自己的訪問令牌,但是他們也可以獲得一個訪問令牌坟奥,因此單獨的線程可以模仿另一個進程的安全環(huán)境树瞭。
虛擬地址描述符(AVD)是指一些數據結構,內存管理器利用這些數據結構來記錄進程正在使用的虛擬地址爱谁。
Windows在進程模型上提供了一個拓展晒喷,稱為作業(yè)(job)。作業(yè)對象的主要功能是访敌,使一組進程被當做一個整體來管理和維護凉敲。通過作業(yè)對象,可以對特定屬性進行控制,也可以對一個進程爷抓,或者所有與作業(yè)相關聯(lián)的進程進行限制势决。作業(yè)對象也可以為所有與該作業(yè)相關聯(lián)的進程記錄下基本審計信息,其中也包括曾經與改作業(yè)關聯(lián)但是已經終止了的進程的審計信息蓝撇。在某種程度上果复,作業(yè)對象彌補了Windows平臺上缺乏結構化的進程樹的不足,而且渤昌,它的功能虽抄。
虛擬內存
Windows實現(xiàn)了一個基于平面(線性)地址空間的虛擬內存系統(tǒng),使每個進程感覺自己獨立擁有一個很大的私有地址空間独柑。虛擬內存提供了一個內存邏輯視圖迈窟,它可能并不對應于內存的物理布局。在運行的時候群嗤,內存管理器借助于硬件的支持菠隆,將虛擬地址轉譯或者映射(map)成真正存放數據的物理地址。操作系統(tǒng)通過控制這一保護和映射機制狂秘,可以確保一個進程不會闖入到另一個進程中骇径,也不會改寫操作系統(tǒng)的數據。
因為大多數系統(tǒng)所擁有的物理內存者春,比當前正在運行的進程所用到的虛擬內存總量要少得多破衔,所以,內存管理器會將內存中的有些內容轉移或者翻(page)到磁盤上钱烟。將數據翻譯到磁盤上以后晰筛,就可以釋放這部分物理內存,因此拴袭,這些物理內存可以被別的進程所使用读第,或者用于操作系統(tǒng)本身。當線程訪問一個已被翻到磁盤上的虛擬地址時拥刻,虛擬內存管理器會將磁盤上的信息裝回內存中怜瞒。應用程序無須任何改變就可以利用這種分頁(paging)功能,因為在硬件的支持下般哼,內存管理器無須任何關于進程和線程的知識吴汪,也無須進程或線程的協(xié)助,就可以實現(xiàn)分頁蒸眠。
虛擬地址空間的大小隨著硬件平臺而有所不同漾橙。在32位x86系統(tǒng)中,總的虛擬地址空間有一個理論上的最大值4GB楞卡。在默認情況下霜运,Windows將這一部分地址空間的一半(4GB虛擬地址空間中較低的一半脾歇,x00000000x7FFFFFFF)分配給進程,作為它們獨有的私有存儲空間觉渴,而另一半(地址空間中較高的一半介劫,x80000000xFFFFFFFF)則用于它自己的被保護的操作系統(tǒng)內存徽惋。低一半地址空間的映射關系會發(fā)生變化案淋,以便總是反應出當前正在執(zhí)行的進程的虛擬地址空間,而高一半地址空間的映射關系總是由操作系統(tǒng)的虛擬內存構成险绘。Windows支持一些引導選項踢京,可以使那些運行帶有特殊標記的程序(在可執(zhí)行映像文件頭部設置了大地址空間感知標志)的進程能夠使用多達3GB的私有空間(給操作系統(tǒng)留下1GB)。這一選項使得像數據庫服務器這樣的應用程序的更多內容保留在進程的地址空間中宦棺,從而減少映射該數據庫的子集視圖的需求瓣距。
雖然3GB比2GB更好,但是代咸,對于映射非常大的數據庫(許多個GB)而言蹈丸,虛擬地址空間任然不足。針對在32位系統(tǒng)上的這種需求呐芥,Windows提供了一個被稱為地址窗口擴展(AWE,Addres Windowing Extension)的機制逻杖,使得32位應用程序可以申請多達64GB物理內存,然后將內存視圖或者窗口映射到它的2GB虛擬地址空間中思瘟。雖然AWE將管理"虛擬內存-物理內存"映射關系的負擔放到了程序員的身上荸百,但是,它確實解決了問題滨攻,使得進程能夠直接訪問更多的物理內存够话。超過了它的32位進程地址空間一次能夠映射的數量。
64位Windows為進程提供了更大的地址空間:在IA-64系統(tǒng)上位7152GB光绕,x64系統(tǒng)上為8192GB女嘲。注意,這些大小值并不代表這些平臺上的架構限制诞帐。64位地址空間的大小超過了170億GB欣尼,但當前的64位硬件限制了地址空間比該值要小,而在當前的64位Windows中景埃,由于Windows的實現(xiàn)機制媒至,此地址空間又被降低到8192GB(8TB)。
內核模式和用戶模式
為了避免用戶應用程序訪問和/或修改關鍵的操作系統(tǒng)數據谷徙,Windows使用了兩種處理器訪問模式(即使運行Windows的底層處理器支持多余兩種模式):用戶模式和內核模式拒啰。用戶程序運行在用戶模式下,而操作系統(tǒng)代碼(比如系統(tǒng)服務和設備驅動程序)運行在內核模式下完慧。內核模式是指這樣一種處理器執(zhí)行模式:它允許訪問所有的系統(tǒng)內存和所有的CPU指令谋旦。通過讓操作系統(tǒng)軟件比應用軟件有更高的特權級,處理器位操作系統(tǒng)設計者提供了必要的保護,可以確保行為不正常的應用程序不會破環(huán)系統(tǒng)整體的穩(wěn)定性册着。
注:
x86和x64處理器架構定義了四種特權級拴孤,或者稱為四個環(huán)(ring),來保護系統(tǒng)代碼和數據不會被低級別的代碼惡意地或無意地改寫甲捏。Windows使用特權級0(或稱為0環(huán))作為內核模式演熟,特權級3(或稱3環(huán))作為用戶模式。Windows之所以只使用兩級司顿,是因為它過去支持的一些硬件架構(比如Compaq Alpha和Silicon Graphics MIPS)只實現(xiàn)了兩個特權級芒粹。
雖然每個Windows進程都有自己私有的內存空間,但是內核模式的操作系統(tǒng)和設備驅動程序代碼共享一個虛擬地址空間大溜。虛擬內存中的內一個頁面都被標記了處理器必須在什么訪問模式下才可以讀和/或寫該頁面化漆。系統(tǒng)空間中的頁面只有在內核模式下才可以訪問,而用戶地址空間的所有頁面都可以在用戶模式下訪問钦奋。只讀頁面(比如包含靜態(tài)數據的頁面)在任何模式下都是不可寫的座云。此外,在支持不可執(zhí)行(no-execute)內存保護的處理器上付材,Windows將包含數據的頁面標記為不可執(zhí)行朦拖,從而防止數據區(qū)域被無意或惡意地當作代碼來執(zhí)行。
對于在內核模式下運行的組件伞租,32位Windows對它們所使用的私有系統(tǒng)內存并不提供讀寫保護贞谓。換句話說,一旦進入內核模式葵诈,操作系統(tǒng)和設備驅動程序的代碼可以完全訪問系統(tǒng)空間的內存裸弦,也可以繞過Windows的安全機制直接訪問對象。因為有大量的Windows操作系統(tǒng)代碼運行在內核模式下作喘,所以很關鍵的一點是理疙,對在內核模式下運行的組件必須要謹慎地設計和測試,以確保它們不會破壞系統(tǒng)的安全性泞坦,也不會造成系統(tǒng)不穩(wěn)定窖贤。
由于缺乏保護,因此贰锁,再加載第三方設備驅動程序時更需要加倍小心赃梧,因為一旦進入內核模式,這些軟件就可以完全訪問所有的操作系統(tǒng)數據豌熄。這一弱點也正是Windows要引入驅動程序簽名機制的原因之一授嘀。引入驅動程序簽名機制以后,當未簽名的即插即用驅動程序企圖加入系統(tǒng)中時锣险,Windows會警告用戶蹄皱,并且阻止其加入系統(tǒng)(如果做了這樣的配置)览闰。還有一種被稱為驅動程序檢驗器(Driver Verifier)的機制,可以幫助設備驅動程序的編寫者找到驅動程序中引發(fā)安全性或可靠性問題的缺陷(比如緩存區(qū)溢出或者內存泄漏)巷折。
在64位版本的Windows中压鉴,內核模式代碼簽名(KMCS,Kernel Mode Code Signing)策略規(guī)定锻拘,64位設備驅動程序(不僅僅是即插即用程序)必須要經過某個主碼認證權威機構發(fā)放的密鑰來簽名油吭。用戶不能明確地強制安裝未經簽名的驅動程序,即使管理員也不行逊拍,但有一個一次性的例外上鞠,這一限制可以在系統(tǒng)引導時手工禁止际邻,即芯丧,在引導時按下F8鍵,選擇高級引導選項"禁用驅動程序強制簽名(Disable Driver Signature Enforcement)"世曾。這會導致在桌面壁紙上出現(xiàn)一個水印缨恒,同時特定的數字版權保護(DRM)特性被關閉。
在第2章"系統(tǒng)架構"中將看到轮听,用戶應用程序將在進行系統(tǒng)服務調用時骗露,會從用戶模式切換到內核模式下。例如血巍,WIndows的ReadFile函數最終要調用Windows內部的一個例程萧锉,由該例程真正完成從一個文件中讀取數據的任務。由于該例程需要訪問內部的系統(tǒng)數據結構述寡,所以柿隙,它必須運行在內核模式下。從用戶模式切換到內核模式鲫凶,可以通過專門的處理器指令來完成禀崖,該指令會將處理器切換到內核模式下,并進入內核模式中的系統(tǒng)服務分發(fā)代碼螟炫,進一步調用Ntostrnl.exe或Win32k.sys中適當的內部函數波附。在將控制權返回用戶線程之前,處理器的模式被切換回用戶模式昼钻。通過這種方法掸屡,操作系統(tǒng)將自身和它的數據保護起來,使它們不會被用戶進程看到或者修改然评。
因此仅财,很自然地,對于一個用戶線程來說沾瓦,它的一部分時間運行在用戶模式下满着,另一部時間運行在內核模式下谦炒。實際上,因為圖形和窗口系統(tǒng)的大部分時間也運行在內核模式下风喇,所以宁改,圖形密集的應用程序花在內模式下的時間比在用戶模式下的時間多得多。這一點很容易測試魂莫,一種簡單的辦法是还蹲,運行一個圖形密集的應用程序,比如"畫圖"或者Chess Tians耙考,然后使用性能監(jiān)視器(具體方法百度)
終端服務及多個會話
終端服務指的是在單個系統(tǒng)中谜喊,Windows對于多個可交互用戶會話的支持。利用Windows的終端服務倦始,一個遠程用戶可以在另一臺機器上建立一個會話斗遏,并且登陸進去,在該服務器上運行應用程序鞋邑。服務器把圖形用戶界面(以及其他可配置的資源诵次,比如音頻和剪切板)傳送到客戶機,客戶機把用戶的輸入傳回服務器枚碗。(與X窗口系統(tǒng)類似逾一,Windows允許在一個服務器系統(tǒng)運行獨立的應用程序,其顯示部分遠程傳送到客戶機肮雨,而非將整個桌面遠程到客戶機)遵堵。
第一個會話被認為是服務會話,或者零號會話怨规,它包含了宿納系統(tǒng)服務的進程陌宿。在機器的物理控制臺上的第一個登陸會話位一號會話,而其他會話可以通過遠程桌面連接程序(Mstsc.exe)來建立椅亚,或者通過使用快速用戶切換來建立限番。
Windows的客戶機版本允許單個遠程用戶連接到及其上,但如果有人已經在控制臺上登陸了呀舔,則工作站會被鎖酌峙啊(也就是說,一個人可以利用本地或者遠程方式使用Windows客戶機系統(tǒng)媚赖,但不能同時以這兩種方式來使用系統(tǒng))霜瘪。
Windows服務器系統(tǒng)支持兩個并發(fā)的遠程連接(這是為了方便遠程管理,例如惧磺,有些管理工具要求登錄到被管理的機器中才可以使用)颖对,以及兩個以上的遠程會話。
所有Windows客戶機版本都支持通過使用一個被稱為快速用戶切換(fast user switching)的特性磨隘,在本地創(chuàng)建多個會話缤底。當用戶選擇斷開其會話顾患,而不是注銷其登錄時,當前會話仍然保留在系統(tǒng)中个唧,而系統(tǒng)返回到主屏幕江解。如果一個新的用戶登陸進來,則新建一個會話徙歼。
對象和句柄
在Windows操作系統(tǒng)中犁河,內核對象是指某個靜態(tài)定義的對象類型的單個運行時實例。對象類型由系統(tǒng)定義的的數據類型魄梯,在該數據類型的實例上進行操作的一組函數桨螺,以及一組對象屬性構成。如果你編寫Windows應用程序酿秸,那么灭翔,你可能會遇到進程,線程允扇,文件和事件對象缠局,這只是對象的一些例子而已。這些對象都是以Windows創(chuàng)建和管理的底層對象為基礎的考润。在Windows中,任何進程都是進程對象類型的實例读处,文件是文件對象類型的實例糊治,如此等等。
對象屬性是對象中的數據域罚舱,每個對象屬性定義了對象的一部分狀態(tài)井辜。例如,類型為進程的對象管闷,其屬性包括進程ID粥脚,基本調度優(yōu)先級和一個指向訪問令牌對象的指針。對象方法包个,即操縱對象的手段刷允,通常用于讀取或者改變對象的屬性。例如碧囊,進程的open方法接受一個進程標識符作為輸入树灶,返回一個指向該進程對象的指針作為輸出。
對象和普通數據結構之間的最根本區(qū)別是糯而,對象的內部結構是不透明的天通。你必須調用一個對象服務才可以獲得對象內部的數據,或者把數據放入對象內部熄驼。你不能直接讀取或者改變一個對象內部的數據像寒。這一區(qū)別將對象的底層實現(xiàn)與那些僅僅使用該對象的代碼隔離開來烘豹,此技術使得對象的實現(xiàn)可以隨著時間而容易地改變。
借助一個被稱為對象管理器的內核組件诺祸,Windows中的對象提供一種便捷的途徑來實現(xiàn)下列四個重要的操作系統(tǒng)任務:
- 為系統(tǒng)資源提供可供人讀的名稱吴叶。
- 進程之間共享資源和數據。
- 保護資源序臂,避免未授權的訪問蚌卤。
- 引用跟蹤,這使得系統(tǒng)能夠知道一個對象何時不再有用奥秆,從而可以被自動釋放逊彭。
并非Windows操作系統(tǒng)中的所有數據結構都是對象。只有確實需要被共享构订,保護侮叮,命名或者讓用戶模式程序看得到(通過系統(tǒng)服務)的數據才被放入到對象中。僅僅被操作系統(tǒng)的某一個組件用來實現(xiàn)其內部函數的數據結構并不是對象悼瘾。
安全性
Windows從一開始就被要求是安全的囊榜,能夠滿足政府和工業(yè)界各種正式的安全評級的需求
Windows的核心安全功能包括:針對所有可共享系統(tǒng)對象(比如文件,目錄亥宿,進程卸勺,線程等等)的自主保護(need-to-know)和強制完整性保護,安全審計(針對主體或者用戶和他們發(fā)起的動作的記錄)烫扼,登陸時候的用戶認證曙求,以及禁止用戶通過訪問未初始化資源的做法來訪問其他用戶已釋放的資源(比如空閑內存或磁盤空間)。
Windows有三種對對象的訪問控制形式映企。第一種控制形式稱為自主訪問控制悟狱,大多數人一想到操作系統(tǒng)安全性,自然就會想到這種保護機制堰氓。其做法是挤渐,由對象(比如文件或者打印機)的所有者授權或者拒絕其他人訪問這些對象。當用戶登陸系統(tǒng)中時双絮,他們會得到一組安全憑證浴麻,或者一個安全環(huán)境。當他們試圖訪問對象時掷邦,系統(tǒng)會將他們的安全環(huán)境與他們要訪問的對象的訪問控制列表進行比較白胀,以確定他們是否可以執(zhí)行所請求的操作。
當自主訪問控制不能滿足需要時抚岗,應該使用特權訪問控制或杠。這種方法可以確保:即使對象的所有者當前無法聯(lián)系到,也有人可以訪問被保護的對象宣蔚。例如向抢,如果一個員工離開了公司认境,則管理員必須有辦法訪問那些本該只有該員工才可以訪問的文件。在這種情況下挟鸠,在Windows中叉信,管理員能夠接管這些文件的所有權,從而可以根據需要管理它們的權限艘希。
最后硼身,當需要額外的一層安全控制以實現(xiàn)在同一個賬戶內部的對象訪問保護時,需要使用強制完整性控制覆享。它既被用于將Internet Explorer的保護模式與用戶的配置隔離開佳遂,也被用于保護那些由提升了特權的管理員所創(chuàng)建的對象,避免被未被提升特權的管理員賬戶所訪問撒顿。
注冊表
如果你與Windows操作系統(tǒng)打過交道丑罪,那么,你可能聽說過或者看到過注冊表凤壁。探討Windows內部機理吩屹,就不能不提到注冊表,因為注冊表是系統(tǒng)數據庫拧抖,它包含了引導和配置系統(tǒng)所必需的消息煤搜,全系統(tǒng)范圍內控制Windows操作的軟件設置,安全數據庫徙鱼,以及針對每個用戶配置設置(比如使用哪個屏幕保護程序)宅楞。
同時,注冊表也是一個反映內存中易失數據的窗口袱吆,比如系統(tǒng)的當前硬件狀態(tài)(哪些設備驅動程序已經加載,它們用到了哪些資源距淫,等等)以及Windows的性能計數器绞绒。
雖然許多Windows用戶和管理員從來不需要直接查看注冊表(因為你可以通過標準的管理工具來查看或者改變大多數配置設置),但是榕暇,注冊表仍然是一個非常有用的Windows內部信息來源蓬衡,因為它包含了許多會影響系統(tǒng)性能和行為的設置。在本書中你將會看到許多注冊表鍵彤枢,當介紹某些組件時狰晚,將會提及相應的注冊表鍵。本書中提到的絕大多數注冊表鍵位于全系統(tǒng)范圍的配置(即HKEY_LOCAL_MACHINE)下面缴啡,我們將其縮寫位HKLM。
Unicode
Windows區(qū)別于大多數其他操作系統(tǒng)的一個方面是,它的大多數內部文本串是以16位寬度的Unicode字符來存儲和處理的雁竞。
因為許多應用程序只處理8位(單字節(jié))ANS字符串,所以谬晕,接受字符串參數的Windows函數有兩個入口點:一個Unicode(寬字符,16位)版本和一個ANSI(窄字符携取,8位)版本攒钳。
無論哪個語言版本的Windows,它們都包含同樣的函數雷滋。Windows不再使用多種不同的語言版本不撑,而是使用一份全球同一的二進制代碼,這樣晤斩,同一份安裝可以支持多種語言(只需導入各種語言包即可)焕檬。