Совместимость драйверов с целостностью памяти и VBS

Целостность памяти — это функция безопасности на основе виртуализации (VBS), доступная в Windows 10, Windows 11 и Windows Server 2016 и более поздних версий. Целостность памяти и VBS улучшают модель угроз Windows и обеспечивают более надежную защиту от вредоносных программ, пытающихся использовать ядро Windows. VBS использует гипервизор Windows для создания изолированной виртуальной среды, которая становится корнем доверия ОС, предполагающей, что ядро может быть скомпрометировано. Целостность памяти — это критически важный компонент, который защищает и защищает Windows путем выполнения целостности кода в режиме ядра в изолированной виртуальной среде VBS. Целостность памяти также ограничивает выделение памяти ядра, которое может использоваться для компрометации системы, гарантируя, что страницы памяти ядра выполняются только после передачи целостности кода проверка внутри безопасной среды выполнения, и исполняемые страницы сами никогда не записываются.

Примечание.

Целостность памяти иногда называется целостностью кода, защищенной гипервизором (HVCI) или гипервизором, принудительной целостностью кода и первоначально выпущена в составе Device Guard. Device Guard больше не используется, кроме того, чтобы найти параметры целостности памяти и VBS в групповой политике или реестре Windows.

Целостность памяти включена по умолчанию для чистых установок Windows 10 в режиме S и Windows 11 на совместимом оборудовании, как описано в включении целостности памяти. В других системах, которые не соответствуют требованиям автоматической включения целостности памяти, клиенты могут использовать любой из методов, описанных в том, как включить целостность памяти.

Совместимость приложений

Хотя совместимость с целостностью памяти является требованием для всех драйверов после юбилейного обновления Windows 10 (1607), некоторые приложения и аппаратные драйверы устройств по-прежнему могут быть несовместимы. Эта несовместимость может привести к сбоям устройств или программного обеспечения, и в редких случаях может привести к сбою загрузки (синий экран). Такие проблемы могут возникнуть после включения защиты целостности памяти или во время процесса включения. Если вы являетесь разработчиком приложений и хотите проверить, совместимы ли драйверы и пакеты программного обеспечения с целостностью памяти, выполните следующие действия.

Ниже приведены некоторые примеры, в которых мы наблюдали несовместимость с целостностью памяти:

  • Решения для защиты от обмана с помощью игр
  • Сторонние методы ввода
  • Защита банковских паролей стороннего производителя

Мы работали над устранением затронутых проблем, поэтому если несовместимость существует для загрузочного драйвера, защита целостности памяти будет автоматически отключена, если она была включена автоматически. Если вы столкнулись с несовместимыми с другими приложениями, мы советуем проверка обновления для конкретного приложения и версии, столкнувшись с проблемой, прежде чем отключить защиту целостности памяти.

Создание совместимых драйверов

Так как страницы и разделы памяти никогда не могут быть записываемыми и исполняемыми, сначала необходимо обеспечить четкое разделение данных и кода, а не пытаться напрямую изменять кодовые страницы.

  • По умолчанию при входе в NX
  • Использование NX API-интерфейсов и флагов для выделения памяти — NonPagedPoolNx
  • Не используйте разделы, которые являются как записываемыми, так и исполняемыми
  • Не пытайтесь напрямую изменять исполняемую системную память
  • Не используйте динамический код в ядре
  • Не загружайте файлы данных в виде исполняемого файла
  • Выравнивание разделов должно быть несколькими 0x1000 (PAGE_SIZE). Например, DRIVER_ALIGNMENT=0x1000

Используйте последнюю версию WDK и Visual Studio для создания совместимых драйверов при использовании параметров по умолчанию.

Как проверить совместимость драйверов с целостностью памяти

Существует три шага для проверки совместимости драйверов:

  1. Используйте средство проверки драйверов (см. раздел ниже) с включенными проверка совместимости кода.
  2. Проверьте драйвер в системе с включенной целостностью памяти.
  3. Запустите тест готовности к целостности кода HyperVisor в Windows HLK.

Проверка совместимости средства проверки драйверов

Средство проверки драйверов имеет флаг целостности кода (0x02000000), чтобы включить дополнительные проверка, которые проверяют соответствие целостности памяти. Чтобы включить это из командной строки, используйте следующую команду:

verifier.exe /flags 0x02000000 /driver <driver.sys>

Чтобы выбрать этот параметр при использовании графического интерфейса проверяющего средства, выберите "Создать настраиваемые параметры" (для разработчиков кода), нажмите кнопку "Далее", а затем выберите "Целостность кода" проверка.

Для успешного выполнения выходные данные отсутствуют. Ниже приведен пример выходных данных сбоя.

Driver Verifier: Enabled for DvCi.sys, flags 0x2000000, build 16299, key o4Dbg8OVJqaBYlqWQ2QvRH

\*\*\*\*\*\*\*\*\*\*\* Verifier Detected a Code Integrity Issue \*\*\*\*\*\*\*\*\*\*\*\*

\*\* The caller 0xFFFFF8094B9852F0 specified an executable page protection 0x40.

\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

\*\*\* Verifier assertion failed \*\*\*

(B)reak, (I)gnore, (W)arn only, (R)emove assert? B

Тестирование драйвера с включенной целостностью памяти

Хотя Windows будет включать целостность памяти по умолчанию для большинства систем, существует несколько причин, которые могут предотвратить это. Чтобы включить целостность памяти, см . инструкции по включению целостности памяти. Затем проверьте функциональные возможности драйвера. Не забудьте выполнить все пути кода в драйвере, чтобы убедиться, что драйвер не выполняет операции во время выполнения, несовместимые с целостностью памяти.

Тестирование HLK (рабочий стол и сервер)

Тест проверки целостности кода Гипервизора HLK должен пройти проверку готовности драйверов, которые будут утверждены для подписывания Майкрософт. Драйверы, совместимые с целостностью памяти, необходимы как для классических, так и для серверных выпусков. Тест HLK — это базовый тест, написанный, чтобы убедиться, что драйверы, совместимые с целостностью памяти, правильно загружаются и выполняются ОС.

Хотя простое прохождение теста HLK достаточно для подписи Майкрософт для драйвера, настоятельно рекомендуется тщательное функциональное тестирование с включенной целостностью памяти. Например, может быть неправильно закодировано выделение памяти, нарушающее защиту NX, которая приводит к сбоям, которые не будут пойманы тестом. Автор драйвера должен тщательно протестировать драйвер при сохранении целостности памяти.

Во время разработки драйверов и во время тестирования HLK может потребоваться отключить целостность памяти, так как это может препятствовать загрузке драйвера.

Тест готовности к целостности кода гипервизора HLK требуется в рамках AQ проверки целостности кода Windows Server и флагов для включения проверки целостности кода проверка также устанавливаются при включении средства проверки драйверов во время других тестов HLK.

Вопросы и ответы

Что насчет существующих драйверов? Нужно ли повторно создать эти драйверы, чтобы они работали с Windows 10?

Это зависит от ряда обстоятельств. Многие драйверы уже будут совместимы. При использовании стандартных параметров со старыми версиями WDK и Visual Studio известная проблема заключается в том, что раздел INIT помечается как RWX. Однако в Windows 10 W автоматически будет удален, поэтому если это единственная проблема, драйвер будет совместим.

Разделы справки убедитесь, что включена целостность памяти?

Самый простой метод — запустить приложение Сведения о системе (msinfo32). Найдите следующую строку: "Службы безопасности на основе виртуализации выполняются". Он должен сообщить: "Гипервизор применяет целостность кода". Существует также интерфейс WMI для проверка с помощью средств управления, см. статью "Проверка включенных функций VBS и целостности памяти".

Целостность памяти также может быть проверка в приложении Безопасность Windows в приложении Параметры> Update и Security> Безопасность Windows> Device security>Core изоляции сведений о>целостности памяти. Дополнительные сведения см. в КБ4096339.

Можно ли проверить, включена ли целостность памяти программным способом из ядра, чтобы изменить поведение драйвера?

Да, можно использовать NtQuerySystemInformation: https://msdn.microsoft.com/library/windows/desktop/ms724509(v=vs.85).aspx

Структура SYSTEM_CODEINTEGRITY_INFORMATION имеет 0x400 значение, указывающее, что целостность памяти включена.

Разделы справки устранять проблемы совместимости?

