欢迎光临
我们一直在努力

01-03 Windows软件体系 - 用户态与内核态分界线与Ring特权级机制(上)

01-03 Windows软件体系 – 用户态与内核态分界线与Ring特权级机制

Windows软件体系 · 第01-03篇

本篇深入剖析x86/x64架构的CPU特权级模型(Ring 0-3)、Windows用户态与内核态的地址空间分界、系统调用切换的硬件级执行流程(syscall/sysret)、内核栈管理、SSDT系统服务分发表、参数安全验证、中断与异常分发、内核保护机制(PatchGuard/SMEP/SMAP)、切换性能开销,以及硬件虚拟化扩展(VT-x/AMD-V、Ring -1)。


目录

  • 1. CPU特权级体系基础
  • 2. 用户态与内核态的分界
  • 3. Ring3到Ring0的切换机制
  • 4. 内核栈与用户栈的切换
  • 5. 系统服务分发表(SSDT)
  • 6. 参数探测与安全验证
  • 7. 中断与异常处理
  • 8. 内核态的保护机制
  • 9. 用户态/内核态切换的性能分析
  • 10. 虚拟化扩展
  • 11. 总结

1. CPU特权级体系基础

1.1 特权级模型概述

x86架构自80286引入保护模式以来,便确立了基于环(Ring)的特权级模型。该模型定义了4个特权级别,编号从0到3,数字越小特权越高。这一设计是现代操作系统实现用户态/内核态隔离的硬件基石。

#mermaid-svg-QxhQFKjxuXxOBneZ{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-QxhQFKjxuXxOBneZ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-QxhQFKjxuXxOBneZ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-QxhQFKjxuXxOBneZ .error-icon{fill:#552222;}#mermaid-svg-QxhQFKjxuXxOBneZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-QxhQFKjxuXxOBneZ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-QxhQFKjxuXxOBneZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-QxhQFKjxuXxOBneZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-QxhQFKjxuXxOBneZ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-QxhQFKjxuXxOBneZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-QxhQFKjxuXxOBneZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-QxhQFKjxuXxOBneZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-QxhQFKjxuXxOBneZ .marker.cross{stroke:#333333;}#mermaid-svg-QxhQFKjxuXxOBneZ svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-QxhQFKjxuXxOBneZ p{margin:0;}#mermaid-svg-QxhQFKjxuXxOBneZ .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-QxhQFKjxuXxOBneZ .cluster-label text{fill:#333;}#mermaid-svg-QxhQFKjxuXxOBneZ .cluster-label span{color:#333;}#mermaid-svg-QxhQFKjxuXxOBneZ .cluster-label span p{background-color:transparent;}#mermaid-svg-QxhQFKjxuXxOBneZ .label text,#mermaid-svg-QxhQFKjxuXxOBneZ span{fill:#333;color:#333;}#mermaid-svg-QxhQFKjxuXxOBneZ .node rect,#mermaid-svg-QxhQFKjxuXxOBneZ .node circle,#mermaid-svg-QxhQFKjxuXxOBneZ .node ellipse,#mermaid-svg-QxhQFKjxuXxOBneZ .node polygon,#mermaid-svg-QxhQFKjxuXxOBneZ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-QxhQFKjxuXxOBneZ .rough-node .label text,#mermaid-svg-QxhQFKjxuXxOBneZ .node .label text,#mermaid-svg-QxhQFKjxuXxOBneZ .image-shape .label,#mermaid-svg-QxhQFKjxuXxOBneZ .icon-shape .label{text-anchor:middle;}#mermaid-svg-QxhQFKjxuXxOBneZ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-QxhQFKjxuXxOBneZ .rough-node .label,#mermaid-svg-QxhQFKjxuXxOBneZ .node .label,#mermaid-svg-QxhQFKjxuXxOBneZ .image-shape .label,#mermaid-svg-QxhQFKjxuXxOBneZ .icon-shape .label{text-align:center;}#mermaid-svg-QxhQFKjxuXxOBneZ .node.clickable{cursor:pointer;}#mermaid-svg-QxhQFKjxuXxOBneZ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-QxhQFKjxuXxOBneZ .arrowheadPath{fill:#333333;}#mermaid-svg-QxhQFKjxuXxOBneZ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-QxhQFKjxuXxOBneZ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-QxhQFKjxuXxOBneZ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QxhQFKjxuXxOBneZ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-QxhQFKjxuXxOBneZ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QxhQFKjxuXxOBneZ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-QxhQFKjxuXxOBneZ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-QxhQFKjxuXxOBneZ .cluster text{fill:#333;}#mermaid-svg-QxhQFKjxuXxOBneZ .cluster span{color:#333;}#mermaid-svg-QxhQFKjxuXxOBneZ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-QxhQFKjxuXxOBneZ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-QxhQFKjxuXxOBneZ rect.text{fill:none;stroke-width:0;}#mermaid-svg-QxhQFKjxuXxOBneZ .icon-shape,#mermaid-svg-QxhQFKjxuXxOBneZ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QxhQFKjxuXxOBneZ .icon-shape p,#mermaid-svg-QxhQFKjxuXxOBneZ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-QxhQFKjxuXxOBneZ .icon-shape .label rect,#mermaid-svg-QxhQFKjxuXxOBneZ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QxhQFKjxuXxOBneZ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-QxhQFKjxuXxOBneZ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-QxhQFKjxuXxOBneZ :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

x86/x64 Ring特权级模型

Ring 0 (内核态)最高特权可执行所有指令可直接访问硬件Windows: 内核 + 驱动

Ring 1次高特权Windows: 未使用设计用于设备驱动

Ring 2中等特权Windows: 未使用设计用于系统服务

Ring 3 (用户态)最低特权受限指令集不能直接访问硬件Windows: 应用程序

四个特权级的设计初衷是:

Ring设计用途实际使用情况
Ring 0 操作系统内核 Windows/Linux/macOS均使用
Ring 1 设备驱动 OS/2曾使用,现代OS均未使用
Ring 2 系统服务 OS/2曾使用,现代OS均未使用
Ring 3 应用程序 Windows/Linux/macOS均使用

1.2 Ring 0(内核态)详解

Ring 0是CPU的最高特权级别。在此级别下,处理器可以执行指令集中的所有指令,包括特权指令(Privileged Instructions):

特权指令清单(x86/x64):

; I/O端口访问
IN AL, DX ; 从I/O端口读取
OUT DX, AL ; 向I/O端口写入
INSB/INSW/INSD ; I/O端口串读
OUTSB/OUTSW/OUTSD ; I/O端口串写

; 控制寄存器操作
MOV CR0, EAX ; 读写CR0(控制寄存器)
MOV CR2, EAX ; 读写CR2(页故障地址)
MOV CR3, EAX ; 读写CR3(页目录基址)
MOV CR4, EAX ; 读写CR4(扩展控制)
MOV CR8, RAX ; 读写CR8(x64中断优先级)

; GDT/IDT/LDT操作
LGDT [mem] ; 加载GDT寄存器
LIDT [mem] ; 加载IDT寄存器
LLDT [mem] ; 加载LDT寄存器
SGDT [mem] ; 存储GDT寄存器
SIDT [mem] ; 存储IDT寄存器

; 段选择子操作
LMSW [mem] ; 加载机器状态字
SMSW [mem] ; 存储机器状态字

; TLB操作
INVLPG [mem] ; 无效化单个TLB项
WBINVD ; 回写并无效化整个缓存
INVD ; 无效化整个缓存(不回写)

; 中断控制
CLI ; 清除中断标志(关中断)
STI ; 设置中断标志(开中断)
LIDT [mem] ; 加载IDT

; 调试寄存器
MOV DR0, EAX ; 读写调试寄存器
MOV DR7, EAX

; MSR操作(Model-Specific Registers)
RDMSR ; 读取MSR
WRMSR ; 写入MSR

; TLB与缓存
INVLPG [mem] ; 无效化TLB条目

; TSS操作
LTR [mem] ; 加载任务寄存器
STR [mem] ; 存储任务寄存器

; 系统调用(快速)
SYSCALL ; 快速系统调用
SYSRET ; 快速系统返回
SYSENTER ; 快速系统调用(旧)
SYSEXIT ; 快速系统返回(旧)

; 其他
HLT ; 暂停处理器
RDTSC ; 读取时间戳计数器
WRMSR ; 写入MSR

在Ring 0中,处理器还可以:

  • 访问全部物理内存空间(通过页表映射)
  • 直接操作硬件设备(通过I/O端口和MMIO)
  • 修改全局描述符表(GDT)和中断描述符表(IDT)
  • 控制中断的使能与屏蔽
  • 管理页表和内存映射
  • 执行HALT指令暂停CPU

1.3 Ring 3(用户态)详解

Ring 3是CPU的最低特权级别。应用程序在此级别运行,受到以下限制:

Ring 3禁止的操作:

  • 不能执行上述所有特权指令
  • 不能直接访问物理内存(只能通过虚拟地址)
  • 不能直接操作I/O端口(除非I/O Permission Bitmap允许)
  • 不能修改GDT/IDT/页表
  • 不能禁用中断(CLI)
  • 不能使用HALT指令暂停CPU
  • 不能直接与硬件设备通信

