Hypervisor-Protected Codeintegrität (HVCI)

Hypervisor-Protected Codeintegrität kann Hardwaretechnologie und Virtualisierung verwenden, um die Entscheidungsfunktion Codeintegrität (CI) aus dem rest des Windows Betriebssystems zu isolieren. Wenn Sie virtualisierungsbasierte Sicherheit verwenden, um Codeintegrität zu isolieren, kann der Kernelspeicher über eine Codeintegritätsüberprüfung ausführbare Dateien werden. Das bedeutet, dass Kernelspeicherseiten nie beschreibbar und ausführbar sein können, und ausführbarer Code kann nicht direkt geändert werden.

Erstellen kompatibler Treiber

Da Speicherseiten und Abschnitte niemals schreibbar und ausführbarer werden können, besteht der erste Schritt darin, eine klare Trennung von Daten und Code zu gewährleisten und nicht zu versuchen, Codeseiten direkt zu ändern.

  • Opt-In bei NX standardmäßig
  • Verwenden von NX-APIs/Flags für die Speicherzuweisung – NonPagedPoolNx
  • Verwenden Sie keine Abschnitte, die sowohl schreibbar als auch ausführbare Dateien sind.
  • Versuchen Sie nicht, den ausführbaren Systemspeicher direkt zu ändern
  • Verwenden Sie keinen dynamischen Code im Kernel
  • Laden Sie keine Datendateien als ausführbare Datei
  • Die Abschnittsausrichtung muss ein Vielfaches von 0x1000 (PAGE_SIZE) sein. z. B. DRIVER_ALIGNMENT=0x1000

Verwenden Sie die neueste Version des WDK und Visual Studio, um kompatible Treiber bei Verwendung von Standardeinstellungen zu erstellen.

Überprüfen der Treiberkompatibilität

Es gibt vier Schritte zum Überprüfen der Treiberkompatibilität:

  1. Verwenden Sie die Treiberüberprüfung mit aktivierten Kompatibilitätsprüfungen für die Codeintegrität.
  2. Testen Sie den Treiber auf einem System mit virtualisierungsbasierter Isolation der Codeintegrität, die aktiviert ist.
  3. Führen Sie den HyperVisor-Codeintegritätsbereitschaftstest im Windows HLK aus.
  4. Verwenden Sie das DGReadiness-Tool.

Überprüfung der Kompatibilitätsprüfung für Treiberüberprüfungen

Treiberüberprüfung verfügt über ein neues Codeintegritätsoptions-Flag (0x02000000), um zusätzliche Überprüfungen zu aktivieren, die die Compliance mit diesem Feature überprüfen. Um dies aus der Befehlszeile zu aktivieren, verwenden Sie den folgenden Befehl:

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

Wenn Sie diese Option auswählen möchten, wenn Sie die Überprüfungs-GUI verwenden, wählen Sie "Benutzerdefinierte Einstellungen erstellen" (für Codeentwickler) aus, wählen Sie "Weiter" und dann "Codeintegritätsüberprüfungen" aus.

Treiber, die mit älteren Versionen von Visual Studio erstellt wurden, schlägt im INIT-Abschnitt unter WRX fehl. Wenn dies jedoch das einzige Problem ist, können Sie dieses Problem ignorieren und dies im Kernel-Debugger durchlaufen, da dies keine Kompatibilitätsprobleme mit diesem Feature verursacht. Die bevorstehenden Updates für die Treiberüberprüfung kennzeichnen den INIT-Abschnitt nicht.

Aktivieren der virtualisierungsbasierten Isolation für die Codeintegrität

Virtualisierungsbasierte Sicherheit wird auf Enterprise und Server-Editionen von Windows unterstützt. Um virtualisierungsbasierten Schutz der Codeintegrität zu aktivieren, besteht die einfachste Methode darin, gpedit wie unten beschrieben zu verwenden. Dadurch wird der Hyper-V- und isolierter Benutzermodus aktiviert und das Feature aktiviert:

  1. Führen Sie gpedit aus, um lokale Gruppenrichtlinie zu bearbeiten

  2. Wählen Sie unter "Computerkonfiguration " Administrative Vorlagen -> System> ->Device Guard" die Option "Virtualisierung basierende Sicherheit aktivieren" aus.

    Screen shot showing Configuration -> Administrative Templates -> System -> Device Guard, with Turn On Virtualization Based Security highlighted

  3. Wählen Sie im angezeigten Ausführlichen Konfigurationsdialogfeld "Aktiviert" und dann "Virtualisierungsbasierten Schutz der Codeintegrität aktivieren" aus.

    Detailed configuration dialog showing Enabled button and selection of Enable Virtualization Based Protection of Code Integrity.

  4. Reboot

