windows系統中核心態R0和用戶態R3之間的通信

權限級別

系統核心態指的是R0,用戶態指的是R3,系統代碼在覈心態下運行,用戶代碼在用戶態下運行。系統中一共有四個權限級別,R1和R2運行設備驅動,R0到R3權限依次降低,R0和R3的權限分別爲最高和最低。從windows體系結構圖可以看出在用戶態可以調用的函數接口都在ntdll.dll中,在用戶態運行的系統要控制系統時,或者要運行系統代碼就必須取得R0權限。特級環圖和windows 體系結構圖如下所示:
特級環圖
windows 體系結構圖

進程內存

每一進程在運行前,系統都會爲它分配4GB的私有內存,其中2G爲內核內存,2G爲用戶內存。windows內存的邏輯地址分爲兩種:一種是段選擇寄存器,另一種是偏移地址。進程在運行時就必然要涉及虛擬地址到物理地址的翻譯,CPU在進行地址翻譯時,先通過分段機制計算出一個虛擬地址,再通過頁表機制將虛擬地址映射到物理地址,從而存取物理內存中的數據和指令。進程內存佈局如下所示:
進程內存佈局

R3和R0通信

windows分爲應用層和內核層,當應用進程調用一個I/O的API時,那麼這個api一定封裝在某個dll庫中,
但不管這個dll是什麼,到最後都會調用ntdll中的native api函數。native api函數是成對出現的,分別以Nt和Zw開頭。

當kernel.dll中的api調用ntdll.dll執行時,會完成參數的檢查工作,再調用一箇中斷進入到內核態,在內核態中有一個SSDT(系統服務描述符表),它相當於一個數組,裏面存放的是與ntdll.dll對應的SSDT系統服務處理函數,這些函數都是內核態下的函數,執行這些函數也意味着執行內核代碼。

Nt*系列的api會直接調用對應的函數代碼。而以ZW開頭的API則通過KiSystemService跳轉到對應的函數代碼,這兩種調用都會對內核中的previousMode產生改變,在用戶模式下調用Native api,則還是用戶模式,如果在內核模式下調用Native api,則爲內核態。當previous爲用戶態時,將會對用戶態傳遞過來的參數進行檢查,而內核態不會。應用程序調用內核API的過程圖如下所示:

應用程序調用內核API的過程

內核主要由各種驅動文件(*.sys)組成,這些驅動有的是系統自帶的,有的是軟件產商提供的,驅動加載之後,會生成對應的設備對象並可以向R3提供一個可供訪問的和打開的符號鏈接,例如:“??\C:\”等。內核驅動執行了DriverEntry函數時,內核就可以接受R3發送過來的信息了。在內核驅動中有許多分發派遣函數來響應和應用層的的調用請求,每一個應用層負責I/O的API都對應一個內核中的分發派遣函數。驅動文件圖和windows驅動框架模型如下所示:
驅動文件驅動文件
windows驅動框架模型

發佈了25 篇原創文章 · 獲贊 44 · 訪問量 699
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章