Windows Internals 學習筆記(一)

第一章 基礎概念

  • 進程、線程與作業
    • 三個概念中進程最大,進程由以下幾個部分構成:

      • 私有的虛擬內存空間。程序運行時pe文件會被按照一定規則加載到一個4G(x86)虛擬內存空間中,而當執行該程序時CPU會取出該虛擬內存中的一部分加載到實際的內存中。其他進程無法訪問(除非其有訪問權限或者本進程定義了一個共用的內存空間)
      • 可執行的程序,即加載到虛擬內存中的代碼與數據
      • 已打開的句柄列表,其中每個句柄指向一個可以訪問的系統資源(例如文件,通道等等),進程中所有線程均可訪問
      • 訪問令牌,標識了進程相關的用戶組,特權等等安全信息
      • 進程ID,進程獨一無二的標識符
      • 至少一個的線程,線程可以讀取同一個進程內其他線程的空間

      同樣進程也指向父進程或者創建該進程的進程(可以不存在或者關閉,不影響子進程)

    • 線程包括:

      • 一組保存的CPU寄存器的值
      • 兩個棧(一個用於內核模式,一個用於用戶模式)
      • 一個線程局部存儲區域TLS
      • 一個線程ID(唯一標識符)
      • 有時可以包括自身的安全環境

      寄存器,棧與私有內存被合稱爲線程的環境(CONTEXT)

    • 作業:Windows上提供的用於管理一組進程的概念。

  • 虛擬內存

    • Windows對每個進程都分配有1個獨立的虛擬內存空間,對於PE文件將按照一定的規則裝載到這個虛擬內存空間中,直到CPU執行時纔將其按照一定規則取出映射到內存之中。
    • 其中對於x86系統,每個進程的虛擬內存爲4G,其中默認2G屬於系統所有(0x80000000-0xFFFFFFFF),剩餘的是用戶代碼所能使用的空間。
  • 用戶模式與內核模式

    • 一般情況下在操作系統中用戶代碼只能運行在用戶模式中(ring3),而涉及到系統底層調用時我們需要ring0級別的訪問權限,則此時我們需要使用系統API,內核模式本質上是一種處理器執行模式,當執行到API的實現代碼時(例如user32.dll中的代碼),處理器切換到ring0的狀態(與線程切換沒有關係),執行完成後切換回ring3將控制轉交給用戶代碼。
    • 一般PE文件區塊屬性中(_IMAGE_SECTION_HEADER)包含有區塊是否可讀可寫可執行的屬性,對於用戶代碼來說起到了防止發生錯誤訪問的作用(例如棧不可寫DEP技術防止將shellcode或跳板部署在棧上),而一旦切換到了ring0,可以實現無視保護的任意地址讀寫。因此只提供給用戶一個API而禁止其進行直接的ring0操作(然而.sys的驅動是擁有ring0級別的權限,所以在x64之後驅動需要有安全機構認證的簽名才能進行安裝)
  • 對象與句柄

    • 內核對象指靜態定義的對象類型的單個運行實例,對象類型由系統定義的數據類型,在該數據類型實例上進行的操作的一組函數以及一組對象屬性構成,Windows中任何進程都是進程對象的實例,文件是文件對象的實例,等等。
    • 可以將其理解爲C++中的類,對象屬性爲類中的成員變量,對象方法爲成員函數,而句柄則可以理解爲一個指向對象的指針
    • 由於對象內部是不透明的(許多結構Windows沒有公開定義的文檔,相關資料都是大佬們研究出來的),類似於C++的private,我們只能使用成員函數來修改其中的成員變量
    • 並非所有數據結構都是對象,只有需要被共享,保護,命名等等的數據才放在對象中

