Compatibilità dei driver con l'integrità della memoria e la sicurezza basata su vbs

L'integrità della memoria è una funzionalità di sicurezza basata su virtualizzazione disponibile in Windows 10, Windows 11 e Windows Server 2016 e versioni successive. L'integrità della memoria e la sicurezza basata su vbs migliorano il modello di minaccia di Windows e forniscono protezioni più avanzate contro il malware che tenta di sfruttare il kernel di Windows. La sicurezza basata su virtualizzazione usa l'hypervisor Di Windows per creare un ambiente virtuale isolato che diventa la radice di attendibilità del sistema operativo che presuppone che il kernel possa essere compromesso. L'integrità della memoria è un componente critico che protegge e protegge Windows eseguendo l'integrità del codice in modalità kernel all'interno dell'ambiente virtuale isolato della sicurezza basata su virtualizzazione. L'integrità della memoria limita anche le allocazioni di memoria del kernel che potrebbero essere usate per compromettere il sistema, assicurandosi che le pagine di memoria kernel vengano eseguite solo dopo aver superato i controlli di integrità del codice all'interno dell'ambiente di runtime protetto e le pagine eseguibili stesse non siano mai scrivibili.

Nota

L'integrità della memoria viene talvolta definita integrità del codice protetta dall'hypervisor (HVCI) o hypervisor applicata all'integrità del codice ed è stata originariamente rilasciata come parte di Device Guard. Device Guard non viene più usato tranne per individuare l'integrità della memoria e le impostazioni VBS in Criteri di gruppo o nel Registro di sistema di Windows.

L'integrità della memoria è attivata per impostazione predefinita su installazioni pulite di Windows 10 in modalità S e Windows 11 su hardware compatibile, come descritto in Abilitazione dell'integrità della memoria. In altri sistemi che non soddisfano i requisiti di abilitazione automatica dell'integrità della memoria, i clienti possono acconsentire esplicitamente usando uno dei metodi descritti in come abilitare l'integrità della memoria.

Compatibilità delle applicazioni

Anche se la compatibilità con l'integrità della memoria è un requisito per tutti i driver dall'aggiornamento dell'anniversario di Windows 10 (1607), alcune applicazioni e driver di dispositivo hardware potrebbero ancora non essere compatibili. Questa incompatibilità può causare malfunzionamenti dei dispositivi o del software e in rari casi può causare un errore di avvio (schermata blu). Questi problemi possono verificarsi dopo l'attivazione della protezione dell'integrità della memoria o durante il processo di abilitazione stesso. Se si è uno sviluppatore di applicazioni e si vuole verificare che i driver e i pacchetti software siano compatibili con l'integrità della memoria, seguire questa procedura.

Alcuni esempi in cui sono state osservate incompatibilità con l'integrità della memoria includono:

  • Soluzioni anti-inganno con giochi
  • Metodi di input di terze parti
  • Protezione delle password bancarie di terze parti

Abbiamo lavorato duramente per attenuare le esperienze interessate, quindi se esiste un'incompatibilità per un driver critico per l'avvio, la protezione dell'integrità della memoria verrà disattivata automaticamente se era stata abilitata automaticamente. Se si verificano incompatibilità con altre app, è consigliabile verificare la presenza di aggiornamenti per l'app specifica e la versione che riscontrano il problema prima di disattivare la protezione dell'integrità della memoria.

Come creare driver compatibili

Poiché le pagine e le sezioni di memoria non possono mai essere scrivibili ed eseguibili, il primo passaggio consiste nel garantire una netta separazione dei dati e del codice e non tentare di modificare direttamente le tabelle codici.

  • Acconsentire esplicitamente a NX per impostazione predefinita
  • Usare API/flag NX per l'allocazione di memoria - NonPagedPoolNx
  • Non usare sezioni scrivibili e eseguibili
  • Non tentare di modificare direttamente la memoria di sistema eseguibile
  • Non usare il codice dinamico nel kernel
  • Non caricare i file di dati come eseguibile
  • L'allineamento delle sezioni deve essere un multiplo di 0x1000 (PAGE_SIZE). Ad esempio, DRIVER_ALIGNMENT=0x1000

Usare la versione più recente di WDK e Visual Studio per produrre driver compatibili quando si usano le impostazioni predefinite.

