第三章 編寫內(nèi)核模式驅(qū)動(dòng)程序
翻譯: Kendiv
更新: Thursday, February 10, 2005
設(shè)備 I/O 控制
就像在本章開頭的簡介中提到的,在本書中,我們不會(huì)構(gòu)建某一具體硬件的驅(qū)動(dòng)程序 。替代的是,我們將利用功能強(qiáng)大的內(nèi)核驅(qū)動(dòng)程序來研究 Windows 2000 的秘密 。從實(shí)際結(jié)果來看,驅(qū)動(dòng)程序的強(qiáng)大之處在于它們能在 CPU 的最高特權(quán)級別上運(yùn)行 。這意味著內(nèi)核驅(qū)動(dòng)可以訪問所有的系統(tǒng)資源,可以讀取所有的內(nèi)存空間,而且也被允許執(zhí)行 CPU 的特權(quán)指令,如,讀取 CPU 控制寄存器的當(dāng)前值等 。而處于用戶模式下的程序如果試圖從內(nèi)核空間中讀取一個(gè)字節(jié)或者試圖執(zhí)行像 MOV EAX,CR3 這樣的匯編指令都會(huì)被立即終止掉 。不過,這種強(qiáng)大的底線是驅(qū)動(dòng)程序的一個(gè)很小的錯(cuò)誤就會(huì)讓整個(gè)系統(tǒng)崩潰 。即使是非常小的錯(cuò)誤發(fā)生,也會(huì)讓系統(tǒng)藍(lán)屏,因此開發(fā)內(nèi)核程序的人員必須比 Win32 應(yīng)用程序或 DLL 的開發(fā)人員更加仔細(xì)的處理錯(cuò)誤 。還記得我們在第一章里使用的導(dǎo)致系統(tǒng)藍(lán)屏的 Windows 2000 Killer device driver 嗎?它所作的一切只是觸及了虛擬內(nèi)存地址 0x00000000 ,然后就 ---Boom ?。?!你應(yīng)該意識到在開發(fā)內(nèi)核驅(qū)動(dòng)時(shí),你會(huì)比以往更頻繁的重啟你的機(jī)器 。
在隨后章節(jié)中,我給出的驅(qū)動(dòng)程序代碼將采用稱為設(shè)備 I/O 控制( IOCTL )的技術(shù),以允許用戶模式下的代碼實(shí)現(xiàn)一定程序的“遠(yuǎn)程控制” 。如果應(yīng)用程序需要訪問在用戶模式下無法觸及的系統(tǒng)資源,那內(nèi)核驅(qū)動(dòng)程序?qū)⒖珊芎玫耐瓿纱隧?xiàng)工作,而 IOCTL 則是聯(lián)系二者的橋梁 。事實(shí)上, IOCTL 并不是 Windows 2000 采用的新技術(shù) 。即使舊的操作系統(tǒng) ---Dos 2.11 也具有這種能力, 0x44 函數(shù)及其子函數(shù)構(gòu)成了 DOS 的 IOCTL?;旧希?IOCTL 是通過控制通路和設(shè)備通訊的一中手段,控制通路在邏輯上獨(dú)立于數(shù)據(jù)通路 。想象一個(gè)硬盤設(shè)備通過其主數(shù)據(jù)通路傳遞磁盤扇區(qū)中的內(nèi)容 。如果客戶想獲取當(dāng)前設(shè)備使用的媒體信息,它就必須使用另一個(gè)不同的通路 。例如, DOS 函數(shù) 0x44 ,其子函數(shù) 0x0d 、 0x66 構(gòu)成了 DOS 的 IOCTL ,調(diào)用這些函數(shù)就可讀取磁盤的 32 位連續(xù)數(shù)據(jù)(參考 Brown and Kyle 1991 , 1993 ) 。
設(shè)備 I/O 控制根據(jù)要控制的設(shè)備,可以有多種實(shí)現(xiàn)方式 。就其一般形式來說, IOCTL 有如下幾類:
l 客戶端通過一個(gè)特殊的進(jìn)入點(diǎn)來控制設(shè)備 。在 DOS 中,這個(gè)進(jìn)入點(diǎn)為 INT 21h 、函數(shù)號 0x44。在 Windows 2000 中,則通過 Kernel32.dll 導(dǎo)出的 Win32 函數(shù) DeviceIoControl()。
l 客戶端通過提供設(shè)備的唯一標(biāo)識符、控制代碼以及一個(gè)存放輸入數(shù)據(jù)的緩沖區(qū)、一個(gè)存放輸出數(shù)據(jù)的緩沖區(qū)來調(diào)用 IOCTL 的進(jìn)入點(diǎn) 。對于 Windows 2000 ,設(shè)備標(biāo)識符是成功打開的設(shè)備的句柄( HANDLE ) 。
l 控制代碼用于告訴目標(biāo)設(shè)備的 IOCTL 分派器( dispatcher ),客戶端請求的是哪一個(gè)控制函數(shù) 。
l 輸入緩沖區(qū)中可包含任意地附加數(shù)據(jù),設(shè)備可能需要這些數(shù)據(jù)來完成客戶所請求的操作 。
l 客戶所請求的操作產(chǎn)生的任何數(shù)據(jù),都會(huì)保存在客戶端提供的輸出緩沖區(qū)中 。
l IOCTL 操作的整體結(jié)果通過返回給客戶端的狀態(tài)代碼來表示
很 顯然這是一種強(qiáng)大的通用機(jī)制,這種機(jī)制可以適用于很大范圍的控制請求 。例如,應(yīng)用程序在訪問系統(tǒng)內(nèi)核所占用的內(nèi)存空間時(shí)會(huì)被禁止,這是因?yàn)楫?dāng)程序觸及該內(nèi) 存空間時(shí)會(huì)立即拋出一個(gè)異常,不過程序可以通過加載一個(gè)內(nèi)核驅(qū)動(dòng)程序來完成此項(xiàng)工作,這樣就可避免出現(xiàn)異常 。交互的兩個(gè)模塊都需遵循 IOCTL 協(xié)議來管理數(shù)據(jù)的傳輸 。例如,程序可能通過給驅(qū)動(dòng)程序發(fā)送控制代碼 0x80002000 來讀取內(nèi)存或發(fā)送 0x80002001 來向內(nèi)存中寫入數(shù)據(jù) 。對于讀取請求, IOCTL 輸 入緩沖區(qū)或許要提供基地址和要讀取的字節(jié)數(shù) 。內(nèi)核驅(qū)動(dòng)程序能獲取這些請求并通過控制代碼來判斷是讀取操作還是寫入操作 。對于讀取請求,內(nèi)核驅(qū)動(dòng)程序會(huì)將請 求的內(nèi)存范圍內(nèi)的數(shù)據(jù)復(fù)制到調(diào)用者提供的輸出緩沖區(qū)中,如果輸出緩沖區(qū)足夠容納這些數(shù)據(jù),則返回成功代碼 。對于寫入請求,驅(qū)動(dòng)程序會(huì)將輸入緩沖區(qū)中的數(shù)據(jù) 復(fù)制到指定的內(nèi)存中(該內(nèi)存的起始位置也由輸入緩沖區(qū)指定) 。在第四章,我將提供一個(gè) Memory Spy 的示列代碼 。
推薦閱讀
- 暗戀橘生淮南是在哪拍的
- 9 《Undocumented Windows 2000 Secrets》翻譯 --- 第四章
- 奶酪陷阱大結(jié)局是什么
- 葉瀾依結(jié)局
- 安裝Microsoft Windows 2000 恢復(fù)控制臺
- 4 《Undocumented Windows 2000 Secrets》翻譯 --- 第三章
- 1 《Undocumented Windows 2000 Secrets》翻譯 --- 第二章
- 淺談非系統(tǒng)管理員用戶本地登錄Windows 2000 server
- 同床異夢秋瓷炫多少期
- Windows 2000進(jìn)程細(xì)述
