Delen via


Ontwikkelingshandleiding voor VBS-enclaves (virtualization-based security)

Van toepassing op:✅ Windows 11 Build 26100.2314 of hoger ✅ Windows Server 2025 of hoger

In deze handleiding wordt beschreven hoe u een eenvoudige VBS-enclave bouwt, ondertekent en debugt.

Vereiste voorwaarden

Als u aan de slag wilt met VBS Enclaves, moet u aan de volgende vereisten voldoen:

  • Bekijk en voldoet aan apparaatvereisten in het overzicht van VBS Enclaves.
  • Bekijk en voldoet aan de vereisten voor ontwikkeling in het overzicht van VBS Enclaves.
    • Het is raadzaam om de desktopontwikkeling met C++ -werkbelasting te installeren via het Visual Studio-installatieprogramma. Hiermee worden alle benodigde hulpprogramma's geïnstalleerd, waaronder de Windows Software Development Kit (SDK).
  • Download de voorbeeldcode van GitHub. Het demonstreert de levenscyclus van een VBS enclave, waaronder het uitvoeren van functieaanroepen naar de enclave.
    • Elke enclave moet een host-app hebben. De voorbeeldcode bevat een Visual Studio Solution met twee projecten: de enclavehost en de test-enclave.

Waarschuwing

Zorg ervoor dat u de besturingssysteemondersteuning voor VBS-enclaves hierboven hebt bekeken, omdat de ondersteuning onlangs is gewijzigd.

Aan de slag

Nadat u aan de bovenstaande vereisten hebt voldaan, moet u het oplossingsbestand kunnen openen vanuit het VbsEnclave-voorbeeld in Visual Studio en het compileren. Er wordt een testtoepassing gemaakt, samen met de bijbehorende enclave. U kunt uw toepassing echter pas uitvoeren als de enclave is ondertekend met een geldig certificaat.

In deze handleiding wordt beschreven hoe u een eenvoudige VBS-enclave bouwt op uw ontwikkelcomputer. De stappen voor het bouwen van een VBS-enclave zijn:

  1. Een VBS enclave-DLL en een bijbehorende hosttoepassing schrijven
  2. De DLL en host compileren
  3. De VBS enclave-DLL ondertekenen
  4. Fouten opsporen in de VBS-enclave

Laten we beginnen met het begrijpen van de levenscyclus van een enclave. De enclave-API's worden in de volgende volgorde aangeroepen:

Diagram waarin de volgorde wordt weergegeven waarin VBS Enclaves-API's worden aangeroepen

Stap 1: VBS-enclaves schrijven

Laten we de voorbeeldcode bekijken en begrijpen hoe u een toepassing schrijft die gebruikmaakt van een VBS-enclave.

Het programmeren van de Enclave Host

Houd er rekening mee dat een VBS enclave-DLL gewoon een DLL is en daarom een hosttoepassing vereist. De hosttoepassing is niets anders dan een standaard Windows-toepassing. Als u VBS-enclaves wilt gebruiken, moet de host Windows enclave-API's van de enclaveapi.h-header gebruiken. Opnemen windows.h in uw hosttoepassing biedt toegang tot deze API's.

Het DLL-bestand schrijven om te laden in een test-enclave

Raadpleeg de voorbeeldcode in het project Test enclave om deze te volgen, samen met de onderstaande stappen.