Come verificare la compatibilità dei driver con l'integrità della memoria

Esistono tre passaggi per verificare la compatibilità dei driver:

  1. Usare Driver Verifier (vedere la sezione seguente) con i controlli di compatibilità dell'integrità del codice abilitati.
  2. Testare il driver in un sistema con l'integrità della memoria abilitata.
  3. Eseguire il test di conformità dell'integrità del codice HyperVisor in Windows HLK.

Controlli di compatibilità del driver Verifier

Driver Verifier ha un flag di opzione di integrità del codice (0x02000000) per abilitare controlli aggiuntivi che convalidano la conformità con l'integrità della memoria. Per abilitare questa operazione dalla riga di comando, usare il comando seguente:

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

Per scegliere questa opzione se si usa l'interfaccia utente grafica del verificatore, scegliere Crea impostazioni personalizzate (per sviluppatori di codice), scegliere Avanti e quindi scegliere Controlli di integrità del codice.

Per l'esito positivo, non è disponibile alcun output. Di seguito è riportato un esempio per un output di errore.

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

Testare il driver con l'integrità della memoria abilitata

Anche se Windows attiva l'integrità della memoria per impostazione predefinita per la maggior parte dei sistemi, esistono diversi motivi che potrebbero impedire che ciò accada. Per attivare l'integrità della memoria, vedere Come attivare l'integrità della memoria. Quindi, testare la funzionalità del driver. Assicurarsi di eseguire tutti i percorsi di codice nel driver per assicurarsi che il driver non esegua operazioni in fase di esecuzione incompatibili con l'integrità della memoria.

Test HLK (desktop e server)

Il test HLK hyperVisor Code Integrity Readiness Test deve superare per consentire l'approvazione dei driver per la firma Microsoft. I driver compatibili con l'integrità della memoria sono necessari per le edizioni desktop e server. Il test HLK è un test di base scritto per assicurarsi che i driver compatibili con l'integrità della memoria vengano caricati correttamente ed eseguiti dal sistema operativo.

Anche se il semplice superamento del test HLK è sufficiente per una firma Microsoft per il driver, è consigliabile eseguire test funzionali completi con l'integrità della memoria abilitata. Ad esempio, potrebbero esserci allocazioni di memoria codificate in modo non corretto violando le protezioni NX che causano errori che non vengono rilevati dal test. L'autore del driver deve testare accuratamente il driver mantenendo l'integrità della memoria abilitata.

Durante lo sviluppo dei driver e durante i test HLK, potrebbe essere necessario disabilitare l'integrità della memoria, in quanto può impedire il caricamento del driver.

Il test di conformità dell'integrità del codice HLK Hypervisor è necessario come parte dell'AQ di Windows Server Assurance e i flag per abilitare i controlli di integrità del codice vengono impostati durante altri test HLK.

Domande frequenti

Che ne dici dei driver esistenti? È necessario ricompilire questi driver per farli funzionare con Windows 10?

Dipende. Molti driver saranno già compatibili. Se si usano le impostazioni standard con le versioni precedenti di WDK e Visual Studio, un problema noto è che la sezione INIT è contrassegnata come RWX. In Windows 10, tuttavia, il W verrà rimosso automaticamente, quindi se questo è l'unico problema, il driver sarà compatibile.

Ricerca per categorie verificare che l'integrità della memoria sia abilitata?

Il metodo più semplice consiste nell'eseguire l'app System Information (msinfo32). Cercare la riga seguente: "Servizi di sicurezza basati su virtualizzazione in esecuzione". Dovrebbe segnalare: "Integrità del codice applicata da Hypervisor". È disponibile anche un'interfaccia WMI per controllare l'uso degli strumenti di gestione, vedere Convalidare le funzionalità di integrità della memoria e vbs abilitate.

L'integrità della memoria può anche essere archiviata nell'app Sicurezza di Windows in Impostazioni> Update & Security> Sicurezza di Windows> Device security Core isolation details>Memory integrity (Integrità della memoria).> Per altre informazioni, vedere KB4096339.

È possibile verificare che l'integrità della memoria sia abilitata a livello di codice dal kernel per modificare il comportamento del driver?

Sì, puoi usare NtQuerySystemInformation: https://msdn.microsoft.com/library/windows/desktop/ms724509(v=vs.85).aspx