第二章 系統架構

  • 操作系統模型與整體架構

    • 在大部分操作系統中,操作系統與用戶代碼都是隔離的,以防用戶代碼錯誤操作破壞操作系統。對於Windows系統,也體現了面向對象的思想,一般我們無法直接訪問某個結構的數據,而是通過接口(成員函數)來進行訪問/修改數據,以防破壞。然而需要注意,爲了可移植性,Windows大部分代碼都是用C而不是C++寫的,少量需要效率的交互使用匯編編寫,只是借用了面對對象的特性。
    • 操作系統的基本架構如下圖
      在這裏插入圖片描述
      其中,用戶模式進程有以下四種基本類型:
      • 固定的系統支持進程,例如登錄,進程與會話管理器,他們並非系統服務
      • 服務進程,例如TaskSchedule,Windows服務要求獨立用戶登錄進行。在我理解中,Windows爲一個多用戶操作系統,每個用戶都擁有自己的進程,登出更換賬號則將關閉進程,而這個Windows服務進程則不受用戶登錄登出影響
      • 用戶應用程序,即一般我們理解中的進程。對於16位進程只能在32位系統下運行,而64位程序在32位系統安裝組件的情況下同樣可以運行
      • 環境子系統服務器進程,實現操作系統環境的支持部分

    其中需要注意DLL,因爲我們一般調用DLL中的API,而這些API則將調用更多的API,實現了將一個已文檔化的API轉化爲若干未文檔化的原生系統調用(在我理解爲更加底層的API)。

    • Windows的內核組件包含:
      • Windows執行體,包含了基本的操作系統服務,例如內存管理,進程/線程管理,安全性,I/O,網絡,跨進程通信等等。
      • Windows內核,由一部分低層次的操作系統的功能組成,例如線程調度,中斷,異常分發以及多處理器同步等等。
      • 設備驅動程序,既包括硬件設備驅動程序,也包括文件、網絡等等非硬件驅動程序。
      • 硬件抽象層(HAL),將內核、設備驅動程序與Windows執行體其他部分,和與平臺相關的硬件差距隔離開。
      • 窗口與圖形系統,實現了圖形界面的功能。
        Windows的核心文件
