深入理解和使用Windows NT驅動程式的執行內容(一)

來源:互聯網
上載者:User

深入理解和使用Windows NT驅動程式的執行內容

原作:Open System Resources,Inc.
編譯:codewarrior@fudan cse

 

要理解Windows NT驅動程式,最重要的概念之一就是驅動程式執行時的所處的“執行內容”(Execution Context)。深入理解這個概念,並小心地應用你所掌握的關於它的知識,可以協助你編寫更快速高效的驅動程式。本節包括下列主題:l          什麼是上下文l          幾種不同的上下文l          上下文帶來的影響l          最大限度地利用上下文l          總結對於NT標準核心態驅動程式而言,一個重要的細節就是驅動程式的某個特定的函數執行時所處的上下文(Context),傳統上說來檔案系統開發人員大多對此比較關心,但若能牢固理解“執行內容”,對NT所有類型的核心態驅動程式的編寫人員而言,都會從中受益。深入理解執行內容並小心地使用之,可以確保設計出具有更高效能和更低運行代價的驅動程式。在本文中,我們將對執行內容的概念作一個探究。在本文結尾處,會舉出一個允許使用者程式到核心態執行並獲得系統全部特權的驅動程式,以此作為應用我們所介紹的內容的一個執行個體。 什麼是執行內容當我們提到一個常式的“上下文”的時候,我們指的是它的線程和進程的執行環境。在NT中,這個環境是通過當前的線程環境塊TEB和進程環境塊PEB構成的。因此所謂的上下文也就包括虛擬記憶體設定(告訴我們哪個實體記憶體塊對應哪些虛擬記憶體地址)、控制代碼的轉換(因為控制代碼是和進程相關聯的)、調度器資訊、棧,和通用寄存器以及浮點寄存器的集合。當我們問“一個特定的核心常式在哪個上下文中執行”時,我們實際上是在問,“NT核心的調度器當前指定哪個線程在運行?”因為每個線程都只屬於一個進程,故而當前的線程也就暗示了一個明確的當前進程。總之,“當前線程”和“當前進程”隱喻了所有這些區別於其他線程和進程的東西(控制代碼,虛擬記憶體,調度器狀態,寄存器)。對於核心態驅動程式編寫人員而言,虛擬記憶體上下文也許是“上下文”這一術語所包含的眾多方面中最有用的一個。回憶一下,NT把使用者進程映射到虛擬位址空間中低端的2GB,而把作業系統本身的代碼映射到虛擬位址空間中高端的2GB。當一個使用者進程中的一個線程在執行時,它的虛擬位址的範圍是從0到2GB,所有高於2GB的地址都被設為拒絕訪問,以防使用者直接存取作業系統的代碼和資料結構。當作業系統的代碼在執行時,它的虛擬位址的範圍是從0-4GB,目前使用者進程(如果有這麼一個的話)被映射到0-2GB的位址範圍內。在NT V3.51和V4.0中,映射到高端的2GB的代碼是固定不變的。但是映射到低段2GB的地址空間的代碼是在變化的,這取決於當前哪個進程在執行。讓我們比上面所介紹的再更深入一步,在NT這樣的記憶體布局中,給定進程P中一個有效使用者虛擬位址X(X應當小於等於2GB),那麼它同核心虛擬位址X都對應著相同的實體記憶體位置,當然,僅當P是當前進程(也正因為如此)且進程P的物理頁映射到作業系統低端的2GB虛擬位址空間中去時,這個結論才是正確的。上面的最後一句話換種說法來表述就是:“僅當P是當前進程上下文時上述結論正確”。因此,使用者虛擬位址和核心虛擬位址的高端的2GB實際是對應著相同的物理位置,如果進程上下文相同的話。(譯註:這裡所指的使用者虛擬位址空間和核心虛擬位址空間,是兩個不同的概念,核心虛擬位址空間和使用者虛擬位址空間並不是整個4GB空間中高低2GB的簡單劃分。實際上,核心虛擬位址空間指從核心的角度所看到的0-4GB的虛擬位址範圍;而使用者地址空間指的是從使用者態的進程角度看到的0-4GB的虛擬位址範圍——儘管對於使用者態的進程而言,它看到的4GB虛擬位址空間中高2GB是拒絕訪問的。稍候作者會用一張圖來解釋之。對核心而言,它所看到的核心虛擬位址空間的低2GB是不斷變化的,這是因為進程調度的緣故,只有在當前調度進程P執行時,虛擬位址X才對應著實體記憶體中同一個位置)。對於核心態驅動程式編寫人員而言,另一個他們感興趣的關於內容相關的細節是線程調度上下文(Thread scheduling context)。當一個線程等待時(譬如使用Win32函數WaitForSingleObject(…)等待一個未激發的對象),所等待的目標的相關資訊是儲存在該線程的調度上下文中的。如果等待不能得到滿足,則線程會被移出就緒隊列,當等待條件得到滿足之後再重新回到就緒隊列。上下文同樣會對控制代碼的使用產生影響。因為控制代碼是和某個具體的進程相關聯的,因此在一個進程的上下文中建立的控制代碼,不能在另一個進程上下文中使用。 幾種不同的上下文核心態的常式在下列三種上下文中的一種中執行:l          系統進程上下文l          某個具體的使用者線程(和進程)上下文l          任意使用者線程(和進程)上下文在執行過程中,所有核心態驅動程式的各部分都有可能在上述三種上下文中的任一種下執行。譬如,驅動程式的DriverEntry(…)函數總是運行在系統進程上下文中。系統進程上下文沒有與之相關聯的使用者線程上下文(也就沒有TEB),並且也就沒有任何使用者態進程被映射到核心的虛擬位址空間中低端的2GB(譯註:回憶一下,核心的虛擬位址空間也是從0-4GB的)。另一方面來說,DPC(比如用於ISR或計時器定時函數的驅動程式的DPC)運行在無關使用者線程上下文。這意味著在DPC的執行過程中,任何使用者線程都有可能是“當前”線程(譯註:正在執行的意思),也就是說任何使用者進程都有可能被映射到核心虛擬位址空間中低端的2GB。驅動程式分發常式執行時所處的上下文可能尤其令人著迷。在許多情況下,核心態驅動程式的分發常式執行在產生調用的使用者線程的上下文中。圖1解釋了為什麼會這樣。當一個使用者線程發出一個針對裝置的I/O函數調用時——例如調用了Win32函數ReadFile(…)——會導致一個系統服務要求。在Intel體繫結構處理器上,這樣的請求是通過軟體中斷來實現的。軟體中斷穿過中斷門,中斷門切換處理器的當前特權 1級CPL到核心模式,這會引發一個切換到核心棧的動作,然後調用系統服務派發器(System service dispatcher)。接著,系統服務派發器叫用作業系統提供的用於處理所請求的系統服務的函數。以ReadFile(…)為例,這個函數(譯註:指用於處理所請求的系統服務的函數)是I/O子系統的NtReadFile(…),NtReadFile(…)函數建立一個IRP,檢查ReadFile(…)請求中傳入的檔案控制代碼所引用的檔案對象在核心中和哪個驅動程式相關聯,接著調用該驅動程式處理“讀”的分發常式。所有這些都發生在PASSIVE_LEVEL插斷要求級。在上面介紹的整個處理過程中,並沒有發生對使用者請求進行調度或者排隊的動作。因此,使用者線程和進程的上下文不會發生任何改變。在本例中,驅動程式的分發常式執行在發出ReadFile(…)調用的使用者線程的上下文中。這表示當驅動程式的“讀”分發函數執行的時候,是使用者線程在執行核心態驅動的代碼。那麼,是不是驅動程式的分發常式總是執行在發出請求的使用者線程的上下文中呢?未必。4.0版的《核心模式驅動程式開發指南》的第16.4.1.1節告訴我們,“只有位於最高層的NT驅動程式,如檔案系統驅動程式,才可以肯定它們的分發常式是在這樣的使用者模式線程的上下文中被調用的。”但是嚴格說來這並不完全對(從我們的例子中可以看出這一點),所能肯定正確的一點是:FSD是在發出請求的使用者線程的上下文中被調用的。事實是,當使用者發出一個I/O請求後,若一個驅動程式立即被調用且它不把請求傳遞給其他驅動程式,那麼可以擔保該驅動程式是在發出請求的使用者線程的上下文中被調用的,這包括FSD。但是這個事實的另一層意思是,大部分由使用者編寫的標準核心態驅動程式會直接向使用者應用程式提供一些功能,比如處理控制裝置,這些驅動程式的分發函數會在發出請求的使用者線程的上下文中被調用。事實上,只有一種情況下驅動程式的分發常式不在產生調用的使用者線程上下文中被調用,那就是使用者的請求首先是被傳到較高層的驅動程式,如檔案系統驅動程式。如果較高層的驅動程式把請求發送到系統工作者線程(System worker thread),上下文會因此而改變。當IRP最終向下傳遞到較低層的驅動程式手中時,就無法保證較高層驅動程式在執行轉寄IRP的動作時所在的上下文是發出請求的使用者線程的上下文。較低層的驅動程式也因此將執行在任意線程上下文。較為通用的規則是,如果一個裝置直接被使用者訪問,中途不經過其他驅動程式的幹預,則該裝置的驅動程式的分發常式通常是運行在發出請求的使用者線程的上下文中。當這一切發生時,會產生一些相當有趣的結果,這允許我們作一些同樣有趣的事情。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.