一、先建立Windows内核总图
你以后所有知识都放进这张图:
用户程序
↓
CreateFile
DeviceIoControl
ReadFile
WriteFile
↓
Ntdll.dll
↓
Syscall
↓
===================
进入内核
===================
I/O Manager
Memory Manager
Process Manager
Object Manager
Security Manager
Cache Manager
↓
驱动程序
(WDM/KMDF)
↓
硬件
二、用户态和内核态
用户态:
Ring3
权限最低
不能:
访问页表
访问寄存器
访问硬件
执行特权指令
例如:
MessageBox()
CreateFile()
都在用户态。
内核态:
Ring0
权限最高。
可以:
访问所有内存
访问硬件
处理中断
修改页表
例如:
ntoskrnl.exe
驱动程序
运行于内核态。
三、系统调用流程
经典面试题。
例如:
ReadFile()
发生什么?
ReadFile
↓
Kernel32.dll
↓
Ntdll.dll
↓
NtReadFile
↓
syscall指令
↓
切换Ring3→Ring0
↓
SSDT
↓
NtReadFile内核实现
↓
I/O Manager
↓
IRP
↓
驱动
↓
硬件
↓
返回
四、进程和线程
进程:
资源容器。
内核对应:
EPROCESS
保存:
页表
句柄表
Token
线程链表
线程:
执行单元。
内核对应:
ETHREAD
保存:
栈
寄存器
优先级
状态
关系:
EPROCESS
├──ETHREAD
├──ETHREAD
└──ETHREAD
五、虚拟内存
为什么存在?
因为:
物理内存有限。
而程序觉得:
自己拥有4GB
或者:
128TB
虚拟地址空间。
CPU访问:
VA
Virtual Address
经过:
页表(Page Table)
转换:
PA
Physical Address
六、Page Table
这是地址翻译表。
例如:
VA
0x12345678
↓
Page Table
↓
PA
0x87654321
保存于内存。
问题来了:
每次查页表很慢。
于是:
七、TLB
Translation Lookaside Buffer
地址翻译缓存。
CPU内部。
没有TLB:
VA
↓
页表
↓
PA
有TLB:
VA
↓
TLB
↓
PA
直接命中。
快几十倍。
面试经典:
TLB是什么?
答:
CPU缓存最近使用页表项的高速缓存。
加速地址转换。
八、Cache和TLB区别
很多人答错。
Cache缓存:
数据
例如:
int a=100;
缓存这个100。
TLB缓存:
地址映射关系
例如:
VA→PA
一句话:
Cache缓存数据
TLB缓存地址映射
九、Page Fault
缺页异常。
CPU访问:
0x12345678
发现:
页表无效
触发:
#PF
Page Fault
进入:
KiPageFault
↓
Mm
Memory Manager
↓
加载页面
↓
更新PTE
↓
恢复执行
面试:
为什么DPC不能访问Paged Memory?
因为:
Page Fault需要阻塞。
而:
DISPATCH_LEVEL
禁止阻塞。
直接蓝屏。
十、IRQL
面试出现率极高。
全称:
Interrupt Request Level
Windows优先级体系。
PASSIVE_LEVEL
↓
APC_LEVEL
↓
DISPATCH_LEVEL
↓
DIRQL
↓
HIGH_LEVEL
作用:
控制:
谁能抢占谁
十一、ISR
Interrupt Service Routine
中断服务程序。
硬件触发:
网卡
磁盘
串口
↓
CPU中断
↓
ISR
特点:
运行DIRQL
时间必须极短
十二、DPC
Deferred Procedure Call
延迟过程调用。
ISR里不能干重活。
于是:
ISR
↓
KeInsertQueueDpc
↓
DPC
↓
DISPATCH_LEVEL
例如:
网卡收1000个包。
ISR只记录:
来包了
真正处理:
DPC。
十三、APC
Asynchronous Procedure Call
异步过程调用。
运行:
APC_LEVEL
主要:
内核向线程插任务
例如:
ReadFile完成
通知线程。
十四、ISR、DPC、APC、IRQL关系
面试经典。
硬件中断
↓
ISR
DIRQL
↓
DPC
DISPATCH_LEVEL
↓
APC
APC_LEVEL
↓
线程
PASSIVE_LEVEL
记住这张图。
十五、IRP
驱动面试必问。
IRP:
I/O Request Packet
所有IO请求载体。
例如:
ReadFile
变成:
IRP_MJ_READ
DeviceIoControl
变成:
IRP_MJ_DEVICE_CONTROL
十六、IO_STACK_LOCATION
IRP内部的一层。
驱动栈:
应用
↓
文件系统
↓
过滤驱动
↓
磁盘驱动
每层一个:
IO_STACK_LOCATION
保存:
本层参数
十七、IOCTL
设备控制码。
用户层:
DeviceIoControl()
↓
驱动:
IRP_MJ_DEVICE_CONTROL
↓
解析:
IOCTL_XXX
十八、MDL
Memory Descriptor List
面试高频。
作用:
描述用户缓冲区。
例如:
用户层:
char buf[4096];
驱动需要DMA。
不能直接访问。
于是:
buf
↓
MDL
↓
锁页
↓
获得物理页
十九、FastIO
一种绕过IRP机制。
普通:
Read
↓
IRP
↓
文件系统
FastIO:
Read
↓
FastIO
↓
返回
少一次IRP。
更快。
二十、Cancel IRP
取消请求。
用户:
CancelIoEx()
↓
IRP取消
↓
Cancel Routine
↓
驱动清理
↓
完成IRP
二十一、KMDF对象模型
核心思想:
一切皆对象。
WDFDRIVER
↓
WDFDEVICE
↓
WDFQUEUE
↓
WDFREQUEST
二十二、引用计数
KMDF自动管理。
WDM:
ObReferenceObject
ObDereferenceObject
自己维护。
KMDF:
WdfObjectReference
WdfObjectDereference
自动释放。
二十三、WDFQUEUE
请求队列。
模式:
Sequential
顺序
Parallel
并行
Manual
手工
二十四、EvtIoDeviceControl
KMDF最重要回调。
收到:
DeviceIoControl()
最终:
EvtIoDeviceControl()
二十五、PnP状态机
设备生命周期。
AddDevice
↓
StartDevice
↓
Working
↓
StopDevice
↓
RemoveDevice
二十六、Power状态机
电源管理。
设备状态:
D0 工作
D1
D2
D3 睡眠
系统状态:
S0 工作
S1
S2
S3 睡眠
S4 休眠
S5 关机
二十七、VAD
Virtual Address Descriptor
面试高级题。
管理:
进程虚拟内存区域
例如:
VirtualAlloc()
↓
创建:
VAD
二十八、PTE
Page Table Entry
页表项。
保存:
物理页号
权限
Present位
Dirty位
二十九、SSDT
System Service Dispatch Table
系统调用表。
NtOpenProcess
NtReadFile
NtCreateFile
全部登记在:
SSDT
三十、Object Manager
Windows万物皆对象。
例如:
Process
Thread
File
Event
Mutex
Device
都有对象头。
统一:
引用计数
句柄管理
命名空间
由 Object Manager 管理。
名词了解顺序表
IRQL
↓
ISR
↓
DPC
↓
APC
↓
IRP
↓
IOCTL
↓
Page Fault
↓
TLB
↓
PTE
↓
EPROCESS
↓
ETHREAD
↓
VAD