La struttura SYSTEM_CODEINTEGRITY_INFORMATION ha un valore 0x400 esposto, che indica che l'integrità della memoria è attiva.

Ricerca per categorie risolvere i problemi di compatibilità?

Oltre a verificare che non ci siano pagine W+X e che le sezioni del driver siano allineate correttamente come indicato in precedenza, il problema più probabile sarà un'allocazione di memoria non corretta. Le informazioni sugli avvisi di analisi del codice correlati all'allocazione di memoria rilasciata sono disponibili in MSDN nella pagina seguente:

Analisi del codice per gli avvisi dei driver

I collegamenti MSDN seguenti illustrano alcuni esempi di API di uso comune che causano l'allocazione della memoria eseguibile, insieme ad alcune correzioni di esempio:

Usare la tabella seguente per interpretare l'output per determinare quali modifiche al codice del driver sono necessarie per risolvere i diversi tipi di incompatibilità HVCI.

Avviso Risoluzione
Tipo di pool di esecuzione Il chiamante ha specificato un tipo di pool eseguibile. Chiamata di una funzione di allocazione di memoria che richiede memoria eseguibile. Assicurarsi che tutti i tipi di pool contengano un flag NX non eseguibile.
Esegui protezione pagina Il chiamante ha specificato una protezione di pagina eseguibile. Specificare una maschera di protezione della pagina "no execute".
Esegui mapping pagina Il chiamante ha specificato un mapping MDL (Executable Memory Descriptor List). Assicurarsi che la maschera usata contenga MdlMappingNoExecute. Per altre informazioni, vedere MmGetSystemAddressForMdl Cassaforte
Sezione Execute-Write L'immagine contiene una sezione eseguibile e scrivibile.
Errori di allineamento sezione L'immagine contiene una sezione non allineata alla pagina. L'allineamento delle sezioni deve essere un multiplo di 0x1000 (PAGE_SIZE). Ad esempio, DRIVER_ALIGNMENT=0x1000
Rilocazioni non supportate In Windows 10 versione da 1507 a versione 1607, a causa dell'uso di Address Space Layout Randomization (ASLR) un problema può verificarsi con l'allineamento degli indirizzi e la rilocazione della memoria. Il sistema operativo deve rilocare l'indirizzo da cui il linker imposta l'indirizzo di base predefinito sulla posizione effettiva assegnata da ASLR. Questa rilocazione non può allontanarsi da un limite di pagina. Si consideri ad esempio un valore di indirizzo a 64 bit che inizia in corrispondenza dell'offset 0x3FFC in una pagina. Il valore dell'indirizzo si sovrappone alla pagina successiva in corrispondenza dell'offset 0x0003. Questo tipo di rilocazioni sovrapposte non è supportato prima di Windows 10 versione 1703.

Questa situazione può verificarsi quando un inizializzatore di variabile di tipo struct globale ha un puntatore non allineato a un altro globale, disposto in modo che il linker non possa spostare la variabile per evitare la rilocazione stradling. Il linker tenterà di spostare la variabile, ma in alcune situazioni potrebbe non essere possibile farlo, ad esempio con grandi struct non allineati o matrici grandi di struct non allineati correttamente. Se appropriato, i moduli devono essere assemblati usando l'opzione /Gy (COMDAT) per consentire al linker di allineare il più possibile il codice del modulo.

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

Esistono altre situazioni che coinvolgono l'uso del codice assembler, in cui questo problema può verificarsi anche.

IAT nella sezione Eseguibile La tabella degli indirizzi di importazione (IAT) non deve essere una sezione eseguibile della memoria.

Questo problema si verifica quando l'IAT si trova in una sezione di memoria di sola lettura ed esecuzione (RX). Ciò significa che il sistema operativo non sarà in grado di scrivere nell'IAT per impostare gli indirizzi corretti per dove la DLL a cui si fa riferimento.

Un modo in cui ciò può verificarsi è quando si usa l'opzione /MERGE (Combina sezioni) nel collegamento di codice. Ad esempio, se .rdata (dati inizializzati di sola lettura) viene unito ai dati con estensione text (codice eseguibile), è possibile che l'IAT possa terminare in una sezione eseguibile di memoria.

Quali API sono potenzialmente interessate?

L'elenco seguente di API non riservate per l'uso del sistema può essere interessato:

   
Nome API Descrizione
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