Der virtualisierungsbasierte Schutz der Codeintegrität ist jetzt aktiviert.

HLK-Tests und -Anforderungen

Client

Es gibt einen neuen HLK-Test namens Hypervisor code integrity Readiness Test, der die Treiberüberprüfungscodeintegritätsoptionen ermöglicht, um Probleme beim Laden von Treibern zu erfassen. Dieser Test fängt nicht unbedingt Dinge ab, die der Treiber während des normalen Vorgangs ausführt, sodass es vorgeschlagen wird, dass andere Tests ausgeführt werden, während die Treiberüberprüfung aktiviert ist und/oder während der virtualisierungsbasierten Schutz von CI aktiviert ist.

Server

Der HLK-Hypervisor-Codeintegritätsbereitschaftstest ist als Teil der Assurance AQ erforderlich und die Flags zum Aktivieren der Codeintegritätsüberprüfung werden auch festgelegt, während die Treiberüberprüfung während anderer HLK-Tests aktiviert wird.

DGReadiness Tool

Das DGReadiness-Tool kann auch verwendet werden, um die HVCI-Kompatibilität aller installierten Treiber auf dem Gerät zu überprüfen. Der Download enthält eine Readme-Datei, die Nutzungsinformationen enthält. Beachten Sie, dass während der Ausführung des Readiness-Tools "Device Guard" deaktiviert sein muss, da der Treiber möglicherweise nicht geladen wird, und der Treiber ist für den Test des Readiness-Tools nicht verfügbar. Weitere Informationen zum Readiness-Tool finden Sie unter "Auswerten der HVCI-Treiberkompatibilität".

Häufig gestellte Fragen

Was ist mit vorhandenen Treibern? Muss ich diese Treiber erneut erstellen, um sie mit Windows 10 zu arbeiten?

Das ist unterschiedlich. Viele Treiber sind bereits kompatibel. Wenn Sie Standardeinstellungen mit den alten Versionen des WDK und Visual Studio verwenden, ist ein bekanntes Problem, dass der INIT-Abschnitt als RWX gekennzeichnet ist. In Windows 10 wird das W jedoch automatisch entfernt, sodass dies das einzige Problem ist, dann ist der Treiber kompatibel.

Gewusst wie überprüfen, ob HVCI aktiviert ist?

HVCI ist als Speicherintegrität in der Windows-Sicherheit-App gekennzeichnet und kann über Einstellungen>Update & Security Windows-Sicherheit Device> Security>> Core-Isolationsintegrität> im Arbeitsspeicher abgerufen werden. Weitere Informationen finden Sie unter KB4096339.

Kann ich überprüfen, ob HVCI programmgesteuert vom Kernel aktiviert ist, um das Treiberverhalten zu ändern?

Ja, Sie können NtQuerySystemInformation verwenden: https://msdn.microsoft.com/library/windows/desktop/ms724509(v=vs.85).aspx

Die SYSTEM_CODEINTEGRITY_INFORMATION Struktur verfügt über einen neuen 0x400 Wert, der angibt, dass die virtualisierungsbasierte Schutz der Codeintegrität aktiviert ist.

Gewusst wie Beheben von Kompatibilitätsproblemen?

Zusätzlich zur doppelten Überprüfung, dass keine W+X-Seiten vorhanden sind und die Treiberabschnitte korrekt ausgerichtet sind, wie oben erwähnt, ist das wahrscheinlichste Problem eine falsche Speicherzuweisung. Informationen zu den Code Analysis Warnungen im Zusammenhang mit der ausgegebenen Speicherzuweisung finden Sie auf der folgenden Seite unter MSDN:

Codeanalyse für Treiberwarnungen

Die folgenden MSDN-Links zeigen einige Beispiele für häufig verwendete APIs, die dazu führen, dass ausführbarer Speicher zugewiesen wird, zusammen mit einigen Beispielkorrekturen:

Verwenden Sie die folgende Tabelle, um die Ausgabe zu interpretieren, um festzustellen, welche Treibercodeänderungen erforderlich sind, um die verschiedenen Typen von HVCI-Inkompatibilitäten zu beheben.

Warnung Lösung
Ausführen des Pooltyps Der Aufrufer hat einen ausführbaren Pooltyp angegeben. Aufrufen einer Speicherzuordnungsfunktion, die ausführbaren Speicher anfordert. Stellen Sie sicher, dass alle Pooltypen ein nicht ausführbares NX-Flag enthalten.
Ausführen des Seitenschutzes Der Aufrufer hat einen ausführbaren Seitenschutz angegeben. Geben Sie ein Seitenschutzmaske für "keine Ausführung" an.
Ausführen der Seitenzuordnung Der Aufrufer gibt eine ausführbare Speicherdeskriptorliste (MDL) -Zuordnung an. Stellen Sie sicher, dass die verwendete Maske MdlMappingNoExecute enthält. Weitere Informationen finden Sie unter MmGetSystemAddressForMdlSafe
abschnitt Execute-Write Das Bild enthält einen ausführbaren und schreibbaren Abschnitt.
Abschnittsausrichtungsfehler Das Bild enthält einen Abschnitt, der nicht seitenbündig ausgerichtet ist. Die Abschnittsausrichtung muss ein Vielfaches von 0x1000 (PAGE_SIZE) sein. z. B. DRIVER_ALIGNMENT=0x1000
Nicht unterstützte Zuweisungen In Windows 10 Version 1507 bis Version 1607 kann aufgrund der Verwendung der Randomisierung des Adressraumlayouts (ASLR) ein Problem mit der Adressausrichtung und der Speicherverschiebung auftreten. Das Betriebssystem muss die Adresse verschieben, aus der der Linker seine Standardbasisadresse auf den tatsächlichen Speicherort festgelegt hat, den ASLR zugewiesen hat. Diese Verlagerung kann keine Seitengrenze haben. Ziehen Sie beispielsweise einen 64-Bit-Adresswert in Betracht, der mit offset 0x3FFC auf einer Seite beginnt. Der Adresswert überlappen sich mit der nächsten Seite beim Offset 0x0003. Diese Art überlappender Verlagerungen wird vor Windows 10 Version 1703 nicht unterstützt.

Diese Situation kann auftreten, wenn ein globaler Strukturtypvariablen-Initialisierer einen falsch ausgerichteten Zeiger auf einen anderen globalen Zeiger aufweist, der so ausgelegt ist, dass der Linker die Variable nicht verschieben kann, um die Verlagerung von Verschiebungen zu vermeiden. Der Linker versucht, die Variable zu verschieben, aber es gibt Situationen, in denen dies möglicherweise nicht möglich ist, z. B. mit großen falsch ausgerichteten Strukturen oder großen Arrays falsch ausgerichteter Strukturen. Gegebenenfalls sollten Module mithilfe der Option "/Gy" (COMDAT) zusammengefügt werden, damit der Linker den Modulcode so weit wie möglich ausrichten kann.

#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
};

Es gibt andere Situationen mit der Verwendung von Assemblercode, in denen dieses Problem auch auftreten kann.

IAT im ausführbaren Abschnitt Die Importadressentabelle (IAT) sollte kein ausführbarer Speicherabschnitt sein.

Dieses Problem tritt auf, wenn sich das IAT in einem Nur-Lese- und Ausführungsbereich (RX) befindet. Dies bedeutet, dass das Betriebssystem nicht in die IAT schreiben kann, um die richtigen Adressen festzulegen, für die die referenzierte DLL verwendet wird.

Eine Möglichkeit, wie dies auftreten kann, ist die Verwendung der Option /MERGE (Abschnitte kombinieren) in codeverknüpfung. Wenn z. B. Rdata (Schreibgeschützte initialisierte Daten) mit TEXT-Daten (ausführbarer Code) zusammengeführt wird, ist es möglich, dass das IAT möglicherweise in einem ausführbaren Speicherabschnitt endet.

Welche APIs sind potenziell betroffen?

Die folgende Liste der APIs, die nicht für die Systemverwendung reserviert sind, können sich auf folgende Auswirkungen auswirken:

   
API-Name BESCHREIBUNG
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