In ons voorbeeld van een enclave maken we een eenvoudige enclave die de invoer met 0xDADAF00D door middel van XOR bewerkt en het resultaat retourneert. Laten we eens bekijken hoe we dat doen:

  1. Begin met winenclave.h opnemen. Raadpleeg in de voorbeeldcode: Samples/VbsEnclave/Test enclave/precomp.h

    #include <winenclave.h>
    

    winenclave.his het centrale include-bestand voor VBS-enclaves en zelf omvat windows.h, ntenclv.h. winenclaveapi.h

  2. Elke DLL die in een enclave wordt geladen, vereist een configuratie. Deze configuratie wordt gedefinieerd met behulp van een globale const variabele met de naam __enclave_config van het type IMAGE_ENCLAVE_CONFIG. Raadpleeg in de voorbeeldcode: Samples/VbsEnclave/Test enclave/enclave.c

    const IMAGE_ENCLAVE_CONFIG __enclave_config = {
        sizeof(IMAGE_ENCLAVE_CONFIG),
        IMAGE_ENCLAVE_MINIMUM_CONFIG_SIZE,
        IMAGE_ENCLAVE_POLICY_DEBUGGABLE,    // DO NOT SHIP DEBUGGABLE ENCLAVES TO PRODUCTION
        0,
        0,
        0,
        { 0xFE, 0xFE },    // family id
        { 0x01, 0x01 },    // image id
        0,                 // version
        0,                 // SVN
        0x10000000,        // size
        16,                // number of threads
        IMAGE_ENCLAVE_FLAG_PRIMARY_IMAGE
    };
    

    Opmerking

    Er kan slechts één primaire afbeelding per enclave zijn. Als u meerdere primaire afbeeldingen laadt, wordt de eerst geladen afbeelding als primair behandeld en de rest als afhankelijkheden beschouwd. In dit voorbeeld zijn er geen andere afhankelijkheden dan de enclaveplatform-DLL's.

  3. De DllMain() functie is verplicht en definieert het toegangspunt in de enclave. Het wordt genoemd tijdens InitializeEnclave(). Raadpleeg Samples/VbsEnclave/Test enclave/enclave.c in de voorbeeldcode.

    BOOL
    DllMain(
        _In_ HINSTANCE hinstDLL,
        _In_ DWORD dwReason,
        _In_ LPVOID lpvReserved
    )
    {
        UNREFERENCED_PARAMETER(hinstDLL);
        UNREFERENCED_PARAMETER(lpvReserved);
    
        if (dwReason == DLL_PROCESS_ATTACH) {
            InitialCookie = 0xDADAF00D;
        }
    
        return TRUE;
    }
    
  4. Alle functies in de enclave die vanuit de hosttoepassing worden aangeroepen, moeten worden geëxporteerd en van het type LPENCLAVE_ROUTINE zijn. De functiehandtekening ziet er als volgt uit:

    void* CALLBACK enclaveFunctionName(_In_ void* Context)
    

    Raadpleeg Samples/VbsEnclave/Test enclave/enclave.c in de voorbeeldcode.

    void*
    CALLBACK
    CallEnclaveTest(
        _In_ void* Context
    )
    {
        WCHAR String[32];
        swprintf_s(String, ARRAYSIZE(String), L"%s\n", L"CallEnclaveTest started");
        OutputDebugStringW(String);
    
        return (void*)((ULONG_PTR)(Context) ^ InitialCookie);
    }
    

    Opmerking

    Alleen de functies die door de primaire enclave-installatie worden geëxporteerd, zijn toegankelijk vanuit de hosttoepassing.

    Vervolgens kunt u de functie exporteren met behulp van een .DEF bestand. Raadpleeg Samples/VbsEnclave/Test enclave/vbsenclave.def in de voorbeeldcode. Raadpleeg Exporteren vanuit een DLL met behulp van DEF-bestanden voor meer informatie.

En dat is hoe u een eenvoudige VBS enclave-DLL schrijft.

Belangrijk

Houd er rekening mee dat voor het lezen/schrijven van normaal geheugen (niet-enclave) het gebruik van de enclavegeheugentoegangsors (EnclaveCopyOutOfEnclave en EnclaveCopyIntoEnclave) sterk wordt aanbevolen. Zorg ervoor dat alle geheugentoegang tot normaal geheugen via deze accessors plaatsvindt.

Stap 2: VBS-enclaves compileren

Nu we onze VBS enclave-DLL hebben geschreven, gaan we het compileren.

De enclavehost compileren

Het compileren van de host-app is hetzelfde als het compileren van een Windows-toepassing, maar met toevoeging van onecore.lib aan de lijst met afhankelijkheden bij het koppelen.

Het dll-bestand van de test enclave compileren

