Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Санитизатор адресов ядра (KASAN) — это технология обнаружения ошибок, поддерживаемая в драйверах ядра Windows, которая позволяет обнаруживать несколько классов незаконного доступа к памяти, таких как переполнение буфера и события после использования. Для этого необходимо включить KASAN в системе и перекомпилировать драйвер ядра с определенным флагом компилятора MSVC.
Pre-requisites
Чтобы использовать KASAN, вам потребуется:
- Версия ос целевой системы, в которой будет загружен драйвер ядра:
- Клиент: Windows 11 24H2 или более поздней версии.
- Сервер: Windows Server 2025 или более поздней версии.
- VisualStudio: версия 17.11 или более поздней.
- WDK: версия 10.0.26100.2161 или более поздней.
KASAN поддерживается только в x64.
Включение KASAN в драйвере ядра
Введите следующую командную строку в окне командной строки администратора в целевой системе:
reg add "HKLM\System\CurrentControlSet\Control\Session Manager\Kernel" /v KasanEnabled /t REG_DWORD /d 1Установка этого параметра реестра указывает ядру Windows подготовиться к загрузке и принять драйверы с инструментированием KASAN. Если этот раздел реестра не задан, ядро Windows откажется от загрузки инструментированных драйверов KASAN.
Перезагрузите целевую систему, чтобы изменения вступили в силу.
Перекомпилируйте драйвер ядра с включенным инструментированием KASAN, передав новый флаг компилятору MSVC. Для этого можно использовать один из следующих методов:
- GUI: в VisualStudio перейдите в обозреватель решений, щелкните правой кнопкой мыши проект драйвера ядра и выберите "Свойства". На странице свойств перейдите в раздел "Свойства>> конфигурации" C/C++>>Общие и установите для параметра "Включить санитизатор адресов ядра" значение "Да". Затем перестройте решение.
- Командная строка: добавьте параметр /fsanitize=kernel-address в командную строку компилятора. Затем перестройте решение.
Загрузите перекомпилируемый драйвер ядра в целевой системе и проверьте его, как правило. KASAN работает во время выполнения и сообщает о событиях незаконного доступа к памяти с помощью проверки ошибок 0x1F2: KASAN_ILLEGAL_ACCESS.
Регрессия в VisualStudio 17.12
Если вы используете VisualStudio 17.12, может возникнуть следующая ошибка сборки:
error LNK2019: unresolved external symbol __asan_wrap_wcscat referenced in function
Эту ошибку можно обойти, добавив следующий флаг в командную строку компоновщика:
/alternatename:__asan_wrap_wcscat=wcscat
Эта регрессия была исправлена в VisualStudio 17.14.15.
Регрессия в VisualStudio 17.14 до 17.14.14
Если вы используете VisualStudio 17.14, может возникнуть следующая ошибка сборки:
error LNK2001: unresolved external symbol __LINK_WITH_asan_compat.lib_TO_USE_NEW_COMPILER_WITH_OLDER_ASAN_RUNTIME
Эту ошибку можно обойти, добавив следующий флаг в командную строку компилятора:
/fno-sanitize-address-asan-compat-lib
Добавьте следующие флаги в командную строку компоновщика:
/alternatename:__asan_wrap_wcscat=wcscat
/alternatename:__asan_wrap_wcscpy=wcscpy
/alternatename:__asan_wrap_wcsncpy=wcsncpy
Эта регрессия была исправлена в VisualStudio 17.14.15.
Как проверить, включен ли KASAN в драйвере ядра
Драйверы ядра, скомпилированные с помощью KASAN, имеют раздел PE с именем "KASAN". Убедитесь, что KASAN включен в драйвере, выполнив следующую команду в командной строке разработчика:
dumpbin /ALL YourDriver.sys
Если выходные данные содержат раздел "KASAN", в драйвере включен KASAN.
Как анализировать отчеты KASAN
Когда KASAN обнаруживает незаконный доступ к памяти в драйвере, он выдает 0x1F2 проверки ошибок: KASAN_ILLEGAL_ACCESS. Проверьте созданный дамп памяти ядра, чтобы определить, где именно ваш драйвер выполнил незаконный доступ к памяти.
Используйте KASAN с отладчиком ядра, подключенным к целевой системе, чтобы память можно было динамически проверять сразу после выдачи проверки ошибок, а не после отправки дампа памяти.
Параметры проверки ошибок
Параметры проверки ошибок 0x1F2: KASAN_ILLEGAL_ACCESS :
- Параметр 1. Доступ к адресу осуществляется незаконно.
- Параметр 2. Размер доступа к памяти.
- Параметр 3. Адрес вызывающего объекта, выполняющего незаконный доступ к памяти.
- Параметр 4. Дополнительные сведения о доступе к памяти:
- Биты [0:7]: теневой код KASAN. См. таблицу ниже.
- Бит 8:
1если доступ был записью,0если он был чтением.
Теневые коды KASAN
В KASAN мы считаем, что вся память ядра разделена на смежные блоки из восьмибайтовых ячеек, выровненных по восьмибайтовым границам. При использовании KASAN каждая восьмибайтовая ячейка в памяти ядра имеет теневой код , связанный с ним, который представляет собой однобайтовое целое число, указывающее допустимость ячейки. Кодирование теневых кодов выполняется следующим образом:
| Value | Meaning |
|---|---|
0x00 |
Ячейка является полностью допустимой: доступ ко всем восьми байтам ячейки является законным. |
0x01 —>0x07 |
Ячейка является частично допустимой: первые байты значений в ячейке допустимы, но остальные недопустимы. |
0x08 —>0x7F |
Ячейка является условно допустимой: доступ ко всем восьми байтам ячейки может быть законным или незаконным в зависимости от конкретных условий. |
>= 0x80 |
Ячейка полностью недопустима: доступ ко всем восьми байтам ячейки является незаконным. |
Для условно допустимых и полностью недопустимых ячеек используются несколько вложенных кодов, чтобы указать, с каким типом памяти связана ячейка, и почему доступ к ней может быть незаконным.
Подкоды, используемые условно допустимыми ячейками.
-
0x09: подкачиваемая память, доступ к которой запрещён на уровне DISPATCH_LEVEL и выше, но разрешён в остальных случаях.
Вложенные коды, используемые полностью недопустимыми ячейками:
-
0x81: левая красная зона alloca. -
0x82: средняя красная зона alloca. -
0x83: правая красная зона alloca. -
0x84: правая красная зона глобальной переменной. -
0x85: универсальная красная зона. -
0x86: правая красная зона памяти пула. -
0x87: память пула освобождена. -
0x8A: левая красная зона непрерывной памяти. -
0x8B: правая красная зона непрерывной памяти. -
0x8C: освобожденная память lookasidelist. -
0x8D: левая красная зона памяти пула. -
0xF1: левая красная зона переменной стека. -
0xF2: средняя красная зона переменной стека. -
0xF3: правая красная зона переменной стека. -
0xF5: используемая переменная стека после повторных попыток. -
0xF8: переменная стека вне области.
Общие сведения об ошибках KASAN: пример
Предположим, что KASAN выдал ошибку при выполнении драйвера с этими параметрами:
- Параметр 1.
0xFFFFFFFFFFFFABCD - Параметр 2.
0x0000000000000004 - Параметр 3.
0xFFFFFFFF12345678 - Параметр 4.
0x0000000000000184
Параметр 1 сообщает, что драйвер пытался получить доступ к адресу 0xFFFFFFFFFFFFABCD и что этот доступ был незаконным.
Параметр 2 указывает, что это был четырехбайтовый доступ.
Параметр 3 предоставляет адрес указателя инструкции, на который драйвер выполнил незаконный доступ.
Параметр 4 сообщает, что это был доступ на запись и что затронутая память принадлежит правой "redzone" глобальной переменной.
Другими словами, драйвер, скорее всего, пытался выполнить переполнение буфера записи в глобальной переменной. Используйте эти сведения для изучения и определения того, где и как устранить эту ошибку в драйвере.
Влияние на производительность KASAN
KASAN увеличивает потребление памяти ядра и приводит к примерному двухкратному замедлению в драйверах, скомпилированных с включенным KASAN.
Сравнение с проверятелем драйверов
KASAN и Driver Verifier являются полностью отдельными функциями, но совместимы друг с другом.
KASAN сосредоточен на обнаружении незаконного доступа к памяти и более эффективно, чем средство проверки драйверов в этом домене, так как он использует более точный подход и охватывает больше областей памяти. Средство проверки драйверов имеет правила, относящиеся к драйверу, которые стремятся найти другие типы ошибок, что KASAN не обнаруживает. Дополнительные сведения см. в статье Майкрософт. Знакомство с средствами очистки ядра на платформах Майкрософт.
Используйте KASAN в сочетании с средство проверки драйверов, чтобы максимально увеличить обнаружение ошибок в драйвере.