文件名稱 組件
Ntoskrnl.exe 執行體與內核
Ntkrnlpa.exe(僅適用於32位) 執行體與內核,支持物理地址擴展,使得32位擴展到64GB內存,將內存標記爲不可執行
Hal.dll 硬件抽象層
Win32k.sys Windows子系統的內核模式部分
Ntdll.dll 內部支持函數,執行體函數後的系統服務分發存根(stub)
Kernel32.dll,Advapi32.dll,User32.dll,Gdi32.dll Windows的核心子系統dll
  • Windows子系統

    • Windows子系統中存放了基本的功能函數,其他子系統使用這些功能時調用Windows子系統完成
    • Windows子系統包括以下基本內容
      • 對於每個會話,環境子系統進程(Csrss.exe)一個實例加載三個DLL(Basesrv.dll、Winsrv.dll、Csrsrv.dll),其中包含以下支持:
        • 創建/刪除進程、線程
        • 對16位DOS虛擬機(VDM)的部分支持(僅32位Windows)
        • 部分API,例如GetTempFile、DefineDosService、ExitWindowsEx,以及部分自然語言函數支持
      • 內核模式設備驅動函數(Win32k.exe)
        • 窗口管理器,控制窗口顯示,屏幕輸出,採集外設輸入,負責將用戶消息傳遞給應用程序
        • 圖形設備接口(GDI),針對圖形輸出設備
        • DirectX的封裝函數(不包括支持)
      • 控制檯宿主進程(Conhost.exe),提供對CUI的支持
      • 子系統DLL(例如Kernel32.dll,Advapi.dll,User32.dll,Gdi32.dll),將已經文檔化的API轉換爲未文檔化的Ntoskrnl.exe與Win32k.sys中的底層API調用
      • 圖形設備驅動程序
  • Dtdll.dll

    • 系統服務分發存根(Stub),調用Windows執行體的系統服務,在用戶模式下程序可以通過這些接口函數調用Windows執行體的系統服務,例如NtCreateFile,NtSetEvent等等。在Ntdll的函數內部切換到內核模式,之後調用系統服務分發器(system service dispatcher),檢驗參數後調用真正的系統函數。
    • 內部支持函數,供子系統,子系統DLL及其他原生映像文件使用,例如映像加載器,堆管理器,Windows子系統進程通信函數。以及用戶態調試函數,Windows事件跟蹤,以及一個小型的C的庫
  • 執行體

    • Windows執行體爲Ntoskrnl.exe中的上層(內核爲下層),其中包含如下函數
      • 可在用戶模式下調用的導出函數,這些函數稱爲系統服務,通過Ntdll導出,其中絕大部分都可以通過系統API訪問
      • 通過DeviceIoControl來調用設備驅動函數,這個爲用戶模式到內核模式提供一個接口
      • 只能在內核模式下調用的導出函數(已經文檔化的部分)
      • 內核模式下調用但是未文檔化的函數
    • 執行體中包含以下主要組件
      • 配置管理器,負責實現管理系統的註冊表
      • 進程管理器,創建與終止進程與線程。針對進程線程的底層實現與支持是在Windows內核中實現的,而執行體在底層對象的基礎上添加了額外語義與功能。
      • 安全引用監視器,守護操作系統資源,實行運行時對對象的保護與審計
      • I/O管理器,負責將I/O請求分配到對應的設備驅動
      • 即插即用管理器,確定對於特定的設備需要哪些驅動,負責加載驅動,以及獲取運行時的資源需求並分配資源。
      • 電源管理器,負責協調電源事件,產生電源I/O通知發送給設備驅動程序
      • Windows驅動程序模型的WMI例程,允許設備驅動程序發佈有關性能與配置消息,接收來自用戶模式的WMI服務命令。
      • 緩存管理程序,將引用的磁盤數據存儲在主存,提高運行效率
      • 內存管理器,實現了虛擬內存
      • 邏輯預取器,加速系統與進程啓動
    • 執行體包括以下四類主要的支持函數:
      • 對象管理器,創建,管理與刪除Windows執行體對象與抽象數據類,它們代表着Windows的資源,例如進程,線程與各種同步對象
      • 高級LPC設施,爲同一臺機器上的客戶端進程與服務器進程傳遞消息
      • 公共庫運行函數,例如字符串處理,算數操作,數據類型轉換等等
      • 執行體支持例程,例如系統內存分配,互鎖內存訪問等等
  • 內核

    • 內核由Ntoskrnl.exe中的一組函數以及對硬件底層架構的支持(例如中斷與異常)構成的,Ntoskrnl.exe中的函數提供了一些最基本的機制,例如線程調度與同步,供執行體組件使用,而面對硬件底層部分則由硬件決定
  • 內核對象

    • 相對於執行體標記的對象(需要對象句柄,安全檢查,資源配置等等),內核對象更加簡單,不需要這些額外開銷。絕大多數執行體層對象都封裝了一個及以上的內核對象,併合並了內核屬性。
    • 其中執行體通過內核函數來創建管理內核對象,其中內核對象包括
      • 控制對象,包括控制各種操作系統功能的語義
      • 分發器對象,融合了同步能力,具有影響、改變線程調度能力,例如線程,互斥體,事件,定時器等等。
  • 內核處理器控制區與控制塊
    * 內和使用一個處理器控制區(KPCR)存放處理器相關數據。KPCR包含基本信息,例如處理器中斷分發表(IDT)、任務狀態段(TSS)、全局描述符表(GDT)
    * KPCR中包含了一個內核處理器控制塊(KPCRB),其中包含調度信息,處理器信息等等。

  • 硬件抽象層(HAL)

    • 爲了方便移植,Windows操作系統使用HAL來隱藏底部細節,並且提供對於硬件訪問的功能,對於不同的硬件平臺只需替換HAL即可
  • 設備驅動程序

    • 可加載的內核模式模塊(一般爲.sys),他們在I/O管理器與相應的硬件之間建立連接。設備驅動程序一般運行於內核模式下,三種環境中:
      • 在發起I/O功能的用戶線程環境中
      • 在內核模式系統線程的環境中
      • 作爲中斷的結果(此時不處於特定線程、進程環境中)
    • 設備驅動程序往往不直接用於維護硬件,而是調用HAL中的函數與硬件交互,一般而言驅動可以在Windows支持的CPU體系中以源碼移植,或同一體系中以二進制移植
    • 設備驅動程序包括:
      • 硬件設備驅動程序
      • 文件系統驅動程序
      • 文件系統過濾驅動程序
      • 網絡重定向器與服務器
      • 協議驅動程序
      • 內核流式過濾驅動程序
    • 某種角度而言驅動程序是用戶在系統添加自己代碼的方式
  • Windows驅動程序模型

    • 從WDM角度看存在三種驅動程序
      • 總線驅動程序
      • 功能驅動程序
      • 過濾驅動程序
  • Windows驅動程序基礎(WDF)

    • WDF簡化了驅動的開發,它提供兩個框架:內核模式驅動程序框架(KMDF)與用戶模式驅動程序框架(UMDF)
  • 系統進程

    • 基礎系統進程包括
      • Idle進程,用於佔用空閒CPU時間
      • system進程,所有系統子線程都是屬於system進程,只能在內核模式運行。
      • 會話管理器(Smss.exe),系統創建的第一個用戶模式進程
      • 本地會話管理器(Lsm.exe)
      • Windows子系統(Csrss.exe)
      • 會話0初始化(Wininit.exe)
      • 登錄進程(Winlogon.exe)
      • 服務控制管理器(Services.exe)以及其創建的子服務進程(例如通用服務宿主進程Svchost.exe)
      • 本地安全認證服務器(Lsass.exe)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章