首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

Windows NT/2000 核心程式設計:免驅動程式實現 Ring 0 程式碼執行技術解析

     編輯:關於C++

Windows NT/2000 採用嚴格的核心模式 (Ring 0) 與使用者模式 (Ring 3) 分離架構,確保系統穩定性。一般應用程式若需執行特權指令 (如 I/O 埠操作、控制暫存器存取),傳統做法必須編寫核心模式驅動程式。本文揭示一種不載入驅動程式、純使用者模式程式即可實現 Ring 0 程式碼執行的進階技術——透過修改全域描述符表 (GDT) 植入呼叫閘 (Call Gate) 達成權限提升。

核心原理:Call Gate 與 GDT 操作

  • Call Gate (呼叫閘):x86 架構提供的保護機制,允許低權限程式 (Ring 3) 透過閘描述符呼叫高權限程式碼 (Ring 0)。
  • GDT (Global Descriptor Table):系統全域描述符表,定義記憶體段與閘的屬性。其基址存放於 KPCR (Processor Control Region) 結構中,可透過 sgdt 指令 (非特權指令) 從 Ring 3 讀取。
  • 物理記憶體存取:GDT 位於核心虛擬位址空間 (通常 0x80000000~0xA0000000),Ring 3 無法直接寫入。Windows 提供 \Device\PhysicalMemory 區段物件,允許對實體記憶體讀寫。

關鍵實作步驟

1. 取得 \Device\PhysicalMemory 寫入權限

預設僅 SYSTEM 擁有讀寫權,Administrators 唯讀。需以 Administrator 權限執行,呼叫 GetSecurityInfo、SetEntriesInAcl、SetSecurityInfo 為目前使用者加入 SECTION_MAP_WRITE ACE。

2. 虛擬位址轉換實體位址 (針對 GDT 區域)

分析 nt!MmGetPhysicalAddress 反組譯碼發現:核心空間線性位址 (0x80000000~0xA0000000) 採簡單位移對應實體位址,無需走頁表。公式:Physical = (Virtual & 0x1FFFF000)。

3. 映射實體記憶體並修改 GDT

  1. ZwOpenSection 開啟 \Device\PhysicalMemory (若拒絕存取則先調整 DACL)。
  2. MapViewOfFile 將 GDT 實體頁面映射至使用者空間。
  3. 掃描 GDT 尋找空閒描述符 (Type=0),植入 Call Gate 描述符:
    Selector = 0x08 (核心代碼段), DPL = 3 (允許 Ring 3 呼叫), Type = 0xC (386 Call Gate), Offset 指向使用者定義的 Ring 0 程式碼入口點。

4. 執行 Ring 0 程式碼並清理

  • 使用 VirtualLock 鎖定使用者 Ring 0 程式碼頁面防止分頁。
  • 提升執行緒優先權至 THREAD_PRIORITY_TIME_CRITICAL 減少被切換機率。
  • 透過 call fword ptr [farcall] 遠端呼叫 Call Gate 進入 Ring 0。
  • 執行完畢降低優先權、解鎖記憶體、清除 GDT 中的 Call Gate、關閉 Section 控制代碼。

完整核心程式碼架構 (C/C++)

// Call Gate 描述符結構
typedef struct {
    unsigned short offset_0_15;
    unsigned short selector;
    unsigned char param_count : 4;
    unsigned char some_bits   : 4;
    unsigned char type        : 4;
    unsigned char app_system  : 1;
    unsigned char dpl         : 2;
    unsigned char present     : 1;
    unsigned short offset_16_31;
} CALLGATE_DESCRIPTOR;

// GDTR 結構 (sgdt 回傳)
typedef struct { short Limit; short BaseLow; short BaseHigh; } GDTR;

// 簡易虛轉實 (核心空間 0x80000000~0xA0000000)
ULONG MiniMmGetPhysicalAddress(ULONG va) {
    if (va < 0x80000000 || va >= 0xA0000000) return 0;
    return va & 0x1FFFF000;
}

BOOL ExecRing0Proc(ULONG EntryPoint, ULONG CodeSize) {
    GDTR gdt; __asm sgdt gdt;
    ULONG gdtBase = (gdt.BaseHigh << 16) | gdt.BaseLow;
    ULONG physAddr = MiniMmGetPhysicalAddress(gdtBase);
    if (!physAddr) return FALSE;

    // 開啟 PhysicalMemory Section (含 DACL 調整邏輯)
    HANDLE hSection = OpenPhysicalMemorySection();
    if (!hSection) return FALSE;

    // 映射 GDT 所在實體頁
    PVOID pGdt = MapViewOfFile(hSection, FILE_MAP_READ|FILE_MAP_WRITE, 0, physAddr, gdt.Limit+1);
    if (!pGdt) { CloseHandle(hSection); return FALSE; }

    // 尋找空閒描述符並植入 Call Gate
    CALLGATE_DESCRIPTOR *cg = FindAndSetupCallGate(pGdt, gdt.Limit, EntryPoint);
    if (!cg) { UnmapViewOfFile(pGdt); CloseHandle(hSection); return FALSE; }

    // 準備遠端呼叫指標 (Selector | 3 表示 Ring 3 呼叫)
    WORD farCall[3]; farCall[2] = ((ULONG)cg - (ULONG)pGdt) | 3;

    // 鎖定程式碼、執行、清理
    VirtualLock((PVOID)EntryPoint, CodeSize);
    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
    _asm call fword ptr [farCall];
    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
    VirtualUnlock((PVOID)EntryPoint, CodeSize);

    // 清除 Call Gate
    *(ULONG*)cg = 0; *((ULONG*)cg+1) = 0;
    UnmapViewOfFile(pGdt); CloseHandle(hSection);
    return TRUE;
}

安全性警示與限制

  1. 極高風險:Ring 0 程式碼錯誤直接導致系統藍畫面 (BSOD) 或資料損毀。嚴禁用於生產環境或惡意用途。
  2. 需 Administrator 權限:修改 PhysicalMemory DACL 必須具備管理員權限。
  3. 相容性限制:依賴 GDT 位於 0x80000000~0xA0000000 且採線性映射實體位址的假設。/3GB 啟動選項、PAE、x64 版本、後續 Windows 版本 (XP SP2+, Vista, 7, 10, 11) 均已阻擋或變更此機制 (如移除 \Device\PhysicalMemory、強制驅動程式簽章、PatchGuard 核心修補防護)。
  4. 僅供學術研究:展示 x86 保護模式機制、Windows 記憶體管理與安全架構演進歷史。

現代替代方案

現代 Windows 開發需求 (硬體存取、高效能、系統監控) 應採用正規管道:

  • KMDF/UMDF 驅動程式:標準、簽章、穩定的核心模式開發框架。
  • WinRing0 / InpOut32 等開源庫:封裝已簽章驅動提供 Ring 0 I/O 存取 (需測試模式或簽章)。
  • ETW (Event Tracing for Windows)、WMI、Performance Counters:系統監控與效能分析標準 API。
  • Virtualization-Based Security (VBS) / Hyper-V API:硬體虛擬化輔助的隔離執行環境。

本文技術屬於「考古級」核心程式設計知識,理解其原理有助於深入掌握作業系統保護機制與安全防禦演進,但實務開發必須遵循現代安全開發規範。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved