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 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中典型的段选择子:
| 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)下,分段机制大幅简化:
尽管分段被简化,但以下机制仍然有效:
- 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只允许通过以下受控路径进行:
这些受控路径确保了特权级切换只能发生在预定义的入口点,操作系统能完全控制这些入口,从而实现安全隔离。
#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寄存器:
| 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硬件会自动完成以下操作:
#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地址空间对比
| 虚拟地址宽度 | 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寄存器:
| 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的开销:
| 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 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线程在创建时都会分配一个内核栈。内核栈用于线程在内核态执行时使用,包括系统调用、中断处理和异常处理。
内核栈的类型:
| 主内核栈 | 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机制,允许特定中断使用预定义的栈,而非当前线程的内核栈。这在以下场景中至关重要:
// 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 // 保留
);
}