В дополнение к двойному проверка, что нет страниц W+X и разделы драйверов выровнены правильно, как упоминание выше, наиболее вероятной проблемой будет неправильное выделение памяти. Сведения о предупреждениях анализа кода, связанных с выделением памяти, доступны на веб-сайте MSDN на следующей странице:

Анализ кода для предупреждений драйверов

В следующих ссылках MSDN показаны некоторые примеры часто используемых API, которые приводят к выделению исполняемой памяти, а также некоторые примеры исправлений:

Используйте следующую таблицу для интерпретации выходных данных, чтобы определить, какие изменения кода драйвера необходимы для разрешения различных типов несовместимости HVCI.

Предупреждение Разрешение
Тип пула execute Вызывающий объект указал тип исполняемого пула. Вызов функции выделения памяти, которая запрашивает исполняемую память. Убедитесь, что все типы пулов содержат флаг NX, отличный от исполняемого файла.
Выполнение защиты страниц Вызывающий объект указал защиту исполняемой страницы. Укажите маску защиты страницы "без выполнения".
Выполнение сопоставления страниц Вызывающий объект указал сопоставление дескриптора памяти (MDL). Убедитесь, что маска, используемая, содержит MdlMappingNoExecute. Дополнительные сведения см. в статье MmGetSystemAddressForMdl Сейф
Раздел Execute-Write Изображение содержит исполняемый и записываемый раздел.
Сбои выравнивания разделов Изображение содержит раздел, который не выровнен по страницам. Выравнивание разделов должно быть несколькими 0x1000 (PAGE_SIZE). Например, DRIVER_ALIGNMENT=0x1000
Неподдерживаемые релоки В 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
};

Существуют и другие ситуации, связанные с использованием кода сборщика, где также может возникнуть эта проблема.

IAT в разделе исполняемых файлов Таблица адресов импорта (IAT) не должна быть исполняемым разделом памяти.

Эта проблема возникает, когда IAT находится только в разделе памяти для чтения и выполнения (RX). Это означает, что ОС не сможет записывать данные в IAT, чтобы задать правильные адреса, для которых указана ссылка на библиотеку DLL.

Одним из способов этого является использование параметра /MERGE (Объединение разделов) в связывании кода. Например, если rdata (инициализированные данные только для чтения) объединяется с текстовыми данными (исполняемым кодом), возможно, что IAT может оказаться в исполняемом разделе памяти.

Какие API потенциально затронуты?