如果Ring 3代码尝试执行特权指令,CPU会触发通用保护异常(General Protection Fault, #GP, 中断号0x0D),操作系统通常会终止该进程。

I/O Permission Bitmap(IOPM)的例外:

x86允许通过TSS中的I/O Permission Bitmap为Ring 3代码开放特定I/O端口的访问权限。Windows在某些场景下会利用此机制(如直接I/O的驱动通信),但默认情况下所有I/O端口对Ring 3都是禁止的。

#mermaid-svg-A7Gul51TBm9vRlnA{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-A7Gul51TBm9vRlnA .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-A7Gul51TBm9vRlnA .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-A7Gul51TBm9vRlnA .error-icon{fill:#552222;}#mermaid-svg-A7Gul51TBm9vRlnA .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-A7Gul51TBm9vRlnA .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-A7Gul51TBm9vRlnA .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-A7Gul51TBm9vRlnA .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-A7Gul51TBm9vRlnA .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-A7Gul51TBm9vRlnA .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-A7Gul51TBm9vRlnA .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-A7Gul51TBm9vRlnA .marker{fill:#333333;stroke:#333333;}#mermaid-svg-A7Gul51TBm9vRlnA .marker.cross{stroke:#333333;}#mermaid-svg-A7Gul51TBm9vRlnA svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-A7Gul51TBm9vRlnA p{margin:0;}#mermaid-svg-A7Gul51TBm9vRlnA .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-A7Gul51TBm9vRlnA .cluster-label text{fill:#333;}#mermaid-svg-A7Gul51TBm9vRlnA .cluster-label span{color:#333;}#mermaid-svg-A7Gul51TBm9vRlnA .cluster-label span p{background-color:transparent;}#mermaid-svg-A7Gul51TBm9vRlnA .label text,#mermaid-svg-A7Gul51TBm9vRlnA span{fill:#333;color:#333;}#mermaid-svg-A7Gul51TBm9vRlnA .node rect,#mermaid-svg-A7Gul51TBm9vRlnA .node circle,#mermaid-svg-A7Gul51TBm9vRlnA .node ellipse,#mermaid-svg-A7Gul51TBm9vRlnA .node polygon,#mermaid-svg-A7Gul51TBm9vRlnA .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-A7Gul51TBm9vRlnA .rough-node .label text,#mermaid-svg-A7Gul51TBm9vRlnA .node .label text,#mermaid-svg-A7Gul51TBm9vRlnA .image-shape .label,#mermaid-svg-A7Gul51TBm9vRlnA .icon-shape .label{text-anchor:middle;}#mermaid-svg-A7Gul51TBm9vRlnA .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-A7Gul51TBm9vRlnA .rough-node .label,#mermaid-svg-A7Gul51TBm9vRlnA .node .label,#mermaid-svg-A7Gul51TBm9vRlnA .image-shape .label,#mermaid-svg-A7Gul51TBm9vRlnA .icon-shape .label{text-align:center;}#mermaid-svg-A7Gul51TBm9vRlnA .node.clickable{cursor:pointer;}#mermaid-svg-A7Gul51TBm9vRlnA .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-A7Gul51TBm9vRlnA .arrowheadPath{fill:#333333;}#mermaid-svg-A7Gul51TBm9vRlnA .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-A7Gul51TBm9vRlnA .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-A7Gul51TBm9vRlnA .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-A7Gul51TBm9vRlnA .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-A7Gul51TBm9vRlnA .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-A7Gul51TBm9vRlnA .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-A7Gul51TBm9vRlnA .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-A7Gul51TBm9vRlnA .cluster text{fill:#333;}#mermaid-svg-A7Gul51TBm9vRlnA .cluster span{color:#333;}#mermaid-svg-A7Gul51TBm9vRlnA div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-A7Gul51TBm9vRlnA .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-A7Gul51TBm9vRlnA rect.text{fill:none;stroke-width:0;}#mermaid-svg-A7Gul51TBm9vRlnA .icon-shape,#mermaid-svg-A7Gul51TBm9vRlnA .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-A7Gul51TBm9vRlnA .icon-shape p,#mermaid-svg-A7Gul51TBm9vRlnA .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-A7Gul51TBm9vRlnA .icon-shape .label rect,#mermaid-svg-A7Gul51TBm9vRlnA .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-A7Gul51TBm9vRlnA .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-A7Gul51TBm9vRlnA .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-A7Gul51TBm9vRlnA :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

特权指令检查流程

Ring 3 应用程序

是

否

是

否

应用程序代码

执行指令

是否特权指令?

CPL <= DPL?

正常执行

允许执行

触发 #GP 异常(中断号 0x0D)

进程终止(Windows: 0xC0000005)

1.4 Ring 1/Ring 2在Windows中未使用的原因

尽管x86架构提供了4个特权级,但Windows(以及Linux)只使用了Ring 0和Ring 3两个级别。这一决策有多方面的原因:

1. 简化设计

使用两个特权级别大幅简化了操作系统的设计。如果使用Ring 1或Ring 2来运行驱动程序,则需要:

  • 在Ring 0与Ring 1之间增加额外的权限检查
  • 处理Ring 1代码访问内核数据时的保护
  • 管理三个特权级别之间的栈切换
  • 处理跨特权级的调用门(Call Gate)权限验证

2. 性能考量

每次特权级切换都涉及栈切换、寄存器保存/恢复、TLB可能刷新等操作。引入更多特权级别会增加切换频率和开销。

3. 历史原因

Intel设计Ring 0-3时,期望操作系统使用分层架构:

  • Ring 0:微内核
  • Ring 1:设备驱动
  • Ring 2:系统服务(如文件系统)
  • Ring 3:应用程序

但实际发展中,Windows NT和Linux都选择了宏内核架构,将内核和驱动都放在Ring 0,应用程序放在Ring 3。这种"两环"模型被证明是简单且高效的。

4. 兼容性

许多CPU架构(如ARM)只提供两个特权级别。将操作系统设计为仅依赖两个级别,有利于跨架构移植。Windows NT最初就设计为可移植的,支持x86、MIPS、Alpha、PowerPC等多种架构。

5. 安全性收益有限

Ring 1/Ring 2的特权介于内核和用户态之间,理论上可以限制恶意驱动的危害范围。但实际上:

  • 驱动需要直接操作硬件,通常需要Ring 0权限
  • 驱动间隔离可以通过其他方式实现(如用户态驱动框架UMDF)
  • Ring 1/Ring 2的隔离强度不足以抵御内核级攻击

#mermaid-svg-l2PabHz5JtzuHc7y{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-l2PabHz5JtzuHc7y .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-l2PabHz5JtzuHc7y .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-l2PabHz5JtzuHc7y .error-icon{fill:#552222;}#mermaid-svg-l2PabHz5JtzuHc7y .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-l2PabHz5JtzuHc7y .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-l2PabHz5JtzuHc7y .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-l2PabHz5JtzuHc7y .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-l2PabHz5JtzuHc7y .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-l2PabHz5JtzuHc7y .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-l2PabHz5JtzuHc7y .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-l2PabHz5JtzuHc7y .marker{fill:#333333;stroke:#333333;}#mermaid-svg-l2PabHz5JtzuHc7y .marker.cross{stroke:#333333;}#mermaid-svg-l2PabHz5JtzuHc7y svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-l2PabHz5JtzuHc7y p{margin:0;}#mermaid-svg-l2PabHz5JtzuHc7y .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-l2PabHz5JtzuHc7y .cluster-label text{fill:#333;}#mermaid-svg-l2PabHz5JtzuHc7y .cluster-label span{color:#333;}#mermaid-svg-l2PabHz5JtzuHc7y .cluster-label span p{background-color:transparent;}#mermaid-svg-l2PabHz5JtzuHc7y .label text,#mermaid-svg-l2PabHz5JtzuHc7y span{fill:#333;color:#333;}#mermaid-svg-l2PabHz5JtzuHc7y .node rect,#mermaid-svg-l2PabHz5JtzuHc7y .node circle,#mermaid-svg-l2PabHz5JtzuHc7y .node ellipse,#mermaid-svg-l2PabHz5JtzuHc7y .node polygon,#mermaid-svg-l2PabHz5JtzuHc7y .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-l2PabHz5JtzuHc7y .rough-node .label text,#mermaid-svg-l2PabHz5JtzuHc7y .node .label text,#mermaid-svg-l2PabHz5JtzuHc7y .image-shape .label,#mermaid-svg-l2PabHz5JtzuHc7y .icon-shape .label{text-anchor:middle;}#mermaid-svg-l2PabHz5JtzuHc7y .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-l2PabHz5JtzuHc7y .rough-node .label,#mermaid-svg-l2PabHz5JtzuHc7y .node .label,#mermaid-svg-l2PabHz5JtzuHc7y .image-shape .label,#mermaid-svg-l2PabHz5JtzuHc7y .icon-shape .label{text-align:center;}#mermaid-svg-l2PabHz5JtzuHc7y .node.clickable{cursor:pointer;}#mermaid-svg-l2PabHz5JtzuHc7y .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-l2PabHz5JtzuHc7y .arrowheadPath{fill:#333333;}#mermaid-svg-l2PabHz5JtzuHc7y .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-l2PabHz5JtzuHc7y .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-l2PabHz5JtzuHc7y .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-l2PabHz5JtzuHc7y .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-l2PabHz5JtzuHc7y .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-l2PabHz5JtzuHc7y .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-l2PabHz5JtzuHc7y .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-l2PabHz5JtzuHc7y .cluster text{fill:#333;}#mermaid-svg-l2PabHz5JtzuHc7y .cluster span{color:#333;}#mermaid-svg-l2PabHz5JtzuHc7y div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-l2PabHz5JtzuHc7y .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-l2PabHz5JtzuHc7y rect.text{fill:none;stroke-width:0;}#mermaid-svg-l2PabHz5JtzuHc7y .icon-shape,#mermaid-svg-l2PabHz5JtzuHc7y .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-l2PabHz5JtzuHc7y .icon-shape p,#mermaid-svg-l2PabHz5JtzuHc7y .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-l2PabHz5JtzuHc7y .icon-shape .label rect,#mermaid-svg-l2PabHz5JtzuHc7y .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-l2PabHz5JtzuHc7y .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-l2PabHz5JtzuHc7y .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-l2PabHz5JtzuHc7y :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

实际放弃

未使用Ring 1/2的原因

简化设计

性能考量

历史兼容

安全收益有限

跨架构移植

Windows实际实现

Ring 0: 内核+驱动+HAL(合并为一个特权级)

Ring 3: 应用程序+子系统(合并为一个特权级)

Intel原始设计意图

Ring 0: 微内核

Ring 1: 设备驱动

Ring 2: 系统服务

Ring 3: 应用程序

1.5 CPL、DPL与RPL详解

x86/x64保护模式下的权限检查涉及三个关键概念:

CPL(Current Privilege Level,当前特权级)

CPL是处理器当前运行的特权级别,存储在CS段寄存器的最低两位(bit 0和bit 1)。

CS段寄存器布局(16位):
┌─────────────────────────┬────┬────┐
│ 段选择子索引 │ TI │ RPL│
│ (13 bits) │(1b)│(2b)│
└─────────────────────────┴────┴────┘

注意:对于CS寄存器,RPL字段就是CPL

当CPU执行在Ring 0时,CS = 0x0010(索引=2, TI=0, RPL=0) 当CPU执行在Ring 3时,CS = 0x002B(索引=5, TI=0, RPL=3)

Windows x64中典型的段选择子:

选择子索引RPL/CPL用途
0x0010 2 0 内核态代码段(Ring 0)
0x0018 3 0 内核态数据段(Ring 0)
0x002B 5 3 用户态代码段(Ring 3)
0x0023 4 3 用户态数据段(Ring 3)
0x0030 6 0 内核态FS/GS相关
0x0053 10 3 用户态TSS相关

在x64长模式下,分段机制基本被禁用(所有段基址为0,段限为全地址空间),但CS中的CPL仍然发挥核心作用——它是CPU判断当前处于用户态还是内核态的唯一依据。

DPL(Descriptor Privilege Level,描述符特权级)

DPL存储在GDT(全局描述符表)中的段描述符里,表示访问该段所需的最低特权级别。

段描述符结构(8字节):

高32位:
┌──┬──┬──┬──┬──┬───────────┬──────────┐
│G │D/B│L │AVL│ Limit高4位 │ P DPL S Type │
│ │ │ │ │ │ │ │ │ 4位│
└──┴──┴──┴──┴───────────┴──────────┘

低32位:
┌─────────────────────┬───────────┐
│ Base低32位 │ Limit低16位 │
└─────────────────────┴───────────┘

关键字段:
– P (Present): 段是否存在
– DPL (2 bits): 描述符特权级 (0-3)
– S: 0=系统段/门, 1=代码/数据段
– Type (4 bits): 段类型

RPL(Requested Privilege Level,请求特权级)

RPL存储在段选择子的最低两位。它用于在访问段时进行额外的权限检查。RPL允许一个低特权级的代码使用高特权级的选择子来访问数据段,但通过RPL来限制实际访问权限。

权限检查规则:

当CPU访问一个段时,会进行以下检查:

有效特权级 Effective Privilege Level (EPL) = max(CPL, RPL)

访问条件: EPL <= DPL

即: max(CPL, RPL) <= DPL

这意味着:

  • 如果CPL=3, RPL=3, DPL=0:max(3,3)=3 > 0,访问被拒绝
  • 如果CPL=0, RPL=3, DPL=0:max(0,3)=3 > 0,访问被拒绝
  • 如果CPL=0, RPL=0, DPL=0:max(0,0)=0 <= 0,访问允许
  • 如果CPL=3, RPL=3, DPL=3:max(3,3)=3 <= 3,访问允许

#mermaid-svg-ZCUHbj8bpsYPHt6J{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ZCUHbj8bpsYPHt6J .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ZCUHbj8bpsYPHt6J .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ZCUHbj8bpsYPHt6J .error-icon{fill:#552222;}#mermaid-svg-ZCUHbj8bpsYPHt6J .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ZCUHbj8bpsYPHt6J .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ZCUHbj8bpsYPHt6J .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ZCUHbj8bpsYPHt6J .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ZCUHbj8bpsYPHt6J .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ZCUHbj8bpsYPHt6J .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ZCUHbj8bpsYPHt6J .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ZCUHbj8bpsYPHt6J .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ZCUHbj8bpsYPHt6J .marker.cross{stroke:#333333;}#mermaid-svg-ZCUHbj8bpsYPHt6J svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ZCUHbj8bpsYPHt6J p{margin:0;}#mermaid-svg-ZCUHbj8bpsYPHt6J .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-ZCUHbj8bpsYPHt6J .cluster-label text{fill:#333;}#mermaid-svg-ZCUHbj8bpsYPHt6J .cluster-label span{color:#333;}#mermaid-svg-ZCUHbj8bpsYPHt6J .cluster-label span p{background-color:transparent;}#mermaid-svg-ZCUHbj8bpsYPHt6J .label text,#mermaid-svg-ZCUHbj8bpsYPHt6J span{fill:#333;color:#333;}#mermaid-svg-ZCUHbj8bpsYPHt6J .node rect,#mermaid-svg-ZCUHbj8bpsYPHt6J .node circle,#mermaid-svg-ZCUHbj8bpsYPHt6J .node ellipse,#mermaid-svg-ZCUHbj8bpsYPHt6J .node polygon,#mermaid-svg-ZCUHbj8bpsYPHt6J .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ZCUHbj8bpsYPHt6J .rough-node .label text,#mermaid-svg-ZCUHbj8bpsYPHt6J .node .label text,#mermaid-svg-ZCUHbj8bpsYPHt6J .image-shape .label,#mermaid-svg-ZCUHbj8bpsYPHt6J .icon-shape .label{text-anchor:middle;}#mermaid-svg-ZCUHbj8bpsYPHt6J .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ZCUHbj8bpsYPHt6J .rough-node .label,#mermaid-svg-ZCUHbj8bpsYPHt6J .node .label,#mermaid-svg-ZCUHbj8bpsYPHt6J .image-shape .label,#mermaid-svg-ZCUHbj8bpsYPHt6J .icon-shape .label{text-align:center;}#mermaid-svg-ZCUHbj8bpsYPHt6J .node.clickable{cursor:pointer;}#mermaid-svg-ZCUHbj8bpsYPHt6J .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ZCUHbj8bpsYPHt6J .arrowheadPath{fill:#333333;}#mermaid-svg-ZCUHbj8bpsYPHt6J .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ZCUHbj8bpsYPHt6J .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ZCUHbj8bpsYPHt6J .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ZCUHbj8bpsYPHt6J .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ZCUHbj8bpsYPHt6J .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ZCUHbj8bpsYPHt6J .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ZCUHbj8bpsYPHt6J .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ZCUHbj8bpsYPHt6J .cluster text{fill:#333;}#mermaid-svg-ZCUHbj8bpsYPHt6J .cluster span{color:#333;}#mermaid-svg-ZCUHbj8bpsYPHt6J div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ZCUHbj8bpsYPHt6J .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ZCUHbj8bpsYPHt6J rect.text{fill:none;stroke-width:0;}#mermaid-svg-ZCUHbj8bpsYPHt6J .icon-shape,#mermaid-svg-ZCUHbj8bpsYPHt6J .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ZCUHbj8bpsYPHt6J .icon-shape p,#mermaid-svg-ZCUHbj8bpsYPHt6J .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ZCUHbj8bpsYPHt6J .icon-shape .label rect,#mermaid-svg-ZCUHbj8bpsYPHt6J .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ZCUHbj8bpsYPHt6J .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ZCUHbj8bpsYPHt6J .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ZCUHbj8bpsYPHt6J :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

上下文信息

CPL(CS.RPL)当前运行级别

RPL(选择子低2位)请求级别

DPL(段描述符)段所需级别

段访问权限检查流程

是

否

CPU访问段

段选择子含RPL

查GDT/LDT获取段描述符

读取DPL

计算EPL = max(CPL, RPL)

EPL <= DPL?

允许访问

触发 #GP

1.6 x64长模式下的特权级简化

在x64长模式(Long Mode, 64-bit)下,分段机制大幅简化:

  • 段基址固定为0:所有段的基址都设为0,偏移即为线性地址
  • 段限固定为全空间:所有段的段限都设为全地址空间
  • CS/DS/ES/SS不再使用段描述符中的基址和限:这些字段被忽略
  • FS/GS仍保留基址:用于线程本地存储(FS在x86, GS在x64)和KPCR访问
  • 尽管分段被简化,但以下机制仍然有效:

    • CS中的CPL仍然控制特权级
    • 段描述符中的DPL仍然参与权限检查
    • 跨特权级的代码段切换(如syscall)仍然改变CPL

    x64长模式下GDT的典型布局:

    // Windows x64 GDT 布局(简化)
    // GDT基址存储在GDTR寄存器中

    typedef struct _KGDTENTRY64 {
    USHORT LimitLow;
    USHORT BaseLow;
    ULONG BaseMiddle : 8;
    ULONG Type : 5; // 段类型
    ULONG Dpl : 2; // 描述符特权级
    ULONG Present : 1;
    ULONG LimitHigh : 4;
    ULONG System : 1;
    ULONG LongMode : 1; // 64位代码段标志
    ULONG DefaultBig : 1;
    ULONG Granularity : 1;
    ULONG BaseHigh : 8;
    ULONG BaseUpper : 32;
    ULONG MustBeZero : 32;
    } KGDTENTRY64;

    // GDT条目列表(Windows x64典型值):
    // [0] 0x0000 – 空描述符(Null Segment)
    // [1] 0x0008 – 未使用/保留
    // [2] 0x0010 – 内核代码段 (DPL=0, Type=代码, LongMode=1)
    // [3] 0x0018 – 内核数据段 (DPL=0, Type=数据, 可读写)
    // [4] 0x0023 – 用户数据段 (DPL=3, Type=数据, 可读写)
    // [5] 0x002B – 用户代码段 (DPL=3, Type=代码, LongMode=1)
    // [6] 0x0030 – 内核TSS相关
    // [7] 0x0038 – 未使用/保留
    // … 后续为TSS、FS/GS等

    #mermaid-svg-sYJZANshLiKqDG7D{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-sYJZANshLiKqDG7D .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-sYJZANshLiKqDG7D .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-sYJZANshLiKqDG7D .error-icon{fill:#552222;}#mermaid-svg-sYJZANshLiKqDG7D .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-sYJZANshLiKqDG7D .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-sYJZANshLiKqDG7D .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-sYJZANshLiKqDG7D .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-sYJZANshLiKqDG7D .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-sYJZANshLiKqDG7D .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-sYJZANshLiKqDG7D .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-sYJZANshLiKqDG7D .marker{fill:#333333;stroke:#333333;}#mermaid-svg-sYJZANshLiKqDG7D .marker.cross{stroke:#333333;}#mermaid-svg-sYJZANshLiKqDG7D svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-sYJZANshLiKqDG7D p{margin:0;}#mermaid-svg-sYJZANshLiKqDG7D .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-sYJZANshLiKqDG7D .cluster-label text{fill:#333;}#mermaid-svg-sYJZANshLiKqDG7D .cluster-label span{color:#333;}#mermaid-svg-sYJZANshLiKqDG7D .cluster-label span p{background-color:transparent;}#mermaid-svg-sYJZANshLiKqDG7D .label text,#mermaid-svg-sYJZANshLiKqDG7D span{fill:#333;color:#333;}#mermaid-svg-sYJZANshLiKqDG7D .node rect,#mermaid-svg-sYJZANshLiKqDG7D .node circle,#mermaid-svg-sYJZANshLiKqDG7D .node ellipse,#mermaid-svg-sYJZANshLiKqDG7D .node polygon,#mermaid-svg-sYJZANshLiKqDG7D .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-sYJZANshLiKqDG7D .rough-node .label text,#mermaid-svg-sYJZANshLiKqDG7D .node .label text,#mermaid-svg-sYJZANshLiKqDG7D .image-shape .label,#mermaid-svg-sYJZANshLiKqDG7D .icon-shape .label{text-anchor:middle;}#mermaid-svg-sYJZANshLiKqDG7D .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-sYJZANshLiKqDG7D .rough-node .label,#mermaid-svg-sYJZANshLiKqDG7D .node .label,#mermaid-svg-sYJZANshLiKqDG7D .image-shape .label,#mermaid-svg-sYJZANshLiKqDG7D .icon-shape .label{text-align:center;}#mermaid-svg-sYJZANshLiKqDG7D .node.clickable{cursor:pointer;}#mermaid-svg-sYJZANshLiKqDG7D .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-sYJZANshLiKqDG7D .arrowheadPath{fill:#333333;}#mermaid-svg-sYJZANshLiKqDG7D .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-sYJZANshLiKqDG7D .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-sYJZANshLiKqDG7D .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-sYJZANshLiKqDG7D .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-sYJZANshLiKqDG7D .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-sYJZANshLiKqDG7D .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-sYJZANshLiKqDG7D .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-sYJZANshLiKqDG7D .cluster text{fill:#333;}#mermaid-svg-sYJZANshLiKqDG7D .cluster span{color:#333;}#mermaid-svg-sYJZANshLiKqDG7D div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-sYJZANshLiKqDG7D .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-sYJZANshLiKqDG7D rect.text{fill:none;stroke-width:0;}#mermaid-svg-sYJZANshLiKqDG7D .icon-shape,#mermaid-svg-sYJZANshLiKqDG7D .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-sYJZANshLiKqDG7D .icon-shape p,#mermaid-svg-sYJZANshLiKqDG7D .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-sYJZANshLiKqDG7D .icon-shape .label rect,#mermaid-svg-sYJZANshLiKqDG7D .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-sYJZANshLiKqDG7D .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-sYJZANshLiKqDG7D .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-sYJZANshLiKqDG7D :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    使用场景

    x64 GDT 结构

    GDT[0] 0x0000Null Descriptor必须为0

    GDT[2] 0x0010内核代码段DPL=0, L=1(64bit)

    GDT[3] 0x0018内核数据段DPL=0, 可读写

    GDT[4] 0x0023用户数据段DPL=3, 可读写

    GDT[5] 0x002B用户代码段DPL=3, L=1(64bit)

    GDT[6] 0x0030TSS描述符DPL=0

    内核态运行CS=0x0010, DS/SS=0x0018

    用户态运行CS=0x002B, DS/SS=0x0023

    1.7 特权级切换的硬件约束

    从Ring 3切换到Ring 0(或反向)不是随意的,CPU只允许通过以下受控路径进行:

  • 系统调用指令:SYSCALL / SYSENTER / INT 0x2E
  • 中断和异常:硬件中断、软件中断、CPU异常
  • 调用门(Call Gate):通过GDT中的调用门描述符进行受控调用(x64中基本不再使用)
  • 任务门(Task Gate):通过TSS进行任务切换(x64中不再使用硬件任务切换)
  • 这些受控路径确保了特权级切换只能发生在预定义的入口点,操作系统能完全控制这些入口,从而实现安全隔离。

    #mermaid-svg-lOR9NwzDViAheXai{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-lOR9NwzDViAheXai .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-lOR9NwzDViAheXai .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-lOR9NwzDViAheXai .error-icon{fill:#552222;}#mermaid-svg-lOR9NwzDViAheXai .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-lOR9NwzDViAheXai .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-lOR9NwzDViAheXai .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-lOR9NwzDViAheXai .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-lOR9NwzDViAheXai .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-lOR9NwzDViAheXai .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-lOR9NwzDViAheXai .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-lOR9NwzDViAheXai .marker{fill:#333333;stroke:#333333;}#mermaid-svg-lOR9NwzDViAheXai .marker.cross{stroke:#333333;}#mermaid-svg-lOR9NwzDViAheXai svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-lOR9NwzDViAheXai p{margin:0;}#mermaid-svg-lOR9NwzDViAheXai .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-lOR9NwzDViAheXai .cluster-label text{fill:#333;}#mermaid-svg-lOR9NwzDViAheXai .cluster-label span{color:#333;}#mermaid-svg-lOR9NwzDViAheXai .cluster-label span p{background-color:transparent;}#mermaid-svg-lOR9NwzDViAheXai .label text,#mermaid-svg-lOR9NwzDViAheXai span{fill:#333;color:#333;}#mermaid-svg-lOR9NwzDViAheXai .node rect,#mermaid-svg-lOR9NwzDViAheXai .node circle,#mermaid-svg-lOR9NwzDViAheXai .node ellipse,#mermaid-svg-lOR9NwzDViAheXai .node polygon,#mermaid-svg-lOR9NwzDViAheXai .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-lOR9NwzDViAheXai .rough-node .label text,#mermaid-svg-lOR9NwzDViAheXai .node .label text,#mermaid-svg-lOR9NwzDViAheXai .image-shape .label,#mermaid-svg-lOR9NwzDViAheXai .icon-shape .label{text-anchor:middle;}#mermaid-svg-lOR9NwzDViAheXai .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-lOR9NwzDViAheXai .rough-node .label,#mermaid-svg-lOR9NwzDViAheXai .node .label,#mermaid-svg-lOR9NwzDViAheXai .image-shape .label,#mermaid-svg-lOR9NwzDViAheXai .icon-shape .label{text-align:center;}#mermaid-svg-lOR9NwzDViAheXai .node.clickable{cursor:pointer;}#mermaid-svg-lOR9NwzDViAheXai .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-lOR9NwzDViAheXai .arrowheadPath{fill:#333333;}#mermaid-svg-lOR9NwzDViAheXai .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-lOR9NwzDViAheXai .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-lOR9NwzDViAheXai .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-lOR9NwzDViAheXai .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-lOR9NwzDViAheXai .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-lOR9NwzDViAheXai .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-lOR9NwzDViAheXai .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-lOR9NwzDViAheXai .cluster text{fill:#333;}#mermaid-svg-lOR9NwzDViAheXai .cluster span{color:#333;}#mermaid-svg-lOR9NwzDViAheXai div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-lOR9NwzDViAheXai .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-lOR9NwzDViAheXai rect.text{fill:none;stroke-width:0;}#mermaid-svg-lOR9NwzDViAheXai .icon-shape,#mermaid-svg-lOR9NwzDViAheXai .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-lOR9NwzDViAheXai .icon-shape p,#mermaid-svg-lOR9NwzDViAheXai .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-lOR9NwzDViAheXai .icon-shape .label rect,#mermaid-svg-lOR9NwzDViAheXai .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-lOR9NwzDViAheXai .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-lOR9NwzDViAheXai .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-lOR9NwzDViAheXai :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    Ring 0 (内核态)

    受控切换路径

    Ring 3 (用户态)

    应用程序

    SYSCALL指令

    SYSENTER指令

    INT 0x2E

    硬件中断(时钟/网卡/键鼠等)

    CPU异常(缺页/GP/除零等)

    调用门(x64基本弃用)

    内核入口函数KiSystemCall64KiInterruptDispatchKiExceptionDispatch


    2. 用户态与内核态的分界

    2.1 虚拟地址空间布局

    Windows x64使用48位虚拟地址空间(虽然寄存器是64位,但CPU只实现48位虚拟地址),总地址空间为256TB。这个空间被精确地分为两半:用户态地址空间和内核态地址空间。

    #mermaid-svg-kWGSDc7ePR3i0Kks{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-kWGSDc7ePR3i0Kks .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-kWGSDc7ePR3i0Kks .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-kWGSDc7ePR3i0Kks .error-icon{fill:#552222;}#mermaid-svg-kWGSDc7ePR3i0Kks .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-kWGSDc7ePR3i0Kks .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-kWGSDc7ePR3i0Kks .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-kWGSDc7ePR3i0Kks .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-kWGSDc7ePR3i0Kks .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-kWGSDc7ePR3i0Kks .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-kWGSDc7ePR3i0Kks .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-kWGSDc7ePR3i0Kks .marker{fill:#333333;stroke:#333333;}#mermaid-svg-kWGSDc7ePR3i0Kks .marker.cross{stroke:#333333;}#mermaid-svg-kWGSDc7ePR3i0Kks svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-kWGSDc7ePR3i0Kks p{margin:0;}#mermaid-svg-kWGSDc7ePR3i0Kks .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-kWGSDc7ePR3i0Kks .cluster-label text{fill:#333;}#mermaid-svg-kWGSDc7ePR3i0Kks .cluster-label span{color:#333;}#mermaid-svg-kWGSDc7ePR3i0Kks .cluster-label span p{background-color:transparent;}#mermaid-svg-kWGSDc7ePR3i0Kks .label text,#mermaid-svg-kWGSDc7ePR3i0Kks span{fill:#333;color:#333;}#mermaid-svg-kWGSDc7ePR3i0Kks .node rect,#mermaid-svg-kWGSDc7ePR3i0Kks .node circle,#mermaid-svg-kWGSDc7ePR3i0Kks .node ellipse,#mermaid-svg-kWGSDc7ePR3i0Kks .node polygon,#mermaid-svg-kWGSDc7ePR3i0Kks .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-kWGSDc7ePR3i0Kks .rough-node .label text,#mermaid-svg-kWGSDc7ePR3i0Kks .node .label text,#mermaid-svg-kWGSDc7ePR3i0Kks .image-shape .label,#mermaid-svg-kWGSDc7ePR3i0Kks .icon-shape .label{text-anchor:middle;}#mermaid-svg-kWGSDc7ePR3i0Kks .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-kWGSDc7ePR3i0Kks .rough-node .label,#mermaid-svg-kWGSDc7ePR3i0Kks .node .label,#mermaid-svg-kWGSDc7ePR3i0Kks .image-shape .label,#mermaid-svg-kWGSDc7ePR3i0Kks .icon-shape .label{text-align:center;}#mermaid-svg-kWGSDc7ePR3i0Kks .node.clickable{cursor:pointer;}#mermaid-svg-kWGSDc7ePR3i0Kks .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-kWGSDc7ePR3i0Kks .arrowheadPath{fill:#333333;}#mermaid-svg-kWGSDc7ePR3i0Kks .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-kWGSDc7ePR3i0Kks .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-kWGSDc7ePR3i0Kks .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-kWGSDc7ePR3i0Kks .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-kWGSDc7ePR3i0Kks .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-kWGSDc7ePR3i0Kks .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-kWGSDc7ePR3i0Kks .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-kWGSDc7ePR3i0Kks .cluster text{fill:#333;}#mermaid-svg-kWGSDc7ePR3i0Kks .cluster span{color:#333;}#mermaid-svg-kWGSDc7ePR3i0Kks div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-kWGSDc7ePR3i0Kks .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-kWGSDc7ePR3i0Kks rect.text{fill:none;stroke-width:0;}#mermaid-svg-kWGSDc7ePR3i0Kks .icon-shape,#mermaid-svg-kWGSDc7ePR3i0Kks .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-kWGSDc7ePR3i0Kks .icon-shape p,#mermaid-svg-kWGSDc7ePR3i0Kks .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-kWGSDc7ePR3i0Kks .icon-shape .label rect,#mermaid-svg-kWGSDc7ePR3i0Kks .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-kWGSDc7ePR3i0Kks .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-kWGSDc7ePR3i0Kks .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-kWGSDc7ePR3i0Kks :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    Windows x64 虚拟地址空间布局 (48位VA)

    0x00007FFF'FFFFFFFF用户态地址空间上界 (128TB)

    用户态区域0x00000000'00000000 – 0x00007FFF'FFFFFFFF128TB包含: EXE/DLL/堆/栈/TEB等

    0x00007FFE'0000KUSER_SHARED_DATA用户态只读, 内核态读写4KB共享页

    不可用区域0x00008000'00000000 – 0xFFFF0000'00000000(架构保留, 访问触发#GP)

    0xFFFF0000'00000000内核态地址空间下界

    内核态区域0xFFFF0000'00000000 – 0xFFFFFFFF'FFFFFFFF128TB包含: 内核映像/页表/PFN/系统缓存等

    0xFFFFFFFF'FFFFFFFF内核态地址空间上界

    关键地址分界点说明:

    地址范围大小用途访问权限
    0x0000000000000000 – 0x00007FFFFFFFFFFF 128TB 用户态地址空间 Ring 3可访问
    0x00007FFE0000 4KB KUSER_SHARED_DATA Ring 3只读, Ring 0读写
    0x0000800000000000 – 0xFFFEFFFFFFFFFFFF ~16EB 架构保留区 任何Ring都不可访问
    0xFFFF000000000000 – 0xFFFFFFFFFFFFFFFF 128TB 内核态地址空间 仅Ring 0可访问

    2.2 用户态地址空间详细布局

    用户态的128TB地址空间内部也有精细的划分:

    #mermaid-svg-heznxQFOEfGHXNuB{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-heznxQFOEfGHXNuB .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-heznxQFOEfGHXNuB .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-heznxQFOEfGHXNuB .error-icon{fill:#552222;}#mermaid-svg-heznxQFOEfGHXNuB .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-heznxQFOEfGHXNuB .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-heznxQFOEfGHXNuB .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-heznxQFOEfGHXNuB .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-heznxQFOEfGHXNuB .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-heznxQFOEfGHXNuB .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-heznxQFOEfGHXNuB .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-heznxQFOEfGHXNuB .marker{fill:#333333;stroke:#333333;}#mermaid-svg-heznxQFOEfGHXNuB .marker.cross{stroke:#333333;}#mermaid-svg-heznxQFOEfGHXNuB svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-heznxQFOEfGHXNuB p{margin:0;}#mermaid-svg-heznxQFOEfGHXNuB .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-heznxQFOEfGHXNuB .cluster-label text{fill:#333;}#mermaid-svg-heznxQFOEfGHXNuB .cluster-label span{color:#333;}#mermaid-svg-heznxQFOEfGHXNuB .cluster-label span p{background-color:transparent;}#mermaid-svg-heznxQFOEfGHXNuB .label text,#mermaid-svg-heznxQFOEfGHXNuB span{fill:#333;color:#333;}#mermaid-svg-heznxQFOEfGHXNuB .node rect,#mermaid-svg-heznxQFOEfGHXNuB .node circle,#mermaid-svg-heznxQFOEfGHXNuB .node ellipse,#mermaid-svg-heznxQFOEfGHXNuB .node polygon,#mermaid-svg-heznxQFOEfGHXNuB .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-heznxQFOEfGHXNuB .rough-node .label text,#mermaid-svg-heznxQFOEfGHXNuB .node .label text,#mermaid-svg-heznxQFOEfGHXNuB .image-shape .label,#mermaid-svg-heznxQFOEfGHXNuB .icon-shape .label{text-anchor:middle;}#mermaid-svg-heznxQFOEfGHXNuB .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-heznxQFOEfGHXNuB .rough-node .label,#mermaid-svg-heznxQFOEfGHXNuB .node .label,#mermaid-svg-heznxQFOEfGHXNuB .image-shape .label,#mermaid-svg-heznxQFOEfGHXNuB .icon-shape .label{text-align:center;}#mermaid-svg-heznxQFOEfGHXNuB .node.clickable{cursor:pointer;}#mermaid-svg-heznxQFOEfGHXNuB .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-heznxQFOEfGHXNuB .arrowheadPath{fill:#333333;}#mermaid-svg-heznxQFOEfGHXNuB .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-heznxQFOEfGHXNuB .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-heznxQFOEfGHXNuB .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-heznxQFOEfGHXNuB .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-heznxQFOEfGHXNuB .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-heznxQFOEfGHXNuB .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-heznxQFOEfGHXNuB .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-heznxQFOEfGHXNuB .cluster text{fill:#333;}#mermaid-svg-heznxQFOEfGHXNuB .cluster span{color:#333;}#mermaid-svg-heznxQFOEfGHXNuB div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-heznxQFOEfGHXNuB .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-heznxQFOEfGHXNuB rect.text{fill:none;stroke-width:0;}#mermaid-svg-heznxQFOEfGHXNuB .icon-shape,#mermaid-svg-heznxQFOEfGHXNuB .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-heznxQFOEfGHXNuB .icon-shape p,#mermaid-svg-heznxQFOEfGHXNuB .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-heznxQFOEfGHXNuB .icon-shape .label rect,#mermaid-svg-heznxQFOEfGHXNuB .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-heznxQFOEfGHXNuB .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-heznxQFOEfGHXNuB .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-heznxQFOEfGHXNuB :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    用户态地址空间 0x0000000000000000 – 0x00007FFFFFFFFFFF

    0x00000000 – 0x0000FFFF空指针陷阱区 (64KB)捕获NULL指针解引用

    0x00010000 – 0x7FFEFFFF低地址用户区EXE/DLL加载/堆/栈

    0x7FFE0000 – 0x7FFE0FFFKUSER_SHARED_DATA内核共享数据(只读)

    0x7FFE1000 – 0x7FFE1FFFSharedData+1页扩展共享数据

    0x7FFE2000 – 0x7FFEFFFF保留区域

    0x7FFEXXXX – 0x7FFEXXXX主线程用户栈(默认1MB保留, 按需提交)

    TEB/PEB区域每个线程一个TEB(4KB+)进程PEB(4KB+)

    0x7FF700000000 – 0x7FF7FFFFFFFF系统DLL加载区ntdll.dll/kernel32.dll等

    用户堆区域HeapAlloc/VirtualAlloc分配动态增长

    用户态地址空间关键区域说明:

  • 空指针陷阱区(0x00000000 – 0x0000FFFF):Windows保留最低64KB的地址空间不分配,任何对这区域的访问都会触发访问违规异常(0xC0000005),这用于捕获空指针解引用bug。

  • EXE/DLL加载区:可执行文件和DLL的映像加载区域。Windows ASLR(地址空间布局随机化)会在此区域随机选择加载基址。

  • KUSER_SHARED_DATA(0x7FFE0000):这是一个特殊的共享页面,将在下一节详细说明。

  • TEB(Thread Environment Block):每个线程都有一个TEB,存储线程相关的信息,如线程ID、异常链表、TLS数组指针等。通过GS段寄存器(x64)或FS段寄存器(x86)访问。

  • PEB(Process Environment Block):每个进程一个PEB,存储进程相关信息,如加载的模块列表、堆信息、调试标志等。

  • 用户栈:每个线程的用户态栈,默认保留1MB、初始提交4KB。

  • 2.3 KUSER_SHARED_DATA共享区

    KUSER_SHARED_DATA是Windows中一个极其重要但经常被忽视的机制。它是一个4KB的页面,被同时映射到用户态地址(0x7FFE0000)和内核态地址(0xFFFFF78000000000),使得用户态代码可以直接读取某些内核维护的数据,而无需发起系统调用。

    // KUSER_SHARED_DATA 结构(简化版,实际更复杂)
    // 用户态地址: 0x7FFE0000
    // 内核态地址: 0xFFFFF78000000000

    typedef struct _KUSER_SHARED_DATA {
    ULONG TickCountLowDeprecated; // 0x000 时钟滴答计数(低32位, 已弃用)
    ULONG TickCountMultiplier; // 0x004 滴答乘数

    volatile KSYSTEM_TIME InterruptTime; // 0x008 中断时间(100ns单位)
    volatile KSYSTEM_TIME SystemTime; // 0x014 系统时间(100ns单位)
    volatile KSYSTEM_TIME TimeZoneBias; // 0x020 时区偏移

    USHORT ImageNumberLow; // 0x02C
    USHORT ImageNumberHigh; // 0x02E
    WCHAR NtSystemRoot[260]; // 0x030 系统目录路径(如\\Windows)
    ULONG MaxStackTraceDepth; // 0x238
    ULONG CryptoExponent; // 0x23C
    ULONG TimeZoneId; // 0x240 时区ID
    ULONG LargePageMinimum; // 0x244 大页最小值

    ULONG Reserved2[7]; // 0x248

    // NtProductType: 产品类型(工作站/服务器等)
    NT_PRODUCT_TYPE NtProductType; // 0x264
    BOOLEAN ProductTypeIsValid; // 0x268

    ULONG Reserved3[1]; // 0x26C
    ULONG NtMajorVersion; // 0x26C 主版本号 (如10)
    ULONG NtMinorVersion; // 0x270 次版本号 (如0)

    // … 更多字段 …

    // 重要: 用户态可读取的时间信息
    volatile ULONG TickCountLow; // 时钟滴答(低32位)
    volatile ULONG TickCountHigh; // 时钟滴答(高32位)

    // x64: 使用 QPC 相关字段
    volatile ULONG64 QpcBias; // QPC偏移
    volatile ULONG64 QpcFrequency; // QPC频率

    // … 更多字段 …

    // SystemCall: 系统调用入口地址(x86)
    ULONG SystemCall; // sysenter入口地址
    ULONG SystemCallReturn; // sysenter返回地址

    // … 更多字段 …

    volatile KSYSTEM_TIME TickCount; // 完整的时钟滴答
    volatile ULONG64 Cookie; // 随机Cookie

    // … 更多字段 …
    } KUSER_SHARED_DATA;

    KUSER_SHARED_DATA的核心价值:

    用户态代码经常需要获取系统时间、时钟滴答等信息。如果每次都通过系统调用获取,会产生巨大的性能开销。通过共享页面,用户态代码可以直接读取这些数据:

    // 用户态获取系统时间的优化路径
    // 无需系统调用,直接读取共享页面

    ULONGLONG GetUserModeSystemTime(void)
    {
    // 直接通过0x7FFE0000地址读取
    KUSER_SHARED_DATA *SharedData = (KUSER_SHARED_DATA *)0x7FFE0000;

    // 读取系统时间(100ns为单位,从1601-01-01开始)
    LARGE_INTEGER SystemTime;

    // 注意:需要处理读取过程中时间更新的竞态
    // 高32位可能在我们读取低32位后变化
    do {
    SystemTime.HighPart = SharedData->SystemTime.High1Time;
    SystemTime.LowPart = SharedData->SystemTime.LowPart;
    } while (SystemTime.HighPart != SharedData->SystemTime.High2Time);

    return SystemTime.QuadPart;
    }

    // 用户态获取高精度性能计数器
    // QueryPerformanceCounter的底层实现就是读取KUSER_SHARED_DATA
    ULONGLONG GetQPC(void)
    {
    KUSER_SHARED_DATA *SharedData = (KUSER_SHARED_DATA *)0x7FFE0000;
    // QPC的具体读取逻辑取决于平台和CPU特性
    // 在支持RDTSCP的CPU上,结合TSC和QpcBias计算
    // 在不支持时,直接读取共享页面
    return __rdtsc() – SharedData->QpcBias;
    }

    #mermaid-svg-LMrgcdJMXaDSuvX8{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-LMrgcdJMXaDSuvX8 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-LMrgcdJMXaDSuvX8 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-LMrgcdJMXaDSuvX8 .error-icon{fill:#552222;}#mermaid-svg-LMrgcdJMXaDSuvX8 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-LMrgcdJMXaDSuvX8 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-LMrgcdJMXaDSuvX8 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-LMrgcdJMXaDSuvX8 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-LMrgcdJMXaDSuvX8 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-LMrgcdJMXaDSuvX8 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-LMrgcdJMXaDSuvX8 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-LMrgcdJMXaDSuvX8 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-LMrgcdJMXaDSuvX8 .marker.cross{stroke:#333333;}#mermaid-svg-LMrgcdJMXaDSuvX8 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-LMrgcdJMXaDSuvX8 p{margin:0;}#mermaid-svg-LMrgcdJMXaDSuvX8 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-LMrgcdJMXaDSuvX8 .cluster-label text{fill:#333;}#mermaid-svg-LMrgcdJMXaDSuvX8 .cluster-label span{color:#333;}#mermaid-svg-LMrgcdJMXaDSuvX8 .cluster-label span p{background-color:transparent;}#mermaid-svg-LMrgcdJMXaDSuvX8 .label text,#mermaid-svg-LMrgcdJMXaDSuvX8 span{fill:#333;color:#333;}#mermaid-svg-LMrgcdJMXaDSuvX8 .node rect,#mermaid-svg-LMrgcdJMXaDSuvX8 .node circle,#mermaid-svg-LMrgcdJMXaDSuvX8 .node ellipse,#mermaid-svg-LMrgcdJMXaDSuvX8 .node polygon,#mermaid-svg-LMrgcdJMXaDSuvX8 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-LMrgcdJMXaDSuvX8 .rough-node .label text,#mermaid-svg-LMrgcdJMXaDSuvX8 .node .label text,#mermaid-svg-LMrgcdJMXaDSuvX8 .image-shape .label,#mermaid-svg-LMrgcdJMXaDSuvX8 .icon-shape .label{text-anchor:middle;}#mermaid-svg-LMrgcdJMXaDSuvX8 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-LMrgcdJMXaDSuvX8 .rough-node .label,#mermaid-svg-LMrgcdJMXaDSuvX8 .node .label,#mermaid-svg-LMrgcdJMXaDSuvX8 .image-shape .label,#mermaid-svg-LMrgcdJMXaDSuvX8 .icon-shape .label{text-align:center;}#mermaid-svg-LMrgcdJMXaDSuvX8 .node.clickable{cursor:pointer;}#mermaid-svg-LMrgcdJMXaDSuvX8 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-LMrgcdJMXaDSuvX8 .arrowheadPath{fill:#333333;}#mermaid-svg-LMrgcdJMXaDSuvX8 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-LMrgcdJMXaDSuvX8 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-LMrgcdJMXaDSuvX8 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-LMrgcdJMXaDSuvX8 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-LMrgcdJMXaDSuvX8 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-LMrgcdJMXaDSuvX8 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-LMrgcdJMXaDSuvX8 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-LMrgcdJMXaDSuvX8 .cluster text{fill:#333;}#mermaid-svg-LMrgcdJMXaDSuvX8 .cluster span{color:#333;}#mermaid-svg-LMrgcdJMXaDSuvX8 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-LMrgcdJMXaDSuvX8 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-LMrgcdJMXaDSuvX8 rect.text{fill:none;stroke-width:0;}#mermaid-svg-LMrgcdJMXaDSuvX8 .icon-shape,#mermaid-svg-LMrgcdJMXaDSuvX8 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-LMrgcdJMXaDSuvX8 .icon-shape p,#mermaid-svg-LMrgcdJMXaDSuvX8 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-LMrgcdJMXaDSuvX8 .icon-shape .label rect,#mermaid-svg-LMrgcdJMXaDSuvX8 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-LMrgcdJMXaDSuvX8 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-LMrgcdJMXaDSuvX8 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-LMrgcdJMXaDSuvX8 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    使用场景

    用户态映射

    内核态映射

    物理内存页 (4KB)

    PTE映射(内核)

    PTE映射(用户,只读)

    KUSER_SHARED_DATA 物理页包含: SystemTime/TickCount/QPC等

    0xFFFFF78000000000内核可读写

    0x00007FFE0000用户只读

    内核: 更新SystemTime更新TickCount更新QpcBias

    用户态: GetSystemTimeAsFileTimeQueryPerformanceCounterGetTickCount

    安全性说明:

    KUSER_SHARED_DATA的用户态映射是只读的。如果用户态代码尝试写入这个页面,会触发访问违规异常(STATUS_ACCESS_VIOLATION, 0xC0000005)。内核通过页表项(PTE)的权限位来控制这一行为:

    用户态PTE权限:
    – Present = 1 (页面存在)
    – Readable = 1 (可读)
    – Writable = 0 (不可写)
    – User = 1 (用户态可访问)
    – NX = 1 (不可执行)

    内核态PTE权限 (同一物理页的另一个映射):
    – Present = 1
    – Readable = 1
    – Writable = 1 (可写)
    – User = 0 (仅内核可访问)
    – NX = 1

    2.4 内核态地址空间详细布局

    内核态的128TB地址空间同样有精细的划分:

    #mermaid-svg-5ZXVYPcjh6XHsPLl{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-5ZXVYPcjh6XHsPLl .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-5ZXVYPcjh6XHsPLl .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-5ZXVYPcjh6XHsPLl .error-icon{fill:#552222;}#mermaid-svg-5ZXVYPcjh6XHsPLl .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5ZXVYPcjh6XHsPLl .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-5ZXVYPcjh6XHsPLl .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5ZXVYPcjh6XHsPLl .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5ZXVYPcjh6XHsPLl .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-5ZXVYPcjh6XHsPLl .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5ZXVYPcjh6XHsPLl .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5ZXVYPcjh6XHsPLl .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5ZXVYPcjh6XHsPLl .marker.cross{stroke:#333333;}#mermaid-svg-5ZXVYPcjh6XHsPLl svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5ZXVYPcjh6XHsPLl p{margin:0;}#mermaid-svg-5ZXVYPcjh6XHsPLl .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-5ZXVYPcjh6XHsPLl .cluster-label text{fill:#333;}#mermaid-svg-5ZXVYPcjh6XHsPLl .cluster-label span{color:#333;}#mermaid-svg-5ZXVYPcjh6XHsPLl .cluster-label span p{background-color:transparent;}#mermaid-svg-5ZXVYPcjh6XHsPLl .label text,#mermaid-svg-5ZXVYPcjh6XHsPLl span{fill:#333;color:#333;}#mermaid-svg-5ZXVYPcjh6XHsPLl .node rect,#mermaid-svg-5ZXVYPcjh6XHsPLl .node circle,#mermaid-svg-5ZXVYPcjh6XHsPLl .node ellipse,#mermaid-svg-5ZXVYPcjh6XHsPLl .node polygon,#mermaid-svg-5ZXVYPcjh6XHsPLl .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5ZXVYPcjh6XHsPLl .rough-node .label text,#mermaid-svg-5ZXVYPcjh6XHsPLl .node .label text,#mermaid-svg-5ZXVYPcjh6XHsPLl .image-shape .label,#mermaid-svg-5ZXVYPcjh6XHsPLl .icon-shape .label{text-anchor:middle;}#mermaid-svg-5ZXVYPcjh6XHsPLl .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-5ZXVYPcjh6XHsPLl .rough-node .label,#mermaid-svg-5ZXVYPcjh6XHsPLl .node .label,#mermaid-svg-5ZXVYPcjh6XHsPLl .image-shape .label,#mermaid-svg-5ZXVYPcjh6XHsPLl .icon-shape .label{text-align:center;}#mermaid-svg-5ZXVYPcjh6XHsPLl .node.clickable{cursor:pointer;}#mermaid-svg-5ZXVYPcjh6XHsPLl .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-5ZXVYPcjh6XHsPLl .arrowheadPath{fill:#333333;}#mermaid-svg-5ZXVYPcjh6XHsPLl .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-5ZXVYPcjh6XHsPLl .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-5ZXVYPcjh6XHsPLl .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5ZXVYPcjh6XHsPLl .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-5ZXVYPcjh6XHsPLl .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5ZXVYPcjh6XHsPLl .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-5ZXVYPcjh6XHsPLl .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-5ZXVYPcjh6XHsPLl .cluster text{fill:#333;}#mermaid-svg-5ZXVYPcjh6XHsPLl .cluster span{color:#333;}#mermaid-svg-5ZXVYPcjh6XHsPLl div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-5ZXVYPcjh6XHsPLl .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-5ZXVYPcjh6XHsPLl rect.text{fill:none;stroke-width:0;}#mermaid-svg-5ZXVYPcjh6XHsPLl .icon-shape,#mermaid-svg-5ZXVYPcjh6XHsPLl .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5ZXVYPcjh6XHsPLl .icon-shape p,#mermaid-svg-5ZXVYPcjh6XHsPLl .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-5ZXVYPcjh6XHsPLl .icon-shape .label rect,#mermaid-svg-5ZXVYPcjh6XHsPLl .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5ZXVYPcjh6XHsPLl .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-5ZXVYPcjh6XHsPLl .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-5ZXVYPcjh6XHsPLl :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    内核态地址空间 0xFFFF000000000000 – 0xFFFFFFFFFFFFFFFF

    0xFFFFF80000000000内核映像加载区ntoskrnl.exe/hal.dll/驱动通常约0x000000020000大小

    0xFFFFF68000000000页表自映射区(PTE_BASE)自身映射所有PTE512GB

    0xFFFFFA8000000000PFN数据库描述所有物理页每页约28-32字节

    0xFFFFF90000000000系统缓存区文件系统缓存

    0xFFFFFA8000000000分页池(Paged Pool)可被换出的内核内存

    0xFFFFFB0000000000非分页池(Non-Paged Pool)不可换出, IRQL>=DISPATCH_LEVEL可用

    0xFFFFFC0000000000系统PTE区域用于系统PTE映射

    0xFFFFF80000000000特殊系统区会话空间/终端服务等

    0xFFFFF78000000000KUSER_SHARED_DATA内核态映射

    0xFFFFFFFF00000000高地址区HAL/启动相关

    内核态地址空间关键区域:

    区域起始地址(典型值)说明
    内核映像 0xFFFFF80000000000 ntoskrnl.exe, hal.dll, 驱动程序
    PTE自映射 0xFFFFF68000000000 页表自身的虚拟映射
    系统缓存 0xFFFFF90000000000 文件系统缓存
    分页池 0xFFFFFA8000000000 可换出的内核内存
    非分页池 0xFFFFFB0000000000 不可换出的内核内存
    KUSER_SHARED_DATA 0xFFFFF78000000000 共享数据页内核映射
    系统PTE 0xFFFFFC0000000000 系统PTE区域
    HAL区 0xFFFFFFFF00000000 HAL相关数据

    2.5 地址空间分界的硬件实现

    用户态和内核态地址空间的分界不是软件约定,而是由CPU硬件强制的。具体实现涉及页表项中的User/Supervisor位:

    页表项(PTE)中的权限位:
    ┌────────────────────────────────────────────────────────┐
    │ Bit 63 │ Bit 62 │ … │ Bit 2 │ Bit 1 │ Bit 0 │
    │ NX │ Global │ │ U/S │ R/W │ Present │
    │(不可执行)│ (全局TLB)│ │(用户/管理)│(读/写) │ (存在) │
    └────────────────────────────────────────────────────────┘

    U/S位 (User/Supervisor):
    – 0 = Supervisor only (仅Ring 0可访问)
    – 1 = User accessible (Ring 0和Ring 3都可访问)

    当Ring 3代码尝试访问U/S=0的页面时,CPU的MMU会触发页面错误(Page Fault, #PF, 中断号0x0E),错误码的U/S位会被设置为1(表示用户态访问违规)。

    #mermaid-svg-12mVPlkjDmaTkBWg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-12mVPlkjDmaTkBWg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-12mVPlkjDmaTkBWg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-12mVPlkjDmaTkBWg .error-icon{fill:#552222;}#mermaid-svg-12mVPlkjDmaTkBWg .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-12mVPlkjDmaTkBWg .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-12mVPlkjDmaTkBWg .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-12mVPlkjDmaTkBWg .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-12mVPlkjDmaTkBWg .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-12mVPlkjDmaTkBWg .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-12mVPlkjDmaTkBWg .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-12mVPlkjDmaTkBWg .marker{fill:#333333;stroke:#333333;}#mermaid-svg-12mVPlkjDmaTkBWg .marker.cross{stroke:#333333;}#mermaid-svg-12mVPlkjDmaTkBWg svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-12mVPlkjDmaTkBWg p{margin:0;}#mermaid-svg-12mVPlkjDmaTkBWg .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-12mVPlkjDmaTkBWg .cluster-label text{fill:#333;}#mermaid-svg-12mVPlkjDmaTkBWg .cluster-label span{color:#333;}#mermaid-svg-12mVPlkjDmaTkBWg .cluster-label span p{background-color:transparent;}#mermaid-svg-12mVPlkjDmaTkBWg .label text,#mermaid-svg-12mVPlkjDmaTkBWg span{fill:#333;color:#333;}#mermaid-svg-12mVPlkjDmaTkBWg .node rect,#mermaid-svg-12mVPlkjDmaTkBWg .node circle,#mermaid-svg-12mVPlkjDmaTkBWg .node ellipse,#mermaid-svg-12mVPlkjDmaTkBWg .node polygon,#mermaid-svg-12mVPlkjDmaTkBWg .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-12mVPlkjDmaTkBWg .rough-node .label text,#mermaid-svg-12mVPlkjDmaTkBWg .node .label text,#mermaid-svg-12mVPlkjDmaTkBWg .image-shape .label,#mermaid-svg-12mVPlkjDmaTkBWg .icon-shape .label{text-anchor:middle;}#mermaid-svg-12mVPlkjDmaTkBWg .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-12mVPlkjDmaTkBWg .rough-node .label,#mermaid-svg-12mVPlkjDmaTkBWg .node .label,#mermaid-svg-12mVPlkjDmaTkBWg .image-shape .label,#mermaid-svg-12mVPlkjDmaTkBWg .icon-shape .label{text-align:center;}#mermaid-svg-12mVPlkjDmaTkBWg .node.clickable{cursor:pointer;}#mermaid-svg-12mVPlkjDmaTkBWg .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-12mVPlkjDmaTkBWg .arrowheadPath{fill:#333333;}#mermaid-svg-12mVPlkjDmaTkBWg .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-12mVPlkjDmaTkBWg .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-12mVPlkjDmaTkBWg .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-12mVPlkjDmaTkBWg .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-12mVPlkjDmaTkBWg .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-12mVPlkjDmaTkBWg .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-12mVPlkjDmaTkBWg .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-12mVPlkjDmaTkBWg .cluster text{fill:#333;}#mermaid-svg-12mVPlkjDmaTkBWg .cluster span{color:#333;}#mermaid-svg-12mVPlkjDmaTkBWg div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-12mVPlkjDmaTkBWg .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-12mVPlkjDmaTkBWg rect.text{fill:none;stroke-width:0;}#mermaid-svg-12mVPlkjDmaTkBWg .icon-shape,#mermaid-svg-12mVPlkjDmaTkBWg .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-12mVPlkjDmaTkBWg .icon-shape p,#mermaid-svg-12mVPlkjDmaTkBWg .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-12mVPlkjDmaTkBWg .icon-shape .label rect,#mermaid-svg-12mVPlkjDmaTkBWg .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-12mVPlkjDmaTkBWg .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-12mVPlkjDmaTkBWg .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-12mVPlkjDmaTkBWg :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    虚拟地址访问检查流程

    否

    是

    Ring3且U/S=0

    是

    是

    否

    是

    否

    虚拟地址访问VA = 0xFFFF800000123456

    遍历PML4表(CR3指向PML4基址)

    遍历PDPT表

    遍历PD表

    遍历PT表获取PTE

    PTE.Present=1?

    触发 #PF错误码P=0

    CPL<=Ring0或 PTE.U/S=1?

    触发 #PF错误码U=1(用户态违规)

    写操作且PTE.R/W=0?

    触发 #PF错误码W=1(写违规)

    执行且PTE.NX=1?

    触发 #PF错误码ID=0(执行违规)

    允许访问返回物理地址

    2.6 syscall/sysret作为切换点

    在x64架构中,syscall指令是用户态进入内核态的主要入口点。sysret是对应的返回指令。这对指令的设计目标是实现最小开销的特权级切换。

    与旧机制(int 0x2E、sysenter)相比,syscall/sysret的优势在于:

    • 不需要查内存中的IDT或GDT,直接从MSR寄存器读取入口地址
    • 不需要内存中的栈切换信息,直接从TSS读取
    • 执行路径固定,减少分支预测失败
    • 只修改最少的寄存器(RIP, RSP, CS, SS, RFLAGS)

    相关的MSR寄存器:

    MSR地址名称用途
    0xC0000081 STAR CS/SS选择子基址
    0xC0000082 LSTAR syscall入口地址(KiSystemCall64)
    0xC0000083 CSTAR 32位兼容模式syscall入口(KiSystemCall32)
    0xC0000084 SFMASK RFLAGS掩码(清除哪些标志位)

    在系统初始化时,内核设置这些MSR:

    // Windows内核初始化时设置syscall MSR(简化代码)
    // 文件: ntoskrnl/ke/arch/amd64/syscall.c (概念性)

    VOID KiInitializeSystemCall(VOID)
    {
    ULONG64 StarValue;
    ULONG64 FlagsMask;

    // 设置LSTAR: syscall入口地址
    // KiSystemCall64 是Windows x64的系统调用入口
    __writemsr(0xC0000082, (ULONG64)&KiSystemCall64);

    // 设置CSTAR: 32位兼容模式入口
    __writemsr(0xC0000083, (ULONG64)&KiSystemCall32);

    // 设置STAR: 段选择子
    // [63:48] = sysret后的CS (0x002B, 用户代码段Ring3)
    // [47:32] = syscall后的CS (0x0010, 内核代码段Ring0)
    // [31:0] = sysret后的SS (0x002B+8=0x0023, 用户数据段Ring3)
    // = syscall后的SS (0x0010+8=0x0018, 内核数据段Ring0)
    StarValue = ((ULONG64)KGDT64_USER_CODE << 48) | // 0x002B
    ((ULONG64)KGDT64_CODE << 32) | // 0x0010
    ((ULONG64)KGDT64_USER_DATA << 16) | // 0x0023
    ((ULONG64)KGDT64_DATA << 0); // 0x0018
    // 注意: 实际Windows中STAR的编码略有不同
    // [63:48] = sysret CS = 0x002B
    // [47:32] = syscall CS = 0x0010
    // sysret/syscall自动计算SS = CS + 8
    __writemsr(0xC0000081, StarValue);

    // 设置SFMASK: syscall时清除的RFLAGS位
    // 清除IF(中断标志)、TF(陷阱标志)等
    FlagsMask = EFLAGS_IF_MASK | EFLAGS_TF_MASK;
    __writemsr(0xC0000084, FlagsMask);
    }

    #mermaid-svg-oP91aw80mvJepoQs{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-oP91aw80mvJepoQs .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-oP91aw80mvJepoQs .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-oP91aw80mvJepoQs .error-icon{fill:#552222;}#mermaid-svg-oP91aw80mvJepoQs .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-oP91aw80mvJepoQs .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-oP91aw80mvJepoQs .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-oP91aw80mvJepoQs .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-oP91aw80mvJepoQs .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-oP91aw80mvJepoQs .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-oP91aw80mvJepoQs .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-oP91aw80mvJepoQs .marker{fill:#333333;stroke:#333333;}#mermaid-svg-oP91aw80mvJepoQs .marker.cross{stroke:#333333;}#mermaid-svg-oP91aw80mvJepoQs svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-oP91aw80mvJepoQs p{margin:0;}#mermaid-svg-oP91aw80mvJepoQs .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-oP91aw80mvJepoQs .cluster-label text{fill:#333;}#mermaid-svg-oP91aw80mvJepoQs .cluster-label span{color:#333;}#mermaid-svg-oP91aw80mvJepoQs .cluster-label span p{background-color:transparent;}#mermaid-svg-oP91aw80mvJepoQs .label text,#mermaid-svg-oP91aw80mvJepoQs span{fill:#333;color:#333;}#mermaid-svg-oP91aw80mvJepoQs .node rect,#mermaid-svg-oP91aw80mvJepoQs .node circle,#mermaid-svg-oP91aw80mvJepoQs .node ellipse,#mermaid-svg-oP91aw80mvJepoQs .node polygon,#mermaid-svg-oP91aw80mvJepoQs .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-oP91aw80mvJepoQs .rough-node .label text,#mermaid-svg-oP91aw80mvJepoQs .node .label text,#mermaid-svg-oP91aw80mvJepoQs .image-shape .label,#mermaid-svg-oP91aw80mvJepoQs .icon-shape .label{text-anchor:middle;}#mermaid-svg-oP91aw80mvJepoQs .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-oP91aw80mvJepoQs .rough-node .label,#mermaid-svg-oP91aw80mvJepoQs .node .label,#mermaid-svg-oP91aw80mvJepoQs .image-shape .label,#mermaid-svg-oP91aw80mvJepoQs .icon-shape .label{text-align:center;}#mermaid-svg-oP91aw80mvJepoQs .node.clickable{cursor:pointer;}#mermaid-svg-oP91aw80mvJepoQs .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-oP91aw80mvJepoQs .arrowheadPath{fill:#333333;}#mermaid-svg-oP91aw80mvJepoQs .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-oP91aw80mvJepoQs .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-oP91aw80mvJepoQs .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-oP91aw80mvJepoQs .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-oP91aw80mvJepoQs .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-oP91aw80mvJepoQs .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-oP91aw80mvJepoQs .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-oP91aw80mvJepoQs .cluster text{fill:#333;}#mermaid-svg-oP91aw80mvJepoQs .cluster span{color:#333;}#mermaid-svg-oP91aw80mvJepoQs div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-oP91aw80mvJepoQs .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-oP91aw80mvJepoQs rect.text{fill:none;stroke-width:0;}#mermaid-svg-oP91aw80mvJepoQs .icon-shape,#mermaid-svg-oP91aw80mvJepoQs .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-oP91aw80mvJepoQs .icon-shape p,#mermaid-svg-oP91aw80mvJepoQs .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-oP91aw80mvJepoQs .icon-shape .label rect,#mermaid-svg-oP91aw80mvJepoQs .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-oP91aw80mvJepoQs .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-oP91aw80mvJepoQs .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-oP91aw80mvJepoQs :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    syscall执行后

    TSS中的关键信息

    syscall相关MSR配置

    MSR_LSTAR (0xC0000082)= KiSystemCall64地址syscall跳转目标

    MSR_STAR (0xC0000081)[63:48] = 0x002B (用户CS)[47:32] = 0x0010 (内核CS)syscall后: CS=0x0010, SS=0x0018sysret后: CS=0x002B, SS=0x0023

    MSR_SFMASK (0xC0000084)= IF|TFsyscall时清除的标志位

    MSR_CSTAR (0xC0000083)= KiSystemCall32地址32位兼容模式入口

    RSP0 (offset 0x04)内核栈指针syscall时加载到RSP

    CS = 0x0010 (Ring0)

    SS = 0x0018 (Ring0)

    RSP = TSS.RSP0 (内核栈)

    RIP = MSR_LSTAR (KiSystemCall64)

    RCX = 用户态RIP (返回地址)

    R11 = 用户态RFLAGS

    IF = 0 (中断禁用)

    2.7 中断/异常作为切换触发点

    除了syscall外,中断和异常也会触发Ring 3到Ring 0的切换。这些场景包括:

  • 硬件中断:时钟中断(IRQ0)、网卡中断、键盘中断等

  • CPU异常:

    • 缺页异常(#PF, 0x0E):访问未映射或权限不足的地址
    • 通用保护故障(#GP, 0x0D):执行特权指令或访问违规段
    • 除零错误(#DE, 0x00)
    • 栈段故障(#SS, 0x0C)
    • 断点异常(#BP, 0x03):INT 3指令
    • 单步异常(#DB, 0x01):TF标志位为1时
  • 软件中断:INT n指令(如INT 0x2E,旧的系统调用机制)

  • 当CPU在Ring 3执行时收到中断/异常,CPU硬件会自动完成以下操作:

  • 从IDT中查找对应中断号的门描述符
  • 验证门描述符的DPL(对于软件中断,需CPL <= DPL)
  • 比较门描述符的目标段DPL与当前CPL
  • 如果目标段DPL < CPL(需要提权),进行栈切换
  • 从TSS读取新的RSP(对应目标特权级的栈)
  • 保存用户态SS:RSP、RFLAGS、CS:RIP到内核栈
  • 加载新的CS:RIP(中断处理程序入口)
  • 修改CPL到目标特权级
  • #mermaid-svg-8ZmIyzUFn8VnpoLh{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-8ZmIyzUFn8VnpoLh .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-8ZmIyzUFn8VnpoLh .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-8ZmIyzUFn8VnpoLh .error-icon{fill:#552222;}#mermaid-svg-8ZmIyzUFn8VnpoLh .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-8ZmIyzUFn8VnpoLh .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-8ZmIyzUFn8VnpoLh .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-8ZmIyzUFn8VnpoLh .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-8ZmIyzUFn8VnpoLh .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-8ZmIyzUFn8VnpoLh .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-8ZmIyzUFn8VnpoLh .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-8ZmIyzUFn8VnpoLh .marker{fill:#333333;stroke:#333333;}#mermaid-svg-8ZmIyzUFn8VnpoLh .marker.cross{stroke:#333333;}#mermaid-svg-8ZmIyzUFn8VnpoLh svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-8ZmIyzUFn8VnpoLh p{margin:0;}#mermaid-svg-8ZmIyzUFn8VnpoLh .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-8ZmIyzUFn8VnpoLh .cluster-label text{fill:#333;}#mermaid-svg-8ZmIyzUFn8VnpoLh .cluster-label span{color:#333;}#mermaid-svg-8ZmIyzUFn8VnpoLh .cluster-label span p{background-color:transparent;}#mermaid-svg-8ZmIyzUFn8VnpoLh .label text,#mermaid-svg-8ZmIyzUFn8VnpoLh span{fill:#333;color:#333;}#mermaid-svg-8ZmIyzUFn8VnpoLh .node rect,#mermaid-svg-8ZmIyzUFn8VnpoLh .node circle,#mermaid-svg-8ZmIyzUFn8VnpoLh .node ellipse,#mermaid-svg-8ZmIyzUFn8VnpoLh .node polygon,#mermaid-svg-8ZmIyzUFn8VnpoLh .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-8ZmIyzUFn8VnpoLh .rough-node .label text,#mermaid-svg-8ZmIyzUFn8VnpoLh .node .label text,#mermaid-svg-8ZmIyzUFn8VnpoLh .image-shape .label,#mermaid-svg-8ZmIyzUFn8VnpoLh .icon-shape .label{text-anchor:middle;}#mermaid-svg-8ZmIyzUFn8VnpoLh .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-8ZmIyzUFn8VnpoLh .rough-node .label,#mermaid-svg-8ZmIyzUFn8VnpoLh .node .label,#mermaid-svg-8ZmIyzUFn8VnpoLh .image-shape .label,#mermaid-svg-8ZmIyzUFn8VnpoLh .icon-shape .label{text-align:center;}#mermaid-svg-8ZmIyzUFn8VnpoLh .node.clickable{cursor:pointer;}#mermaid-svg-8ZmIyzUFn8VnpoLh .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-8ZmIyzUFn8VnpoLh .arrowheadPath{fill:#333333;}#mermaid-svg-8ZmIyzUFn8VnpoLh .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-8ZmIyzUFn8VnpoLh .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-8ZmIyzUFn8VnpoLh .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8ZmIyzUFn8VnpoLh .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-8ZmIyzUFn8VnpoLh .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8ZmIyzUFn8VnpoLh .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-8ZmIyzUFn8VnpoLh .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-8ZmIyzUFn8VnpoLh .cluster text{fill:#333;}#mermaid-svg-8ZmIyzUFn8VnpoLh .cluster span{color:#333;}#mermaid-svg-8ZmIyzUFn8VnpoLh div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-8ZmIyzUFn8VnpoLh .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-8ZmIyzUFn8VnpoLh rect.text{fill:none;stroke-width:0;}#mermaid-svg-8ZmIyzUFn8VnpoLh .icon-shape,#mermaid-svg-8ZmIyzUFn8VnpoLh .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8ZmIyzUFn8VnpoLh .icon-shape p,#mermaid-svg-8ZmIyzUFn8VnpoLh .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-8ZmIyzUFn8VnpoLh .icon-shape .label rect,#mermaid-svg-8ZmIyzUFn8VnpoLh .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8ZmIyzUFn8VnpoLh .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-8ZmIyzUFn8VnpoLh .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-8ZmIyzUFn8VnpoLh :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    中断/异常触发的Ring3→Ring0切换

    违反

    通过/硬件中断

    否, 同级

    是, 需提权

    中断/异常发生(如时钟中断/缺页)

    CPU查IDTIDTR指向IDT基址用中断号索引

    读取门描述符(中断门/陷阱门)

    是软件中断?检查CPL<=DPL

    触发 #GP

    目标CS.DPL < CPL?需提权?

    同级中断处理不切换栈直接压入RFLAGS/CS/RIP

    栈切换!1.从TSS读取RSP02.保存用户SS:RSP3.加载内核RSP

    保存上下文到内核栈SS(用户) -> RSP(用户) -> RFLAGS -> CS(用户) -> RIP(用户)

    加载新CS:RIP(中断处理程序入口)CPL=0

    执行中断处理程序

    2.8 x86与x64地址空间对比

    特性x86 (32位)x64 (64位)
    虚拟地址宽度 32位 (4GB) 48位 (256TB)
    用户态范围 0x00000000-0x7FFFFFFF (2GB) 0x0000000000000000-0x00007FFFFFFFFFFF (128TB)
    内核态范围 0x80000000-0xFFFFFFFF (2GB) 0xFFFF000000000000-0xFFFFFFFFFFFFFFFF (128TB)
    分界标志 /3GB可调整为3GB用户/1GB内核 固定为对半分
    KUSER_SHARED_DATA(用户态) 0x7FFE0000 0x00007FFE0000
    KUSER_SHARED_DATA(内核态) 0xFFDF0000 0xFFFFF78000000000
    页表自映射 0xC0000000 0xFFFFF68000000000
    页表层级 2级(PD+PT) 4级(PML4+PDPT+PD+PT)

    3. Ring3到Ring0的切换机制

    3.1 syscall指令的硬件执行流程

    syscall指令是AMD在AMD64架构中引入的快速系统调用机制,Intel在后续处理器中也采用了该指令。它是x64平台上Windows/Linux系统调用的主要路径。

    当CPU执行syscall指令时,硬件按以下步骤操作:

    步骤1:保存用户态返回地址

    RCX ← RIP + 1(syscall下一条指令的地址,即返回地址)

    CPU将syscall指令之后的下一条指令地址存入RCX寄存器。注意,sysret返回时会从RCX恢复RIP。

    步骤2:保存用户态RFLAGS

    R11 ← RFLAGS

    CPU将当前的RFLAGS(标志寄存器)保存到R11中,因为下一步要修改RFLAGS。

    步骤3:修改RFLAGS

    RFLAGS ← RFLAGS AND (NOT MSR_SFMASK)

    CPU用SFMASK(MSR 0xC0000084)对RFLAGS进行掩码操作,清除指定的标志位。通常清除:

    • IF(Interrupt Flag, bit 9):禁用中断,确保系统调用入口的原子性
    • TF(Trap Flag, bit 8):禁用单步调试,防止在内核入口被调试器中断

    步骤4:切换CS和SS(修改CPL)

    CS ← MSR_STAR[47:32] = 0x0010 (内核代码段, DPL=0)
    SS ← MSR_STAR[47:32] + 8 = 0x0018 (内核数据段, DPL=0)

    CPU从STAR寄存器读取段选择子,将CS设置为内核代码段(CPL变为0),SS设置为内核数据段。注意,syscall指令不检查GDT中的段描述符,而是直接使用STAR寄存器中的选择子——这就是它快速的原因。

    步骤5:切换到内核栈

    RSP ← TSS.RSP0 (从TSS中读取Ring 0的栈指针)

    CPU从当前TSS(Task State Segment)的RSP0字段读取内核栈指针,加载到RSP。此时用户态的RSP值尚未保存到内核栈上——这由后续的软件代码完成。

    步骤6:跳转到内核入口

    RIP ← MSR_LSTAR (从LSTAR读取内核系统调用入口地址)

    CPU从LSTAR寄存器(MSR 0xC0000082)读取入口地址,跳转到该地址执行。在Windows x64中,此地址指向KiSystemCall64。

    内核入口

    TSS

    MSR寄存器

    CPU硬件

    用户态代码

    内核入口

    TSS

    MSR寄存器

    CPU硬件

    用户态代码

    #mermaid-svg-1qIRi2IIMsxJgZAv{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-1qIRi2IIMsxJgZAv .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-1qIRi2IIMsxJgZAv .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-1qIRi2IIMsxJgZAv .error-icon{fill:#552222;}#mermaid-svg-1qIRi2IIMsxJgZAv .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-1qIRi2IIMsxJgZAv .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-1qIRi2IIMsxJgZAv .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-1qIRi2IIMsxJgZAv .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-1qIRi2IIMsxJgZAv .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-1qIRi2IIMsxJgZAv .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-1qIRi2IIMsxJgZAv .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-1qIRi2IIMsxJgZAv .marker{fill:#333333;stroke:#333333;}#mermaid-svg-1qIRi2IIMsxJgZAv .marker.cross{stroke:#333333;}#mermaid-svg-1qIRi2IIMsxJgZAv svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-1qIRi2IIMsxJgZAv p{margin:0;}#mermaid-svg-1qIRi2IIMsxJgZAv .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-1qIRi2IIMsxJgZAv text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-1qIRi2IIMsxJgZAv .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-1qIRi2IIMsxJgZAv .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-1qIRi2IIMsxJgZAv .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-1qIRi2IIMsxJgZAv .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-1qIRi2IIMsxJgZAv #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-1qIRi2IIMsxJgZAv .sequenceNumber{fill:white;}#mermaid-svg-1qIRi2IIMsxJgZAv #sequencenumber{fill:#333;}#mermaid-svg-1qIRi2IIMsxJgZAv #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-1qIRi2IIMsxJgZAv .messageText{fill:#333;stroke:none;}#mermaid-svg-1qIRi2IIMsxJgZAv .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-1qIRi2IIMsxJgZAv .labelText,#mermaid-svg-1qIRi2IIMsxJgZAv .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-1qIRi2IIMsxJgZAv .loopText,#mermaid-svg-1qIRi2IIMsxJgZAv .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-1qIRi2IIMsxJgZAv .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-1qIRi2IIMsxJgZAv .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-1qIRi2IIMsxJgZAv .noteText,#mermaid-svg-1qIRi2IIMsxJgZAv .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-1qIRi2IIMsxJgZAv .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-1qIRi2IIMsxJgZAv .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-1qIRi2IIMsxJgZAv .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-1qIRi2IIMsxJgZAv .actorPopupMenu{position:absolute;}#mermaid-svg-1qIRi2IIMsxJgZAv .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-1qIRi2IIMsxJgZAv .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-1qIRi2IIMsxJgZAv .actor-man circle,#mermaid-svg-1qIRi2IIMsxJgZAv line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-1qIRi2IIMsxJgZAv :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    步骤1: 保存返回地址

    步骤2: 保存RFLAGS

    步骤3: 修改RFLAGS

    IF=0 (中断禁用), TF=0

    步骤4: 切换CS/SS (CPL 3→0)

    CPL现在是0!

    步骤5: 切换到内核栈

    步骤6: 跳转

    mov r10, RCX (保存第4参数)

    mov eax, syscall_number

    执行 syscall 指令

    RCX ← RIP (syscall下一条指令)

    R11 ← RFLAGS

    读取 SFMASK (0xC0000084)

    SFMASK值

    RFLAGS ← RFLAGS AND NOT SFMASK

    读取 STAR (0xC0000081)

    STAR[47:32] = 0x0010

    CS ← 0x0010 (Ring0代码段)

    SS ← 0x0018 (Ring0数据段)

    读取 RSP0

    内核栈指针

    RSP ← 内核栈指针

    读取 LSTAR (0xC0000082)

    KiSystemCall64地址

    RIP ← KiSystemCall64

    KiSystemCall64 开始执行

    保存用户态RSP到内核栈

    保存用户态寄存器

    查找SSDT, 调用系统服务

    执行 sysret 返回

    3.2 KiSystemCall64入口代码详解

    KiSystemCall64是Windows x64上所有系统调用的统一入口。以下是其核心逻辑的反汇编/伪代码分析:

    // KiSystemCall64 – Windows x64系统调用入口
    // 这是整个操作系统最关键的代码路径之一
    // 每次API调用都会经过这里

    // 反汇编伪代码(基于Windows 10/11 x64)
    KiSystemCall64:
    // ===== 硬件已完成的工作 =====
    // RCX = 用户态返回地址 (RIP)
    // R11 = 用户态RFLAGS
    // RSP = 内核栈 (来自TSS.RSP0)
    // CS = 0x0010 (Ring0)
    // SS = 0x0018 (Ring0)
    // RAX = 系统调用号
    // IF = 0 (中断已禁用)

    // ===== 软件保存用户态上下文 =====

    // 1. 交换用户态RSP到内核栈
    // 此时RSP指向内核栈顶
    // RCX是用户态返回地址
    // 需要保存用户态的RSP

    // 关键: 使用swapgs切换GS基址
    // 用户态: GS指向用户态TEB
    // 内核态: GS需要指向KPCR
    swapgs // 切换GS到内核态 (KPCR)

    // 此时 GS:[0] = 当前KPCR

    // 2. 保存用户态RSP
    // 将用户态RSP保存到KPCR中
    mov gs:[0x500], rsp // 保存用户态RSP到KPCR.UserRsp

    // 3. 建立内核栈帧
    // 在内核栈上保存trap frame
    sub rsp, 0x158 // 分配KTRAP_FRAME空间

    // 4. 保存通用寄存器
    // 按照KTRAP_FRAME的布局保存
    mov [rsp+0x000], rbp // 保存RBP
    mov [rsp+0x008], rdi // 保存RDI
    mov [rsp+0x010], rsi // 保存RSI
    mov [rsp+0x018], rbx // 保存RBX
    mov [rsp+0x020], rdx // 保存RDX (第2参数)
    mov [rsp+0x028], r12 // 保存R12
    mov [rsp+0x030], r13 // 保存R13
    mov [rsp+0x038], r14 // 保存R14
    mov [rsp+0x040], r15 // 保存R15

    // 5. 保存用户态段寄存器
    // (x64中段寄存器通常固定,但仍保存)
    mov [rsp+0x048], cs // 用户态CS (0x002B)
    mov [rsp+0x050], ds // 用户态DS
    mov [rsp+0x058], es // 用户态ES
    mov [rsp+0x060], fs // 用户态FS
    mov [rsp+0x068], gs // 用户态GS (已是内核GS)

    // 6. 保存RFLAGS和返回地址
    // R11包含用户态RFLAGS
    // RCX包含用户态RIP
    mov [rsp+0x080], r11 // 用户态RFLAGS
    mov [rsp+0x088], rcx // 用户态RIP (返回地址)

    // 7. 检查是否需要调试支持
    // 如果用户态RFLAGS.TF=1, 需要设置单步陷阱
    test dword ptr [rsp+0x080], 0x100 // 检查TF标志
    jnz KiSystemServiceTrapFrame // 需要完整trap frame

    // 8. 正常路径: 快速路径
    // 保存用户态栈指针信息
    // gs:[0x500]已经保存了用户态RSP

    // 9. 设置段寄存器为内核值
    mov cx, KGDT64_R3_DATA // 0x002B
    mov ds, cx
    mov es, cx

    // 10. 开启中断
    // 现在trap frame已建立, 可以安全响应中断
    sti

    // 11. 调用系统服务分发
    // RAX = 系统调用号
    // RCX = 第1参数 (已被syscall保存为返回地址,
    // ntdll在syscall前将RCX移到R10)
    // R10 = 第1参数 (实际值)
    // RDX = 第2参数
    // R8 = 第3参数
    // R9 = 第4参数

    // 跳转到KiSystemServiceRepeat
    jmp KiSystemServiceRepeat

    3.3 sysret指令的返回流程

    sysret指令执行从Ring 0返回Ring 3的逆过程。其硬件流程如下:

    步骤1:恢复RIP

    RIP ← RCX (RCX应包含用户态返回地址)

    步骤2:恢复RFLAGS

    RFLAGS ← R11 (R11应包含用户态RFLAGS)

    步骤3:切换CS和SS(修改CPL回到3)

    CS ← MSR_STAR[63:48] + 0 = 0x002B (用户代码段, DPL=3)
    SS ← MSR_STAR[63:48] + 8 = 0x0023 (用户数据段, DPL=3)

    步骤4:CPL变为3

    CPU将CPL从0切换为3,此后执行的代码处于Ring 3。

    注意: sysret指令不自动恢复用户态RSP。内核代码在执行sysret前必须手动将RSP设置回用户态栈指针。同样,sysret不自动恢复用户态GS——内核代码需要先执行swapgs切回用户态GS。

    // KiSystemServiceExit – 系统调用返回路径
    // 在执行sysret之前完成所有恢复工作

    KiSystemServiceExit:
    // 1. 关闭中断 (确保恢复过程的原子性)
    cli

    // 2. 恢复通用寄存器
    mov r15, [rsp+0x040]
    mov r14, [rsp+0x038]
    mov r13, [rsp+0x030]
    mov r12, [rsp+0x028]
    mov rdx, [rsp+0x020]
    mov rbx, [rsp+0x018]
    mov rsi, [rsp+0x010]
    mov rdi, [rsp+0x008]
    mov rbp, [rsp+0x000]

    // 3. 恢复用户态返回地址和RFLAGS
    mov rcx, [rsp+0x088] // 用户态RIP -> RCX (sysret会用到)
    mov r11, [rsp+0x080] // 用户态RFLAGS -> R11 (sysret会用到)

    // 4. 恢复用户态RSP
    mov rsp, gs:[0x500] // 从KPCR恢复用户态RSP

    // 5. 切换GS回用户态
    swapgs // GS从KPCR切回用户态TEB

    // 6. 执行sysret返回用户态
    // CPU将:
    // – RIP ← RCX (用户态返回地址)
    // – RFLAGS ← R11 (用户态标志)
    // – CS ← 0x002B (Ring3)
    // – SS ← 0x0023 (Ring3)
    // – CPL = 3
    sysret

    用户态代码

    TSS

    MSR寄存器

    CPU硬件

    内核代码

    用户态代码

    TSS

    MSR寄存器

    CPU硬件

    内核代码

    #mermaid-svg-y0Sd1wLhTgD6iWBK{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-y0Sd1wLhTgD6iWBK .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-y0Sd1wLhTgD6iWBK .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-y0Sd1wLhTgD6iWBK .error-icon{fill:#552222;}#mermaid-svg-y0Sd1wLhTgD6iWBK .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-y0Sd1wLhTgD6iWBK .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-y0Sd1wLhTgD6iWBK .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-y0Sd1wLhTgD6iWBK .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-y0Sd1wLhTgD6iWBK .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-y0Sd1wLhTgD6iWBK .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-y0Sd1wLhTgD6iWBK .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-y0Sd1wLhTgD6iWBK .marker{fill:#333333;stroke:#333333;}#mermaid-svg-y0Sd1wLhTgD6iWBK .marker.cross{stroke:#333333;}#mermaid-svg-y0Sd1wLhTgD6iWBK svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-y0Sd1wLhTgD6iWBK p{margin:0;}#mermaid-svg-y0Sd1wLhTgD6iWBK .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-y0Sd1wLhTgD6iWBK text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-y0Sd1wLhTgD6iWBK .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-y0Sd1wLhTgD6iWBK .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-y0Sd1wLhTgD6iWBK .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-y0Sd1wLhTgD6iWBK .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-y0Sd1wLhTgD6iWBK #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-y0Sd1wLhTgD6iWBK .sequenceNumber{fill:white;}#mermaid-svg-y0Sd1wLhTgD6iWBK #sequencenumber{fill:#333;}#mermaid-svg-y0Sd1wLhTgD6iWBK #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-y0Sd1wLhTgD6iWBK .messageText{fill:#333;stroke:none;}#mermaid-svg-y0Sd1wLhTgD6iWBK .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-y0Sd1wLhTgD6iWBK .labelText,#mermaid-svg-y0Sd1wLhTgD6iWBK .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-y0Sd1wLhTgD6iWBK .loopText,#mermaid-svg-y0Sd1wLhTgD6iWBK .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-y0Sd1wLhTgD6iWBK .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-y0Sd1wLhTgD6iWBK .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-y0Sd1wLhTgD6iWBK .noteText,#mermaid-svg-y0Sd1wLhTgD6iWBK .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-y0Sd1wLhTgD6iWBK .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-y0Sd1wLhTgD6iWBK .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-y0Sd1wLhTgD6iWBK .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-y0Sd1wLhTgD6iWBK .actorPopupMenu{position:absolute;}#mermaid-svg-y0Sd1wLhTgD6iWBK .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-y0Sd1wLhTgD6iWBK .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-y0Sd1wLhTgD6iWBK .actor-man circle,#mermaid-svg-y0Sd1wLhTgD6iWBK line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-y0Sd1wLhTgD6iWBK :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    步骤1: 恢复RIP

    步骤2: 恢复RFLAGS

    步骤3: 切换CS/SS (CPL 0→3)

    CPL现在是3!

    步骤4: 继续执行

    应用程序恢复运行

    RAX = 系统调用返回值

    cli (关中断)

    恢复通用寄存器

    RCX ← 用户态RIP (从trap frame)

    R11 ← 用户态RFLAGS (从trap frame)

    RSP ← 用户态RSP (从KPCR)

    swapgs (GS: KPCR → 用户TEB)

    执行 sysret

    RIP ← RCX

    RFLAGS ← R11

    读取 STAR[63:48]

    0x002B

    CS ← 0x002B (Ring3代码段)

    SS ← 0x0023 (Ring3数据段)

    从用户态RIP继续执行

    3.4 sysenter/sysexit(旧机制)

    sysenter/sysexit是Intel在Pentium II中引入的快速系统调用机制,用于替代int 0x2E。在x64平台上,它仍可用于32位兼容模式(WoW64)的系统调用。

    sysenter使用的MSR寄存器:

    MSR地址名称用途
    0x174 SYSENTER_CS CS选择子基址
    0x175 SYSENTER_ESP 内核栈指针
    0x176 SYSENTER_EIP 内核入口地址

    // sysenter的硬件流程(伪代码)
    void sysenter_flow(void)
    {
    // 1. 从MSR读取CS
    CS ← MSR_SYSENTER_CS; // 内核代码段
    SS ← MSR_SYSENTER_CS + 8; // 内核数据段
    // 2. 从MSR读取栈指针
    RSP ← MSR_SYSENTER_ESP; // 内核栈
    // 3. 从MSR读取入口地址
    RIP ← MSR_SYSENTER_EIP; // KiFastCallEntry
    // 4. CPL = 0
    // 注意: sysenter不保存任何寄存器!
    // 不保存返回地址、RFLAGS、用户RSP
    // 这些全部由软件处理
    }

    sysenter的关键缺陷:

    • 不保存返回地址(需软件保存到RCX/EDX)
    • 不保存RFLAGS(需软件保存)
    • 不保存用户态RSP(需软件保存)
    • 不自动切换GS(需软件swapgs)
    • 这些软件操作增加了开销

    #mermaid-svg-B4U2lAi1NsOaZvUj{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-B4U2lAi1NsOaZvUj .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-B4U2lAi1NsOaZvUj .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-B4U2lAi1NsOaZvUj .error-icon{fill:#552222;}#mermaid-svg-B4U2lAi1NsOaZvUj .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-B4U2lAi1NsOaZvUj .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-B4U2lAi1NsOaZvUj .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-B4U2lAi1NsOaZvUj .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-B4U2lAi1NsOaZvUj .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-B4U2lAi1NsOaZvUj .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-B4U2lAi1NsOaZvUj .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-B4U2lAi1NsOaZvUj .marker{fill:#333333;stroke:#333333;}#mermaid-svg-B4U2lAi1NsOaZvUj .marker.cross{stroke:#333333;}#mermaid-svg-B4U2lAi1NsOaZvUj svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-B4U2lAi1NsOaZvUj p{margin:0;}#mermaid-svg-B4U2lAi1NsOaZvUj .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-B4U2lAi1NsOaZvUj .cluster-label text{fill:#333;}#mermaid-svg-B4U2lAi1NsOaZvUj .cluster-label span{color:#333;}#mermaid-svg-B4U2lAi1NsOaZvUj .cluster-label span p{background-color:transparent;}#mermaid-svg-B4U2lAi1NsOaZvUj .label text,#mermaid-svg-B4U2lAi1NsOaZvUj span{fill:#333;color:#333;}#mermaid-svg-B4U2lAi1NsOaZvUj .node rect,#mermaid-svg-B4U2lAi1NsOaZvUj .node circle,#mermaid-svg-B4U2lAi1NsOaZvUj .node ellipse,#mermaid-svg-B4U2lAi1NsOaZvUj .node polygon,#mermaid-svg-B4U2lAi1NsOaZvUj .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-B4U2lAi1NsOaZvUj .rough-node .label text,#mermaid-svg-B4U2lAi1NsOaZvUj .node .label text,#mermaid-svg-B4U2lAi1NsOaZvUj .image-shape .label,#mermaid-svg-B4U2lAi1NsOaZvUj .icon-shape .label{text-anchor:middle;}#mermaid-svg-B4U2lAi1NsOaZvUj .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-B4U2lAi1NsOaZvUj .rough-node .label,#mermaid-svg-B4U2lAi1NsOaZvUj .node .label,#mermaid-svg-B4U2lAi1NsOaZvUj .image-shape .label,#mermaid-svg-B4U2lAi1NsOaZvUj .icon-shape .label{text-align:center;}#mermaid-svg-B4U2lAi1NsOaZvUj .node.clickable{cursor:pointer;}#mermaid-svg-B4U2lAi1NsOaZvUj .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-B4U2lAi1NsOaZvUj .arrowheadPath{fill:#333333;}#mermaid-svg-B4U2lAi1NsOaZvUj .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-B4U2lAi1NsOaZvUj .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-B4U2lAi1NsOaZvUj .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-B4U2lAi1NsOaZvUj .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-B4U2lAi1NsOaZvUj .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-B4U2lAi1NsOaZvUj .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-B4U2lAi1NsOaZvUj .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-B4U2lAi1NsOaZvUj .cluster text{fill:#333;}#mermaid-svg-B4U2lAi1NsOaZvUj .cluster span{color:#333;}#mermaid-svg-B4U2lAi1NsOaZvUj div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-B4U2lAi1NsOaZvUj .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-B4U2lAi1NsOaZvUj rect.text{fill:none;stroke-width:0;}#mermaid-svg-B4U2lAi1NsOaZvUj .icon-shape,#mermaid-svg-B4U2lAi1NsOaZvUj .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-B4U2lAi1NsOaZvUj .icon-shape p,#mermaid-svg-B4U2lAi1NsOaZvUj .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-B4U2lAi1NsOaZvUj .icon-shape .label rect,#mermaid-svg-B4U2lAi1NsOaZvUj .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-B4U2lAi1NsOaZvUj .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-B4U2lAi1NsOaZvUj .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-B4U2lAi1NsOaZvUj :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    系统调用机制对比

    演进

    演进

    INT 0x2E最旧机制开销: ~200-300 cycles通过IDT查表完整中断门流程

    SYSENTER/SYSEXITIntel Pentium II+开销: ~100-150 cycles通过MSR读取入口不保存上下文(软件处理)

    SYSCALL/SYSRETAMD64 (x64标准)开销: ~50-100 cycles通过MSR读取入口自动保存RIP(RCX)和RFLAGS(R11)

    3.5 INT 0x2E(最旧机制)

    在Windows 2000/XP时代(x86),系统调用通过int 0x2E软件中断实现。这种方式通过IDT中的中断门进行特权级切换。

    // INT 0x2E 的执行流程

    // 用户态:
    // ntdll.dll中的系统调用stub
    __declspec(naked) void NtCreateFile_stub(void)
    {
    mov eax, syscall_number // 系统调用号放入EAX
    mov edx, KiFastSystemCall // 或直接使用 int 0x2E
    // 旧方式:
    int 0x2E // 触发软件中断
    ret argument_count // 返回, 清理栈
    }

    // CPU处理int 0x2E的流程:
    // 1. 查IDT[0x2E], 获取中断门描述符
    // 2. 中断门DPL=3 (允许用户态调用)
    // 3. 目标CS.DPL=0 (需要提权)
    // 4. 栈切换: 从TSS读取SS0:ESP0
    // 5. 压栈顺序: SS(用户), ESP(用户), EFLAGS, CS(用户), EIP(用户)
    // 6. 加载内核CS:EIP (KiSystemService)
    // 7. CPL = 0

    // 内核入口 (旧):
    KiSystemService:
    // ESP指向内核栈, 上方依次是:
    // [ESP+0x00] 返回EIP (用户态)
    // [ESP+0x04] 用户态CS
    // [ESP+0x08] 用户态EFLAGS
    // [ESP+0x0C] 用户态ESP
    // [ESP+0x10] 用户态SS

    push ds
    push es
    push fs
    push ebp
    push edi
    push esi
    push ebx
    push edx // 用户态ESP (某些版本)
    push ecx
    push eax // 系统调用号

    // … 保存上下文, 分发系统调用 …

    INT 0x2E相比syscall的开销:

    开销来源INT 0x2ESYSCALL
    IDT内存访问 需要(查表) 不需要
    中断门权限检查 需要(DPL检查) 不需要
    RFLAGS保存 自动压栈 自动到R11
    栈切换信息 从TSS读取 从TSS读取
    总周期数 ~200-300 ~50-100
    TLB影响 可能 可能

    3.6 WoW64的系统调用路径

    在x64 Windows上运行32位应用程序时(WoW64, Windows on Windows 64),系统调用需要额外的转换层:

    #mermaid-svg-vIdDAzQ5O5AtY3Eu{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-vIdDAzQ5O5AtY3Eu .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .error-icon{fill:#552222;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .marker{fill:#333333;stroke:#333333;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .marker.cross{stroke:#333333;}#mermaid-svg-vIdDAzQ5O5AtY3Eu svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-vIdDAzQ5O5AtY3Eu p{margin:0;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .cluster-label text{fill:#333;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .cluster-label span{color:#333;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .cluster-label span p{background-color:transparent;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .label text,#mermaid-svg-vIdDAzQ5O5AtY3Eu span{fill:#333;color:#333;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .node rect,#mermaid-svg-vIdDAzQ5O5AtY3Eu .node circle,#mermaid-svg-vIdDAzQ5O5AtY3Eu .node ellipse,#mermaid-svg-vIdDAzQ5O5AtY3Eu .node polygon,#mermaid-svg-vIdDAzQ5O5AtY3Eu .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .rough-node .label text,#mermaid-svg-vIdDAzQ5O5AtY3Eu .node .label text,#mermaid-svg-vIdDAzQ5O5AtY3Eu .image-shape .label,#mermaid-svg-vIdDAzQ5O5AtY3Eu .icon-shape .label{text-anchor:middle;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .rough-node .label,#mermaid-svg-vIdDAzQ5O5AtY3Eu .node .label,#mermaid-svg-vIdDAzQ5O5AtY3Eu .image-shape .label,#mermaid-svg-vIdDAzQ5O5AtY3Eu .icon-shape .label{text-align:center;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .node.clickable{cursor:pointer;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .arrowheadPath{fill:#333333;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-vIdDAzQ5O5AtY3Eu .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-vIdDAzQ5O5AtY3Eu .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-vIdDAzQ5O5AtY3Eu .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .cluster text{fill:#333;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .cluster span{color:#333;}#mermaid-svg-vIdDAzQ5O5AtY3Eu div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-vIdDAzQ5O5AtY3Eu rect.text{fill:none;stroke-width:0;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .icon-shape,#mermaid-svg-vIdDAzQ5O5AtY3Eu .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .icon-shape p,#mermaid-svg-vIdDAzQ5O5AtY3Eu .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .icon-shape .label rect,#mermaid-svg-vIdDAzQ5O5AtY3Eu .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-vIdDAzQ5O5AtY3Eu .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-vIdDAzQ5O5AtY3Eu .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-vIdDAzQ5O5AtY3Eu :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    WoW64 系统调用路径

    调用API

    far call 0x33:0x…切换到64位模式

    参数转换32→64位

    32位应用程序(Ring 3)

    ntdll32.dll(32位)

    wow64.dll/wow64cpu.dllCPU模拟层(64位Ring 3)

    ntdll.dll(64位)

    syscall指令(Ring 3→Ring 0)

    KiSystemCall64(Ring 0)

    WoW64的系统调用比原生64位调用多了一次模式切换(32位→64位)和参数转换,因此性能开销更大。Windows 10/11的某些版本对WoW64进行了优化(如"新WoW64"),减少了转换开销。

    3.7 系统调用号

    每个系统调用都有一个唯一的编号,称为系统调用号(System Call Number)。用户态通过将调用号放入EAX/RAX寄存器,然后执行syscall来指定要调用的系统服务。

    // ntdll.dll中的系统调用stub示例
    // 以下是一个典型的NtCreateFile调用stub

    // 64位ntdll.dll
    .code
    NtCreateFile proc
    mov r10, rcx ; 保存第1参数到r10 (syscall会用rcx)
    mov eax, 55h ; 系统调用号 0x55 = NtCreateFile
    ; 注意: 不同Windows版本调用号不同!
    syscall ; 进入内核
    ret ; 返回调用者
    NtCreateFile endp
    end

    // 32位ntdll.dll (旧版, 使用int 0x2E)
    .code
    _NtCreateFile@0 proc
    mov eax, 25h ; 32位系统调用号 (与64位不同)
    mov edx, esp ; 保存用户栈指针
    sysenter ; 快速系统调用 (XP+)
    ret
    _NtCreateFile@0 endp
    end

    系统调用号的变化:

    系统调用号不是固定的,每个Windows版本(甚至每个Build)都可能不同:

    Windows版本NtCreateFile调用号(x64)说明
    Windows 7 SP1 0x53 原始值
    Windows 8.1 0x54 +1
    Windows 10 1507 0x55 +1
    Windows 10 1809 0x55 未变
    Windows 10 1903 0x55 未变
    Windows 11 22000 0x55 未变(近期稳定)

    由于调用号可能变化,用户态程序应始终通过ntdll.dll调用系统服务,而不应硬编码调用号。

    3.8 系统调用的参数传递

    x64 Windows系统调用的参数传递遵循Microsoft x64 Calling Convention:

    参数位置寄存器说明
    系统调用号 RAX 指定要调用的系统服务
    第1参数 RCX → R10 syscall前ntdll将RCX移到R10
    第2参数 RDX 直接传递
    第3参数 R8 直接传递
    第4参数 R9 直接传递
    第5+参数 内核栈 由内核从用户栈复制

    #mermaid-svg-xgnQezAMUDHqSQHn{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-xgnQezAMUDHqSQHn .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-xgnQezAMUDHqSQHn .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-xgnQezAMUDHqSQHn .error-icon{fill:#552222;}#mermaid-svg-xgnQezAMUDHqSQHn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-xgnQezAMUDHqSQHn .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-xgnQezAMUDHqSQHn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-xgnQezAMUDHqSQHn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-xgnQezAMUDHqSQHn .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-xgnQezAMUDHqSQHn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-xgnQezAMUDHqSQHn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-xgnQezAMUDHqSQHn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-xgnQezAMUDHqSQHn .marker.cross{stroke:#333333;}#mermaid-svg-xgnQezAMUDHqSQHn svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-xgnQezAMUDHqSQHn p{margin:0;}#mermaid-svg-xgnQezAMUDHqSQHn .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-xgnQezAMUDHqSQHn .cluster-label text{fill:#333;}#mermaid-svg-xgnQezAMUDHqSQHn .cluster-label span{color:#333;}#mermaid-svg-xgnQezAMUDHqSQHn .cluster-label span p{background-color:transparent;}#mermaid-svg-xgnQezAMUDHqSQHn .label text,#mermaid-svg-xgnQezAMUDHqSQHn span{fill:#333;color:#333;}#mermaid-svg-xgnQezAMUDHqSQHn .node rect,#mermaid-svg-xgnQezAMUDHqSQHn .node circle,#mermaid-svg-xgnQezAMUDHqSQHn .node ellipse,#mermaid-svg-xgnQezAMUDHqSQHn .node polygon,#mermaid-svg-xgnQezAMUDHqSQHn .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-xgnQezAMUDHqSQHn .rough-node .label text,#mermaid-svg-xgnQezAMUDHqSQHn .node .label text,#mermaid-svg-xgnQezAMUDHqSQHn .image-shape .label,#mermaid-svg-xgnQezAMUDHqSQHn .icon-shape .label{text-anchor:middle;}#mermaid-svg-xgnQezAMUDHqSQHn .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-xgnQezAMUDHqSQHn .rough-node .label,#mermaid-svg-xgnQezAMUDHqSQHn .node .label,#mermaid-svg-xgnQezAMUDHqSQHn .image-shape .label,#mermaid-svg-xgnQezAMUDHqSQHn .icon-shape .label{text-align:center;}#mermaid-svg-xgnQezAMUDHqSQHn .node.clickable{cursor:pointer;}#mermaid-svg-xgnQezAMUDHqSQHn .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-xgnQezAMUDHqSQHn .arrowheadPath{fill:#333333;}#mermaid-svg-xgnQezAMUDHqSQHn .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-xgnQezAMUDHqSQHn .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-xgnQezAMUDHqSQHn .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xgnQezAMUDHqSQHn .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-xgnQezAMUDHqSQHn .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xgnQezAMUDHqSQHn .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-xgnQezAMUDHqSQHn .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-xgnQezAMUDHqSQHn .cluster text{fill:#333;}#mermaid-svg-xgnQezAMUDHqSQHn .cluster span{color:#333;}#mermaid-svg-xgnQezAMUDHqSQHn div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-xgnQezAMUDHqSQHn .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-xgnQezAMUDHqSQHn rect.text{fill:none;stroke-width:0;}#mermaid-svg-xgnQezAMUDHqSQHn .icon-shape,#mermaid-svg-xgnQezAMUDHqSQHn .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xgnQezAMUDHqSQHn .icon-shape p,#mermaid-svg-xgnQezAMUDHqSQHn .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-xgnQezAMUDHqSQHn .icon-shape .label rect,#mermaid-svg-xgnQezAMUDHqSQHn .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xgnQezAMUDHqSQHn .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-xgnQezAMUDHqSQHn .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-xgnQezAMUDHqSQHn :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    内核态参数接收

    ntdll.dll stub

    用户态参数准备

    第1参数 → RCX

    第2参数 → RDX

    第3参数 → R8

    第4参数 → R9

    第5+参数 → 用户栈

    调用号 → EAX

    mov r10, rcx(保存第1参数)

    mov eax, syscall_num(设置调用号)

    syscall

    R10 = 第1参数

    RDX = 第2参数

    R8 = 第3参数

    R9 = 第4参数

    从用户栈复制第5+参数

    EAX = 系统调用号

    3.9 系统调用的完整调用链示例

    以CreateFileW API为例,完整调用链如下:

    应用程序代码
    │
    ├── CreateFileW(L"C:\\\\test.txt", GENERIC_READ, …)
    │ │ [kernel32.dll / KernelBase.dll]
    │ │ 将宽字符路径转为NT路径
    │ │ 填充OBJECT_ATTRIBUTES等结构
    │ │
    │ ├── NtCreateFile(&hFile, SYNCHRONIZE|GENERIC_READ, &oa, &iosb,
    │ │ NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
    │ │ FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0)
    │ │ [ntdll.dll]
    │ │ mov r10, rcx ; &hFile
    │ │ mov eax, 55h ; 系统调用号
    │ │ syscall ; ← 特权级切换点
    │ │
    │ ├── ┌─── syscall指令执行 ───┐
    │ │ │ RCX ← 返回地址(用户态RIP)
    │ │ │ R11 ← RFLAGS
    │ │ │ RFLAGS ← RFLAGS AND NOT SFMASK (IF=0)
    │ │ │ CS ← 0x0010 (Ring0)
    │ │ │ SS ← 0x0018 (Ring0)
    │ │ │ RSP ← TSS.RSP0 (内核栈)
    │ │ │ RIP ← KiSystemCall64
    │ │ └─────────────────────────┘
    │ │
    │ ├── KiSystemCall64 [ntoskrnl.exe]
    │ │ swapgs ; GS→KPCR
    │ │ 保存用户态RSP到KPCR
    │ │ 分配KTRAP_FRAME
    │ │ 保存寄存器
    │ │ sti ; 开中断
    │ │ → KiSystemServiceRepeat
    │ │
    │ ├── KiSystemServiceRepeat [ntoskrnl.exe]
    │ │ 从RAX提取系统调用号
    │ │ 查KeServiceDescriptorTable
    │ │ 获取NtCreateFile函数指针
    │ │ 获取参数数量
    │ │ 从用户栈复制额外参数
    │ │ → 调用NtCreateFile
    │ │
    │ ├── NtCreateFile [ntoskrnl.exe]
    │ │ 验证参数(ProbeForRead/Write)
    │ │ 捕获用户态参数
    │ │ → IoCreateFileEx / IopCreateFile
    │ │ → I/O管理器创建IRP
    │ │ → 文件系统驱动处理
    │ │ → 返回文件句柄
    │ │
    │ ├── KiSystemServiceExit [ntoskrnl.exe]
    │ │ cli ; 关中断
    │ │ 恢复寄存器
    │ │ RCX ← 用户态RIP
    │ │ R11 ← 用户态RFLAGS
    │ │ RSP ← 用户态RSP
    │ │ swapgs ; GS→用户TEB
    │ │ sysret ; ← 特权级切换回Ring3
    │ │
    │ └── [用户态恢复执行]
    │ RAX = NTSTATUS (成功/失败)
    │ ret
    │
    └── 返回HANDLE给应用程序


    4. 内核栈与用户栈的切换

    4.1 线程的内核栈分配

    每个Windows线程在创建时都会分配一个内核栈。内核栈用于线程在内核态执行时使用,包括系统调用、中断处理和异常处理。

    内核栈的类型:

    栈类型大小用途适用IRQL
    主内核栈 12KB (x64) / 16KB 系统调用、普通内核代码 < DISPATCH_LEVEL
    大内核栈 可增长到24KB+ 深度递归/大栈需求 < DISPATCH_LEVEL
    DPC栈 单独的DPC栈 DPC例程执行 DISPATCH_LEVEL
    中断栈 每CPU一个 高IRQL中断处理 > DISPATCH_LEVEL

    // 内核栈的分配(概念性代码)
    // 文件: ntoskrnl/ke/thrdobj.c (简化)

    NTSTATUS KeInitThread(
    PKTHREAD Thread,
    PVOID KernelStack,
    ...)
    {
    // 分配内核栈
    // x64: 通常12KB (3页), 16KB对齐
    // 栈底保留1页作为溢出保护页(guard page)

    ULONG KernelStackSize = KERNEL_STACK_SIZE; // 0x3000 = 12KB (x64)

    Thread->InitialStack = KernelStack;
    Thread->StackBase = KernelStack;
    Thread->StackLimit = (PUCHAR)KernelStack – KernelStackSize;

    // 初始内核栈顶
    // 栈从高地址向低地址增长
    Thread->KernelStack = (PVOID)((PUCHAR)KernelStack – sizeof(KTRAP_FRAME));

    // 设置TSS中的RSP0
    // 每次线程切换时, KiSwapContext会更新TSS.RSP0
    // TSS.RSP0 = Thread->InitialStack – 0x38 (为硬件留给栈帧)

    return STATUS_SUCCESS;
    }

    4.2 TSS中的RSP0字段

    x64架构中,TSS(Task State Segment)的结构大幅简化,不再用于硬件任务切换,但仍保留关键字段用于特权级切换时的栈切换。

    // x64 TSS结构 (KTSS)
    typedef struct _KTSS64 {
    ULONG Reserved0; // 0x00 保留
    ULONG64 Rsp0; // 0x04 Ring0栈指针 (关键!)
    ULONG64 Rsp1; // 0x0C Ring1栈指针 (未使用)
    ULONG64 Rsp2; // 0x14 Ring2栈指针 (未使用)
    ULONG64 Ist[8]; // 0x1C 中断栈表(IST), 8个条目
    ULONG64 Reserved1; // 0x5C 保留
    USHORT Reserved2; // 0x64 保留
    USHORT IoMapBase; // 0x66 I/O权限位图偏移
    } KTSS64;

    // 关键字段:
    // Rsp0: 当从Ring3切换到Ring0时, CPU自动将此值加载到RSP
    // 每次线程切换时, 调度器更新此值为当前线程的内核栈
    //
    // Ist[8]: 中断栈表(Interrupt Stack Table)
    // IDT中的中断门可以指定使用IST中的某个栈
    // 用于NMI、双故障、机器检查等关键中断
    // 这些中断不能依赖当前栈(可能已损坏)

    #mermaid-svg-pIfLpneMzaIq4zlT{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-pIfLpneMzaIq4zlT .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-pIfLpneMzaIq4zlT .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-pIfLpneMzaIq4zlT .error-icon{fill:#552222;}#mermaid-svg-pIfLpneMzaIq4zlT .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-pIfLpneMzaIq4zlT .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-pIfLpneMzaIq4zlT .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-pIfLpneMzaIq4zlT .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-pIfLpneMzaIq4zlT .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-pIfLpneMzaIq4zlT .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-pIfLpneMzaIq4zlT .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-pIfLpneMzaIq4zlT .marker{fill:#333333;stroke:#333333;}#mermaid-svg-pIfLpneMzaIq4zlT .marker.cross{stroke:#333333;}#mermaid-svg-pIfLpneMzaIq4zlT svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-pIfLpneMzaIq4zlT p{margin:0;}#mermaid-svg-pIfLpneMzaIq4zlT .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-pIfLpneMzaIq4zlT .cluster-label text{fill:#333;}#mermaid-svg-pIfLpneMzaIq4zlT .cluster-label span{color:#333;}#mermaid-svg-pIfLpneMzaIq4zlT .cluster-label span p{background-color:transparent;}#mermaid-svg-pIfLpneMzaIq4zlT .label text,#mermaid-svg-pIfLpneMzaIq4zlT span{fill:#333;color:#333;}#mermaid-svg-pIfLpneMzaIq4zlT .node rect,#mermaid-svg-pIfLpneMzaIq4zlT .node circle,#mermaid-svg-pIfLpneMzaIq4zlT .node ellipse,#mermaid-svg-pIfLpneMzaIq4zlT .node polygon,#mermaid-svg-pIfLpneMzaIq4zlT .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-pIfLpneMzaIq4zlT .rough-node .label text,#mermaid-svg-pIfLpneMzaIq4zlT .node .label text,#mermaid-svg-pIfLpneMzaIq4zlT .image-shape .label,#mermaid-svg-pIfLpneMzaIq4zlT .icon-shape .label{text-anchor:middle;}#mermaid-svg-pIfLpneMzaIq4zlT .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-pIfLpneMzaIq4zlT .rough-node .label,#mermaid-svg-pIfLpneMzaIq4zlT .node .label,#mermaid-svg-pIfLpneMzaIq4zlT .image-shape .label,#mermaid-svg-pIfLpneMzaIq4zlT .icon-shape .label{text-align:center;}#mermaid-svg-pIfLpneMzaIq4zlT .node.clickable{cursor:pointer;}#mermaid-svg-pIfLpneMzaIq4zlT .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-pIfLpneMzaIq4zlT .arrowheadPath{fill:#333333;}#mermaid-svg-pIfLpneMzaIq4zlT .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-pIfLpneMzaIq4zlT .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-pIfLpneMzaIq4zlT .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-pIfLpneMzaIq4zlT .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-pIfLpneMzaIq4zlT .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-pIfLpneMzaIq4zlT .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-pIfLpneMzaIq4zlT .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-pIfLpneMzaIq4zlT .cluster text{fill:#333;}#mermaid-svg-pIfLpneMzaIq4zlT .cluster span{color:#333;}#mermaid-svg-pIfLpneMzaIq4zlT div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-pIfLpneMzaIq4zlT .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-pIfLpneMzaIq4zlT rect.text{fill:none;stroke-width:0;}#mermaid-svg-pIfLpneMzaIq4zlT .icon-shape,#mermaid-svg-pIfLpneMzaIq4zlT .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-pIfLpneMzaIq4zlT .icon-shape p,#mermaid-svg-pIfLpneMzaIq4zlT .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-pIfLpneMzaIq4zlT .icon-shape .label rect,#mermaid-svg-pIfLpneMzaIq4zlT .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-pIfLpneMzaIq4zlT .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-pIfLpneMzaIq4zlT .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-pIfLpneMzaIq4zlT :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    syscall时

    线程切换时

    x64 TSS (KTSS)

    RSP0 (offset 0x04)Ring0内核栈指针syscall/中断时自动加载

    RSP1 (offset 0x0C)Ring1栈 (未使用)

    RSP2 (offset 0x14)Ring2栈 (未使用)

    IST[0-7] (offset 0x1C)中断栈表用于NMI/MC/DF等关键中断

    IoMapBase (offset 0x66)I/O权限位图偏移

    旧线程的内核栈

    新线程的内核栈

    调度器更新TSS.RSP0 = 新线程.InitialStack

    CPU自动加载RSP ← TSS.RSP0

    4.3 IST(中断栈表)的特殊用途

    x64引入了IST机制,允许特定中断使用预定义的栈,而非当前线程的内核栈。这在以下场景中至关重要:

  • NMI(非屏蔽中断):当前栈可能已损坏,需使用独立栈
  • 双故障(#DF):栈本身就是故障原因,必须切换到IST
  • 机器检查异常(#MC):硬件错误,栈可能不可靠
  • // IDT中断门描述符中的IST字段
    typedef struct _IDT_ENTRY64 {
    USHORT OffsetLow;
    USHORT Selector;
    USHORT IstIndex : 3; // IST索引 (0=不使用IST, 1-7=使用IST[索引-1])
    USHORT Reserved : 5;
    USHORT Type : 4; // 0xE=中断门, 0xF=陷阱门
    USHORT Dpl : 2; // 描述符特权级
    USHORT Present : 1;
    USHORT OffsetMiddle;
    ULONG OffsetHigh;
    ULONG Reserved2;
    } IDT_ENTRY64;

    // Windows IST使用情况:
    // IST[0] – NMI处理 (KiNmiInterrupt)
    // IST[1] – 双故障处理 (KiDoubleFaultAbort)
    // IST[2] – 机器检查 (KiMachineCheck)
    // IST[3] – 调试中断 (KiDebugInterrupt)
    // IST[4-6] – 保留
    // IST[7] – 可能用于安全相关中断

    4.4 内核栈的结构布局

    当syscall进入内核后,内核栈上会构建一个KTRAP_FRAME结构,保存用户态的完整上下文:

    // KTRAP_FRAME结构 – 内核栈上保存的陷阱帧
    // 这是系统调用/中断时保存用户态上下文的标准结构

    typedef struct _KTRAP_FRAME {
    ULONG64 P1Home; // 0x000 参数1主存地址
    ULONG64 P2Home; // 0x008 参数2主存地址
    ULONG64 P3Home; // 0x010 参数3主存地址
    ULONG64 P4Home; // 0x018 参数4主存地址
    ULONG64 P5; // 0x020 参数5
    UCHAR PreviousMode; // 0x028 先前模式(UserMode/KernelMode)
    UCHAR PreviousIrql; // 0x029 先前IRQL
    UCHAR FaultIndicator; // 0x02A 故障指示器
    UCHAR ExceptionActive; // 0x02B 异常活跃标志
    ULONG MxCsr; // 0x02C SSE控制寄存器
    ULONG64 Rbp; // 0x030 用户态RBP
    ULONG64 Rbx; // 0x038 用户态RBX
    ULONG64 Rsi; // 0x040 用户态RSI
    ULONG64 Rdi; // 0x048 用户态RDI
    ULONG64 R12; // 0x050 用户态R12
    ULONG64 R13; // 0x058 用户态R13
    ULONG64 R14; // 0x060 用户态R14
    ULONG64 R15; // 0x068 用户态R15
    ULONG64 ReturnAddress; // 0x070 用户态返回地址(从RCX保存)
    ULONG64 ErrorCode; // 0x078 错误码(异常时)
    ULONG64 SegCs; // 0x080 用户态CS
    ULONG64 SegDs; // 0x088 用户态DS
    ULONG64 SegEs; // 0x090 用户态ES
    ULONG64 SegFs; // 0x098 用户态FS
    ULONG64 SegGs; // 0x0A0 用户态GS
    ULONG64 SegSs; // 0x0A8 用户态SS
    ULONG64 Dr0; // 0x0B0 调试寄存器(如果被修改)
    ULONG64 Dr1; // 0x0B8
    ULONG64 Dr2; // 0x0C0
    ULONG64 Dr3; // 0x0C8
    ULONG64 Dr6; // 0x0D0
    ULONG64 Dr7; // 0x0D8
    ULONG64 Rsp; // 0x0E0 用户态RSP
    ULONG64 EFlags; // 0x0E8 用户态RFLAGS
    ULONG64 ErrCode; // 0x0F0 错误码
    // 注意: 以上偏移是概念性的, 实际偏移以WDK定义为准
    // KTRAP_FRAME在x64上约0x190字节
    } KTRAP_FRAME;

    #mermaid-svg-m37itU8THAafIcjG{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-m37itU8THAafIcjG .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-m37itU8THAafIcjG .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-m37itU8THAafIcjG .error-icon{fill:#552222;}#mermaid-svg-m37itU8THAafIcjG .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-m37itU8THAafIcjG .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-m37itU8THAafIcjG .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-m37itU8THAafIcjG .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-m37itU8THAafIcjG .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-m37itU8THAafIcjG .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-m37itU8THAafIcjG .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-m37itU8THAafIcjG .marker{fill:#333333;stroke:#333333;}#mermaid-svg-m37itU8THAafIcjG .marker.cross{stroke:#333333;}#mermaid-svg-m37itU8THAafIcjG svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-m37itU8THAafIcjG p{margin:0;}#mermaid-svg-m37itU8THAafIcjG .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-m37itU8THAafIcjG .cluster-label text{fill:#333;}#mermaid-svg-m37itU8THAafIcjG .cluster-label span{color:#333;}#mermaid-svg-m37itU8THAafIcjG .cluster-label span p{background-color:transparent;}#mermaid-svg-m37itU8THAafIcjG .label text,#mermaid-svg-m37itU8THAafIcjG span{fill:#333;color:#333;}#mermaid-svg-m37itU8THAafIcjG .node rect,#mermaid-svg-m37itU8THAafIcjG .node circle,#mermaid-svg-m37itU8THAafIcjG .node ellipse,#mermaid-svg-m37itU8THAafIcjG .node polygon,#mermaid-svg-m37itU8THAafIcjG .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-m37itU8THAafIcjG .rough-node .label text,#mermaid-svg-m37itU8THAafIcjG .node .label text,#mermaid-svg-m37itU8THAafIcjG .image-shape .label,#mermaid-svg-m37itU8THAafIcjG .icon-shape .label{text-anchor:middle;}#mermaid-svg-m37itU8THAafIcjG .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-m37itU8THAafIcjG .rough-node .label,#mermaid-svg-m37itU8THAafIcjG .node .label,#mermaid-svg-m37itU8THAafIcjG .image-shape .label,#mermaid-svg-m37itU8THAafIcjG .icon-shape .label{text-align:center;}#mermaid-svg-m37itU8THAafIcjG .node.clickable{cursor:pointer;}#mermaid-svg-m37itU8THAafIcjG .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-m37itU8THAafIcjG .arrowheadPath{fill:#333333;}#mermaid-svg-m37itU8THAafIcjG .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-m37itU8THAafIcjG .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-m37itU8THAafIcjG .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-m37itU8THAafIcjG .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-m37itU8THAafIcjG .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-m37itU8THAafIcjG .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-m37itU8THAafIcjG .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-m37itU8THAafIcjG .cluster text{fill:#333;}#mermaid-svg-m37itU8THAafIcjG .cluster span{color:#333;}#mermaid-svg-m37itU8THAafIcjG div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-m37itU8THAafIcjG .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-m37itU8THAafIcjG rect.text{fill:none;stroke-width:0;}#mermaid-svg-m37itU8THAafIcjG .icon-shape,#mermaid-svg-m37itU8THAafIcjG .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-m37itU8THAafIcjG .icon-shape p,#mermaid-svg-m37itU8THAafIcjG .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-m37itU8THAafIcjG .icon-shape .label rect,#mermaid-svg-m37itU8THAafIcjG .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-m37itU8THAafIcjG .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-m37itU8THAafIcjG .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-m37itU8THAafIcjG :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    内核栈布局 (syscall后)

    内核栈顶 (高地址)Thread.InitialStack

    硬件保存的帧 (如果通过中断)SS:RSP(用户) → RFLAGS → CS:RIP(用户)

    KTRAP_FRAME (~0x190字节)┌────────────────────┐│ R15, R14, R13, R12 ││ RDI, RSI, RBX, RBP ││ RFLAGS(用户) ││ RSP(用户) ││ RIP(用户返回地址) ││ CS, SS, DS, ES(用户)││ PreviousMode ││ PreviousIrql ││ MxCsr ││ 调试寄存器(如需) │└────────────────────┘

    参数传递区(第5+参数从用户栈复制)

    内核函数局部变量

    当前RSP (低地址)

    保护页 (4KB)触发栈溢出检测

    4.5 栈切换的时序

    KPCR

    内核栈

    TSS

    CPU

    用户态栈

    KPCR

    内核栈

    TSS

    CPU

    用户态栈

    #mermaid-svg-fNIP7mEomA88h3h1{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-fNIP7mEomA88h3h1 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-fNIP7mEomA88h3h1 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-fNIP7mEomA88h3h1 .error-icon{fill:#552222;}#mermaid-svg-fNIP7mEomA88h3h1 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-fNIP7mEomA88h3h1 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-fNIP7mEomA88h3h1 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-fNIP7mEomA88h3h1 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-fNIP7mEomA88h3h1 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-fNIP7mEomA88h3h1 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-fNIP7mEomA88h3h1 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-fNIP7mEomA88h3h1 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-fNIP7mEomA88h3h1 .marker.cross{stroke:#333333;}#mermaid-svg-fNIP7mEomA88h3h1 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-fNIP7mEomA88h3h1 p{margin:0;}#mermaid-svg-fNIP7mEomA88h3h1 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-fNIP7mEomA88h3h1 text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-fNIP7mEomA88h3h1 .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-fNIP7mEomA88h3h1 .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-fNIP7mEomA88h3h1 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-fNIP7mEomA88h3h1 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-fNIP7mEomA88h3h1 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-fNIP7mEomA88h3h1 .sequenceNumber{fill:white;}#mermaid-svg-fNIP7mEomA88h3h1 #sequencenumber{fill:#333;}#mermaid-svg-fNIP7mEomA88h3h1 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-fNIP7mEomA88h3h1 .messageText{fill:#333;stroke:none;}#mermaid-svg-fNIP7mEomA88h3h1 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-fNIP7mEomA88h3h1 .labelText,#mermaid-svg-fNIP7mEomA88h3h1 .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-fNIP7mEomA88h3h1 .loopText,#mermaid-svg-fNIP7mEomA88h3h1 .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-fNIP7mEomA88h3h1 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-fNIP7mEomA88h3h1 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-fNIP7mEomA88h3h1 .noteText,#mermaid-svg-fNIP7mEomA88h3h1 .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-fNIP7mEomA88h3h1 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-fNIP7mEomA88h3h1 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-fNIP7mEomA88h3h1 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-fNIP7mEomA88h3h1 .actorPopupMenu{position:absolute;}#mermaid-svg-fNIP7mEomA88h3h1 .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-fNIP7mEomA88h3h1 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-fNIP7mEomA88h3h1 .actor-man circle,#mermaid-svg-fNIP7mEomA88h3h1 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-fNIP7mEomA88h3h1 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    用户态栈(RSP=用户栈)

    硬件完成栈切换

    现在使用内核栈

    KiSystemCall64软件代码

    内核执行系统调用…

    硬件不改变RSP

    用户态栈恢复(RSP=用户栈)

    syscall指令

    读取TSS.RSP0

    内核栈指针

    RSP = 内核栈指针

    保存用户RSP到KPCR.UserRsp

    sub rsp, sizeof(KTRAP_FRAME)

    保存寄存器到KTRAP_FRAME

    恢复寄存器从KTRAP_FRAME

    读取KPCR.UserRsp

    用户态RSP

    RSP = 用户态RSP (软件恢复)

    sysret指令

    4.6 内核栈溢出保护

    内核栈空间有限(12-16KB),栈溢出是严重的内核错误。Windows通过保护页机制检测栈溢出:

    // 内核栈布局(含保护页)

    // 高地址
    // ┌─────────────────────┐
    // │ 线程初始栈顶 │ ← InitialStack
    // │ (KTRAP_FRAME等) │
    // │ … │
    // │ 内核函数局部变量 │
    // │ … │
    // │ 当前RSP │ ← 当前栈指针
    // │ (可用空间) │
    // ├─────────────────────┤
    // │ Guard Page (4KB) │ ← 保护页(PTE.NX=1, R/W=0)
    // │ 访问此页触发#PF │
    // ├─────────────────────┤
    // │ 保留页 │
    // └─────────────────────┘
    // 低地址

    // 当内核栈使用到保护页时, 触发页面错误(#PF)
    // 内核的#PF处理程序检查:
    // 1. 故障地址是否在当前线程的内核栈保护页范围内
    // 2. 如果是, 调用KeBugCheckEx
    // BugCheckCode = STACK_OVERFLOW (0x3A)
    // 或 KERNEL_STACK_OVERFLOW_ERROR

    VOID KiKernelStackOverflowHandler(VOID)
    {
    // 不可恢复 – 必须蓝屏
    KeBugCheckEx(
    KERNEL_STACK_OVERFLOW_ERROR, // 0x3A
    0, // 保留
    0, // 保留
    0, // 保留
    0 // 保留
    );
    }


    赞(0)
    未经允许不得转载:171主机测评 » 01-03 Windows软件体系 - 用户态与内核态分界线与Ring特权级机制(上)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址