Voordat we de DLL van de test enclave kunnen bouwen, zijn enkele wijzigingen in de compiler- en linkerconfiguraties vereist:

  1. De MSVC-linker biedt een /ENCLAVE vlag waarmee de configuratiedetails van de enclave worden opgehaald. De /ENCLAVE vlag is niet compatibel met incrementele koppeling, dus we moeten instellen /INCREMENTAL:NO.

  2. [Alleen foutopsporingsconfiguratie]/EDITANDCONTINUE is niet compatibel met /INCREMENTAL:NO, dus we gebruiken /Zi in plaats van /ZI voor foutopsporingsgegevensindeling in de compiler.

  3. [Alleen foutopsporingsconfiguratie] De configuratie basisruntimecontroles moet worden ingesteld op Standaard. Runtimefout-controles worden niet ondersteund in VBS-enclaves.

  4. De digitale handtekening van een enclave-DLL moet bij het laden worden gecontroleerd en vereist dat de /INTEGRITYCHECK-vlag in de linker wordt ingesteld.

  5. Enclave-DLL's moeten worden voorzien van Control Flow Guard (CFG), waarvoor we de /GUARD:MIXED-vlag in de linkeroptie gebruiken.

  6. Enclaves hebben hun eigen versies van platform, opstarten, runtime en UCRT-bibliotheken. Gebruik de /NODEFAULTLIB vlag om ervoor te zorgen dat de niet-enclaveversies niet worden gekoppeld. Voeg vervolgens de juiste bibliotheken toe onder AdditionalDependencies. In de voorbeeldcode worden deze bibliotheken ingekapseld onder de VBS_Enclave_Dependencies macro. De volgende zijn de VBS-enclavebibliotheken:

    1. libcmt.lib and libvcruntime.lib - Gevonden in de enclave map met de Visual C++ build tools, zie C Runtime (CRT) en C++ standard library (STL) .lib-bestanden.
    2. vertdll.lib en bcrypt.lib - gevonden in de um map met de Windows SDK-bibliotheken.
    3. ucrt.lib - Gevonden in de ucrt_enclave map met de Windows SDK-bibliotheken.

Opmerking

Er worden geen andere platformbibliotheken ondersteund binnen VBS-enclaves.

Kortom, de volgende wijzigingen zijn vereist:

Compiler (alleen foutopsporingsconfiguratie):

  • Foutopsporingsgegevens-indeling: /Zi
  • Basisruntimecontroles: Default

Linker:

  • /ENCLAVE
  • /NODEFAULTLIBS + AdditionalDependencies
  • /INCREMENTAL:NO
  • /INTEGRITYCHECK
  • /GUARD:MIXED

U kunt nu de enclave-DLL compileren.

Beveiligen met VEIID

VEIID (het hulpprogramma VBS Enclave Import ID Binding) is een hulpprogramma in de Windows SDK waarmee de importtabellen in een VBS-enclave worden bijgewerkt met bekende id's voor platform-DLL's. Dit verbetert de beveiliging van VBS-enclaves door te voorkomen dat een schadelijk (ondertekend) DLL-bestand met dezelfde naam als een van de platform-DLL's wordt geladen.

In de voorbeeldcode wordt dit automatisch uitgevoerd als een gebeurtenis na de build.

Opmerking

Het wordt sterk aanbevolen om te voorkomen dat u uw eigen niet-primaire DLL's gebruikt, afgezien van de platform-DLL's. Bewaar in plaats daarvan al uw code in de enclave-DLL zelf.

Stap 3: VBS enclave-DLL's ondertekenen

VBS-enclaves moeten zijn ondertekend om te kunnen worden geladen. De handtekening op een enclave bevat informatie over de auteur van de enclave. Dit wordt gebruikt om de auteur-id voor een enclave af te leiden. U kunt een testhandtekening op uw enclave zetten voordat u deze definitief ondertekent voor productie.

Testondertekening - Lokaal

Voor elk enclaveondertekeningscertificaat zijn minimaal 3 EKU's vereist:

  1. Code-ondertekening EKU - 1.3.6.1.5.5.7.3.3

  2. Enclave-EKU - 1.3.6.1.4.1.311.76.57.1.15

  3. Auteur EKU: de EKU is van de vorm 1.3.6.1.4.1.311.97.X.Y.Z..., waar X groter is dan 999. Hiermee ... worden extra waarden in de EKU-indeling aangegeven. Zie het onderstaande voorbeeld voor meer informatie.

    Voor het testen kunt u ervoor kiezen om elke auteur-EKU te gebruiken die overeenkomt met dit patroon. Voor productie wordt een Author EKU verstrekt als onderdeel van het productiecertificaat ( hieronder vindt u meer informatie over productieondertekening).

    Voorbeeld: 1.3.6.1.4.1.311.97.814040577.346743379.4783502.105532346

