1. 程式人生 > >第七章——Windows核心基礎-核心理論基礎(0環通訊,核心函式,驅動載入流程)

第七章——Windows核心基礎-核心理論基礎(0環通訊,核心函式,驅動載入流程)

windowsR3與R0通訊         當我們呼叫某個API的時候,這個API是被封裝在某個DLL庫中,而DLL庫中的函式則是在更底層的ntdll.dll檔案中,而相對應的則是呼叫ntdll中的Native API函式ntdll中的Native API函式是成對出現,分別以Nt和Zw開頭,在ntdll中他們的本質是一樣,只是名字不同。當API函式在ntdll中執行時,首先會檢查引數工作,接著呼叫一箇中斷們(int 2E或者sysenter指令)從R3層進入R0層。在核心中的ntoskrnl.exe中有個一SSDT,裡面存放了與ntdll中對應的SSDT系統服務處理函式,(Nt*)它們與ntdll.dll中的函式一一對應         Ps:在進行核心開發的時候,儘量使用Zw*系列的API,這樣可以減少額外的引數列表檢查,從而提高效率   驅動與應用層的互動         核心主要由各種驅動.sys檔案組成,這些驅動有的是系統自帶,有的是第三方提供,驅動載入完成後,會生成對應的裝置物件,並像三環提供一個可以開啟的符號連結,對應的符號連結名為"\??\C:\","\??\D:\" 等等。應用程式可以根據核心驅動的符號連結名呼叫CreateFile()函式開啟,在獲得一個控制代碼後,就可以將應用層程式和核心驅動進行通訊。雖然作業系統是由C語言完成的,但是在操作思想背後還是有C++面向物件的支援         核心驅動一旦執行了DriverEntry()入口函式,就可以接受三環的通訊請求,在核心驅動中專門有一組分發派遣函式用來分別響應應用層的請求(進城退出,讀取檔案,和MFS的訊息機制有點類似)         如果我們要響應一個API函式的呼叫,在核心層中會有一個分發派遣的函式來負責這個請求。當我們API呼叫後,傳遞給API的資料和命令就會被IRP傳遞給對應的驅動分發派遣函式執行,當驅動的分發派遣函式處理完這個IRP之後,驅動就可以結束或者允許這個IRP,當然如果複雜還可以呼叫給下一層驅動去處理    
核心函式         windows核心部分會用呼叫一些核心層的函式,這些函式都是以固定的字首開始,分別屬於核心中不同的管理模組,通過這些字首,我們就可以知道他的基本模組以及層次。
  • Ex:管理層 Executive
  • Ke:核心層 Kernel
  • HAL: 硬體抽象層
  • Ob:物件管理 Object
  • MM: 記憶體管理,Memory Manager
  • Ps: 程序管理 Process
  • Se: 安全管理,Security
  • Io: I/O管理
  • Fs:檔案系統,File System
  • Cc:檔案快取管理,Cc表示Cache
  • Rtl:執行時程式庫 Rtl是Runtime Library
  • Zw/Nt:對應SSDT中的服務函式
  • Ndis:Ndis網路框架中呼叫的函式
在呼叫核心函式的時候,需要注意他們的中斷請求級別(IRQL),也就是說在不同的情況下,我們會執行在不同的IRQL上,因此不同的IRQL會呼叫不同的IRQL級別函式,下面羅列幾種常見的級別:
  • PASSIVE_LEVEL: 這是IRQL的最低級別,沒有被遮蔽的中斷,所以說在這個級別上,執行緒執行使用者模式可以訪問分頁記憶體。執行緒執行在該中斷級別上,遇到中斷響應全部會做出響應,我們使用者模式的程式碼都是在這個上面執行
  • APC_LEVEL:這個級別只有APC級別的中斷被遮蔽,可以訪問分頁記憶體,當有APC發生時,將處理器提升到APC等級,就能遮蔽其他APC,為了與APC同步,驅動程式可以手動提升級別,分頁排程管理也就能執行在該級別上
  • DIRQL:Device IRQL:處於高層的驅動程式通常不會使用該IRQL級別,這個級別上所有的中斷都會遮蔽,所以通常用來判斷裝置的有限級
    核心驅動載入執行流程         核心驅動在磁碟上的sys檔案即為驅動程式,遵守PE檔案格式,才能被系統載入。這裡只討論編譯好的驅動在系統中是如何被載入並執行的:
  1. 建立一個服務(登錄檔)在登錄檔的Services鍵下建立一個與驅動名稱相關的服務鍵,即HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Servieces\Srvname。這個服務鍵規定了驅動的一些屬性,比如StartType中的0比1先啟動
  2. 物件管理器生成驅動物件,並傳遞給DriverEntry()。執行DriverEntry()函式,他是第一個執行的函式,類似於main()
  3. 建立控制裝置物件
  4. 建立控制裝置符號連結(三環)
  5. 如果是過濾驅動,則建立過濾裝置並繫結
  6. 註冊特定分發派遣函式
  7. 其他初始化操作,HOOK,過濾,回撥框架等