Может повлиять следующий список API, которые не зарезервированы для использования системы:

   
Имя API Description
ExAllocatePool https://msdn.microsoft.com/library/windows/hardware/ff544501(v=vs.85).aspx
ExAllocatePoolWithQuota https://msdn.microsoft.com/library/windows/hardware/ff544506(v=vs.85).aspx
ExAllocatePoolWithQuotaTag https://msdn.microsoft.com/library/windows/hardware/ff544513(v=vs.85).aspx
ExAllocatePoolWithTag https://msdn.microsoft.com/library/windows/hardware/ff544520(v=vs.85).aspx
ExAllocatePoolWithTagPriority https://msdn.microsoft.com/library/windows/hardware/ff544523(v=vs.85).aspx
ExInitializeNPagedLookasideList https://msdn.microsoft.com/library/windows/hardware/ff545301(v=vs.85).aspx
ExInitializeLookasideListEx https://msdn.microsoft.com/library/windows/hardware/ff545298(v=vs.85).aspx
MmAllocateContiguousMemory https://msdn.microsoft.com/library/windows/hardware/ff554460(v=vs.85).aspx
MmAllocateContiguousMemorySpecifyCache https://msdn.microsoft.com/library/windows/hardware/ff554464(v=vs.85).aspx
MmAllocateContiguousMemorySpecifyCacheNode https://msdn.microsoft.com/library/windows/hardware/ff554464(v=vs.85).aspx
MmAllocateContiguousNodeMemory https://msdn.microsoft.com/library/windows/hardware/jj602795(v=vs.85).aspx
MmCopyMemory https://msdn.microsoft.com/library/windows/hardware/dn342884(v=vs.85).aspx
MmMapIoSpace https://msdn.microsoft.com/library/windows/hardware/ff554618(v=vs.85).aspx
MmMapLockedPages https://msdn.microsoft.com/library/windows/hardware/ff554622(v=vs.85).aspx
MmMapLockedPagesSpecifyCache https://msdn.microsoft.com/library/windows/hardware/ff554629(v=vs.85).aspx
MmProtectMdlSystemAddress https://msdn.microsoft.com/library/windows/hardware/ff554670(v=vs.85).aspx
ZwAllocateVirtualMemory https://msdn.microsoft.com/library/windows/hardware/ff566416(v=vs.85).aspx
ZwCreateSection https://msdn.microsoft.com/library/windows/hardware/ff566428(v=vs.85).aspx
ZwMapViewOfSection https://msdn.microsoft.com/library/windows/hardware/ff566481(v=vs.85).aspx
NtCreateSection https://msdn.microsoft.com/library/windows/hardware/ff556473(v=vs.85).aspx
NtMapViewOfSection https://msdn.microsoft.com/library/windows/hardware/ff556551(v=vs.85).aspx
StorPortGetDataInBufferSystemAddress https://msdn.microsoft.com/library/windows/hardware/jj553720(v=vs.85).aspx
StorPortGetSystemAddress https://msdn.microsoft.com/library/windows/hardware/ff567100(v=vs.85).aspx
DxgkCbMapMemory https://msdn.microsoft.com/library/windows/hardware/ff559533(v=vs.85).aspx
IMiniportDMus::NewStream https://msdn.microsoft.com/library/windows/hardware/ff536701(v=vs.85).aspx
FltAllocatePoolAlignedWithTag https://msdn.microsoft.com/library/windows/hardware/ff541762(v=vs.85).aspx
FltAllocateContext https://msdn.microsoft.com/library/windows/hardware/ff541710(v=vs.85).aspx
ChangerClassAllocatePool https://msdn.microsoft.com/library/windows/hardware/ff551402(v=vs.85).aspx
IMiniportMidi::NewStream https://msdn.microsoft.com/library/windows/hardware/ff536710(v=vs.85).aspx
IMiniportWaveCyclic::NewStream https://msdn.microsoft.com/library/windows/hardware/ff536723(v=vs.85).aspx
IPortWavePci::NewMasterDmaChannel https://msdn.microsoft.com/library/windows/hardware/ff536916(v=vs.85).aspx
IMiniportWavePci::NewStream https://msdn.microsoft.com/library/windows/hardware/ff536735(v=vs.85).aspx
PcNewDmaChannel https://msdn.microsoft.com/library/windows/hardware/ff537712(v=vs.85).aspx
PcNewResourceList https://msdn.microsoft.com/library/windows/hardware/ff537717(v=vs.85).aspx
PcNewResourceSublist https://msdn.microsoft.com/library/windows/hardware/ff537718(v=vs.85).aspx
VideoPortAllocatePool https://msdn.microsoft.com/library/windows/hardware/ff570180(v=vs.85).aspx
ClfsCreateMarshallingArea https://msdn.microsoft.com/library/windows/hardware/ff541520(v=vs.85).aspx
WdfLookasideListCreate https://msdn.microsoft.com/library/windows/hardware/ff548694(v=vs.85).aspx
WdfMemoryCreate https://msdn.microsoft.com/library/windows/hardware/ff548706(v=vs.85).aspx
WdfDeviceAllocAndQueryProperty https://msdn.microsoft.com/library/windows/hardware/ff545882(v=vs.85).aspx
WdfDeviceAllocAndQueryPropertyEx https://msdn.microsoft.com/library/windows/hardware/dn265599(v=vs.85).aspx
WdfFdoInitAllocAndQueryProperty https://msdn.microsoft.com/library/windows/hardware/ff547239(v=vs.85).aspx
WdfFdoInitAllocAndQueryPropertyEx https://msdn.microsoft.com/library/windows/hardware/dn265612(v=vs.85).aspx
WdfIoTargetAllocAndQueryTargetProperty https://msdn.microsoft.com/library/windows/hardware/ff548585(v=vs.85).aspx
WdfRegistryQueryMemory https://msdn.microsoft.com/library/windows/hardware/ff549920(v=vs.85).aspx
NdisAllocateMemory https://msdn.microsoft.com/library/windows/hardware/ff550762(v=vs.85).aspx