Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этом разделе описывается, как реализовать совместимый код целостности памяти.
Примечание.
Целостность памяти иногда называется целостностью кода, защищенной гипервизором (HVCI) или целостностью кода, обеспечиваемой гипервизором, и первоначально была выпущена в составе Device Guard. Device Guard больше не используется, кроме того, чтобы найти параметры целостности памяти и VBS в групповой политике или реестре Windows.
Чтобы реализовать совместимый код, убедитесь, что код драйвера выполняет следующие действия:
- По умолчанию выбирает NX
- Использует NX API-интерфейсы и флаги для выделения памяти (NonPagedPoolNx)
- Не использует разделы, которые являются записываемыми и исполняемыми
- Не пытается напрямую изменить исполняемую системную память
- Не использует динамический код в ядре
- Не загружает файлы данных как исполняемые
- Выравнивание секций кратно 0x1000 (PAGE_SIZE). Например, DRIVER_ALIGNMENT=0x1000
В следующем списке DDIs, которые не зарезервированы для использования системой, могут оказаться затронутыми:
Использование тестов целостности кода в HLK для проверки совместимости драйверов целостности памяти
Дополнительные сведения о проверке безопасности основных системных принципов см. в тесте на готовность целостности кода HyperVisor и целостности памяти и VBS.
Дополнительные сведения о тесте на основные характеристики устройства см. в тестах Device.DevFund.
Используйте следующую таблицу, чтобы интерпретировать выходные данные и определить, какие изменения кода драйвера необходимы для исправления различных типов несовместимости целостности памяти.
Предупреждения | Искупление |
Тип пула выполнения |
Вызывающий объект указал тип исполняемого пула. Вызов функции выделения памяти, которая запрашивает исполняемую память. Убедитесь, что все типы пулов содержат неисполняемый флаг NX. |
Запустить защиту страниц |
Вызывающий объект указал защиту исполняемой страницы. Укажите маску защиты страницы "без выполнения". |
Выполнить сопоставление страниц |
Вызывающий объект указал сопоставление исполнимого дескриптора памяти (MDL). Убедитесь, что маска, используемая, содержит MdlMappingNoExecute. Дополнительные сведения см. в разделе MmGetSystemAddressForMdlSafe |
Раздел Execute-Write |
Изображение содержит исполняемый и записываемый раздел. |
Ошибки выравнивания разделов |
Изображение содержит раздел, который не выровнен по страницам. Выравнивание разделов должно быть кратным 0x1000 (PAGE_SIZE). Например, DRIVER_ALIGNMENT=0x1000 |
IAT в разделе исполняемых файлов |
Таблица адресов импорта (IAT) не должна быть исполняемым разделом памяти. Эта проблема возникает, когда IAT находится только в разделе памяти для чтения и выполнения (RX). Это означает, что ОС не сможет записать данные в IAT, чтобы установить правильные адреса для размещения упомянутой библиотеки DLL. Одним из способов, как это может произойти, является использование опции /MERGE (Объединение разделов) при связывании кода. Например, если rdata (инициализированные данные только для чтения) объединяется с текстовыми данными (исполняемым кодом), возможно, что IAT может оказаться в исполняемом разделе памяти. |
Неподдерживаемые релоки
В Windows 10 с версии 1507 по версию 1607 из-за использования рандомизации макета адресного пространства (ASLR) может возникнуть проблема с выравниванием адресов и перемещением памяти. Операционная система должна переместить адрес, из которого компоновщик задает базовый адрес по умолчанию в фактическое расположение, назначенное ASLR. Это перемещение данных не может быть привязано к границе страницы. Например, рассмотрим 64-разрядное значение адреса, которое начинается с смещения 0x3FFC на странице. Это значение адреса переходит на следующую страницу, при смещении 0x0003. Этот тип перекрывающихся перелок не поддерживается до Windows 10 версии 1703.
Эта ситуация может произойти, когда инициализатор переменной типа глобальной структуры имеет неправильно выровненный указатель на другой глобальный объект, расположенный таким образом, что компоновщик не может переместить переменную, чтобы избежать перемещения через границу. Компоновщик попытается переместить переменную, но существуют ситуации, когда это может быть невозможно сделать (например, с большими неправильными структурами или большими массивами несогласованных структур). При необходимости модули должны быть собраны с помощью параметра /Gy (COMDAT), чтобы компоновщик мог максимально выровнять код модуля.
#include <pshpack1.h>
typedef struct _BAD_STRUCT {
USHORT Value;
CONST CHAR *String;
} BAD_STRUCT, * PBAD_STRUCT;
#include <poppack.h>
#define BAD_INITIALIZER0 { 0, "BAD_STRING" },
#define BAD_INITIALIZER1 \
BAD_INITIALIZER0 \
BAD_INITIALIZER0 \
BAD_INITIALIZER0 \
BAD_INITIALIZER0 \
BAD_INITIALIZER0 \
BAD_INITIALIZER0 \
BAD_INITIALIZER0 \
BAD_INITIALIZER0
#define BAD_INITIALIZER2 \
BAD_INITIALIZER1 \
BAD_INITIALIZER1 \
BAD_INITIALIZER1 \
BAD_INITIALIZER1 \
BAD_INITIALIZER1 \
BAD_INITIALIZER1 \
BAD_INITIALIZER1 \
BAD_INITIALIZER1
#define BAD_INITIALIZER3 \
BAD_INITIALIZER2 \
BAD_INITIALIZER2 \
BAD_INITIALIZER2 \
BAD_INITIALIZER2 \
BAD_INITIALIZER2 \
BAD_INITIALIZER2 \
BAD_INITIALIZER2 \
BAD_INITIALIZER2
#define BAD_INITIALIZER4 \
BAD_INITIALIZER3 \
BAD_INITIALIZER3 \
BAD_INITIALIZER3 \
BAD_INITIALIZER3 \
BAD_INITIALIZER3 \
BAD_INITIALIZER3 \
BAD_INITIALIZER3 \
BAD_INITIALIZER3
BAD_STRUCT MayHaveStraddleRelocations[4096] = { // as a global variable
BAD_INITIALIZER4
};
Существуют и другие ситуации, связанные с использованием кода сборщика, где также может возникнуть эта проблема.
Целостность кода проверяющего драйвера
Используйте флаг целостности кода проверяющего драйвера (0x02000000), чтобы включить дополнительные проверки, проверяющие соответствие этой функции. Чтобы включить это из командной строки, используйте следующую команду.
verifier.exe /flags 0x02000000 /driver <driver.sys>
Чтобы выбрать этот параметр при использовании графического интерфейса проверки, выберите Создать настраиваемые параметры (для разработчиков кода), выберите Далее, а затем выберите Проверки целостности кода.
Вы можете использовать параметр командной строки /query средства проверки для отображения информации о текущем состоянии проверки драйвера.
verifier /query