内核地址清理器 (KASAN)
内核地址清理器(KASAN)是 Windows 内核驱动程序上支持的 bug 检测技术,可用于检测多个非法内存访问类,例如缓冲区溢出和无后使用事件。 它要求你在系统上启用 KASAN,并使用特定的 MSVC 编译器标志重新编译内核驱动程序。
先决条件
若要使用 KASAN,需要:
- 将加载内核驱动程序的目标系统的 OS 版本:
- 客户端:Windows 11 24H2 或更高版本。
- 服务器:Windows Server 2025 或更高版本。
- VisualStudio:版本 17.11 或更高版本。
- WDK:版本 10.0.26100.2161 或更高版本。
仅 x64 支持 KASAN。
如何在内核驱动程序上启用 KASAN
在目标系统上的管理员 命令提示符 窗口中输入以下命令行:
reg add "HKLM\System\CurrentControlSet\Control\Session Manager\Kernel" /v KasanEnabled /t REG_DWORD /d 1
重新启动目标系统,使更改生效。
通过将新标志传递给 MSVC 编译器,使用启用了 KASAN 检测的内核驱动程序重新编译。 使用以下方法之一:
- GUI:在 VisualStudio 中,导航到解决方案资源管理器,右键单击内核驱动程序项目,然后选择“属性”。 在属性页中,导航到“配置属性>>C/C++>>General”,并将“启用内核地址清理器”设置为“是”。 然后重新生成解决方案。
- 命令提示符:将 /fsanitize=kernel-address 参数添加到编译器命令行。 然后,重新生成解决方案。
在目标系统上加载重新编译的内核驱动程序,并像往常一样对它进行压力测试。 KASAN 在运行时运行,并通过 Bug 检查0x1F2报告非法内存访问事件:KASAN_ILLEGAL_ACCESS。
如何验证是否已在内核驱动程序上启用 KASAN
使用 KASAN 编译的内核驱动程序具有名为“”KASAN
的 PE 部分。 通过在开发人员命令提示符中运行以下命令,验证是否已在驱动程序上启用 KASAN:
dumpbin /ALL YourDriver.sys
如果输出包含一个名为“”KASAN
的部分,则会在驱动程序上启用 KASAN。
如何分析 KASAN 报表
当 KASAN 检测到驱动程序中的非法内存访问时,它会发出 Bug 检查0x1F2:KASAN_ILLEGAL_ACCESS。 检查生成的内核内存转储,以确定驱动程序执行非法内存访问的位置。
将 KASAN 与附加到目标系统的内核调试器配合使用,以便在发出 bug 检查后立即动态检查内存,而不是使用内存转储进行验尸。
Bug 检查参数
Bug 检查0x1F2的参数 :KASAN_ILLEGAL_ACCESS 为:
- 参数 1:非法访问的地址。
- 参数 2:内存访问的大小。
- 参数 3:执行非法内存访问的调用方地址。
- 参数 4:有关内存访问的额外信息:
- 位 [0:7]:KASAN 阴影代码。 请参阅下表。
- 位 8:
1
如果访问是写入,0
则为读取。
KASAN 影子代码
在 KASAN 中,我们认为所有内核内存在八字节对齐的八字节 单元格的连续区块中划分。 对于 KASAN,内核内存中的每个八字节单元格都有一个 与之关联的阴影代码 ,它是一个指示单元格有效性的一字节整数。 阴影代码的编码如下:
值 | 含义 |
---|---|
0x00 |
单元格完全有效:访问单元格的所有 8 个字节都是合法的。 |
0x01 ->0x07 |
单元格部分有效:单元格中的第一 个值 字节有效,但其余部分无效。 |
>= 0x80 |
单元格完全无效:访问单元格的所有 8 个字节都是非法的。 |
多个子代码用于完全无效的单元格,以进一步指示单元格关联的内存类型,以及它为何无效:
0x81
:alloca 的左红区。0x82
:alloca 的中间红区。0x83
:alloca 的右红区。0x84
:全局变量的右红色区域。0x85
:泛型 redzone。0x86
:池内存的右红区。0x87
:释放的内存。0x8A
:连续内存的左红区。0x8B
:连续内存的右红区。0x8C
:释放的 lookasidelist 内存。0x8D
:池内存的左红区。0xF1
:堆栈变量的左红区。0xF2
:堆栈变量的中间红色区域。0xF3
:堆栈变量的右红色区域。0xF5
:used-after-ret 堆栈变量。0xF8
:范围外堆栈变量。
了解 KASAN bug 检查:示例
假设 KASAN 在执行驱动程序时发出了 bug 检查,并使用以下参数:
- 参数 1:
0xFFFFFFFFFFFFABCD
- 参数 2:
0x0000000000000004
- 参数 3:
0xFFFFFFFF12345678
- 参数 4:
0x0000000000000184
参数 1 告知驱动程序尝试访问地址 0xFFFFFFFFFFFFABCD
,并且此访问是非法的。 参数 2 告诉你,这是一个四字节的访问。 参数 3 提供驱动程序执行非法访问的指令指针的地址。 参数 4 告知这是写入访问权限,所触摸的内存是全局变量的右红区。
换句话说,驱动程序可能尝试对全局变量执行写入缓冲区溢出。 使用此信息调查并确定驱动程序中修复此 bug 的位置和方法。
KASAN 的性能影响
KASAN 增加了内核内存消耗,并在启用了 KASAN 编译的驱动程序中引入了大约两倍的减速。
与驱动程序验证程序比较
KASAN 和驱动程序验证程序是完全独立的功能,但相互兼容。
KASAN 侧重于检测非法内存访问,并且比该域中的驱动程序验证程序更高效,因为它使用更精细的方法并涵盖更多的内存区域。 驱动程序验证程序具有特定于驱动程序的规则,这些规则旨在查找 KASAN 未检测到的其他类型的 bug。 有关详细信息,请参阅 Microsoft:Microsoft 平台上的内核清理器简介。
将 KASAN 与驱动程序验证程序结合使用,最大限度地检测驱动程序中的 bug。