Als u uw enclave-DLL wilt ondertekenen tijdens het ontwikkelen, schakelt u testondertekening in. Als testondertekening is ingeschakeld, kunt u een certificaat met deze drie EKU's maken en uw enclave ermee ondertekenen. U kunt de cmdlet New-SelfSignedCertificate gebruiken om een certificaat te maken. Enclave-DLLs moeten ondertekend zijn met een pagina-hash.

Opmerking

Zodra u een certificaat hebt, kunt u het ondertekeningsproces in de gebeurtenis na de build automatiseren.

New-SelfSignedCertificate -CertStoreLocation Cert:\\CurrentUser\\My -DnsName "MyTestEnclaveCert" -KeyUsage DigitalSignature -KeySpec Signature -KeyLength 2048 -KeyAlgorithm RSA -HashAlgorithm SHA256 -TextExtension "2.5.29.37={text}1.3.6.1.5.5.7.3.3,1.3.6.1.4.1.311.76.57.1.15,1.3.6.1.4.1.311.97.814040577.346743379.4783502.105532346"
signtool sign /ph /fd SHA256 /n "MyTestEnclaveCert" vbsenclave.dll

Als uw enclave-DLL is ondertekend, kunt u deze nu laden in een omgeving waarvoor testondertekening is ingeschakeld.

Productieondertekening : vertrouwde ondertekening (voorheen Azure-codeondertekening)

Productieondertekening van enclaves vindt plaats via het VBS-enclavecertificaatprofiel in Trusted Signing. Raadpleeg de documentatie voor meer informatie over het gebruik van vertrouwde ondertekening.

Met vertrouwde ondertekening kunt u uw enclave ook ondertekenen op de commandoregel. Hiermee wordt een kant-en-klare, ondertekende enclave uitgevoerd wanneer u uw enclave in Visual Studio bouwt.

Stap 4: Foutopsporing van VBS-enclaves

Normaal gesproken is het geheugen van een enclave verborgen voor foutopsporingsprogramma's en wordt beveiligd tegen VTL0. Als u echter fouten wilt opsporen in uw VBS enclave-DLL, kunt u deze bouwen om fouten op te sporen tijdens de ontwikkeling. Enclaves zijn een proces voor de gebruikersmodus van VTL1 en kunnen daarom worden opgespoord met een foutopsporingsprogramma in de gebruikersmodus.

Ga als volgende te werk om uw enclave foutopsporing mogelijk te maken:

  1. De configuratie van de enclave-DLL-installatiekopieën moet foutopsporing toestaan . Dit wordt gedaan door de vlag IMAGE_ENCLAVE_POLICY_DEBUGGABLE in IMAGE_ENCLAVE_CONFIG in te stellen.
  2. Foutopsporing moet worden toegestaan tijdens het maken van enclaves . Dit wordt gedaan door de ENCLAVE_VBS_FLAG_DEBUG vlag in te stellen in de ENCLAVE_CREATE_VBS_INFO structuur die wordt doorgegeven aan de aanroep CreateEnclave .

Fouten opsporen in uw enclave:

  1. Koppel het foutopsporingsprogramma in de gebruikersmodus aan het enclavehostproces.
  2. Laad de enclavesymbolen opnieuw nadat het hostproces de enclave-afbeelding in het geheugen heeft geladen.
  3. Stel onderbrekingspunten in voor de functies in de enclave. Het foutopsporingsprogramma breekt er in op een enclave-aanroep.

U kunt ook breken op de onderbrekingspunten in de gebruikersmodus voor CreateEnclave, InitializeEnclave, enzovoort, die verder ingaan op de bijbehorende code in ntdll.dll.

Opmerking

Gebruik nooit foutopsporingsbare enclaves in productieomgevingen.

Hiermee kunt u nu uw eerste VBS-enclave bouwen en implementeren. Neem contact op met de ondersteuning van Windows-ontwikkelaars als u vragen hebt.

Overzicht van VBS Enclaves

Vertrouwde ondertekening van Azure

enclaveapi.h-header

API's die beschikbaar zijn in VBS-enclaves