<index> / <windows-internals> / dev-setup
[ en | fr ]
┌───────────────────────┐
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
└───────────────────────┘
Configuration de l'environnement de dev de drivers
Windows
~ lululufr
SOMMAIRE
  0  pourquoi un driver
  1  logiciels requis
  2  configuration système
  3  premier projet — kmdf hello world
  4  exécuter le driver
  5  débogage kernel avec windbg

──[ 0. Pourquoi un Driver ]──

Un driver, c'est ce qui permet à un OS de parler au matériel. Pour ce qu'on veut 
faire — kernel callbacks, minifilters, internes d'EDR — il nous faut du code
kernel-mode, donc un driver. Windows Driver Frameworks (WDF) s'installe au-dessus du WDM (Windows Driver
Model) brut et te mâche pas mal de boilerplate :
    KMDF (Kernel-Mode Driver Framework)
        Tourne en Ring 0. Accès kernel complet. Un bug = BSOD.
        Ce qu'il faut pour les callbacks, minifilters, DKOM, etc.

    UMDF (User-Mode Driver Framework)
        Tourne en Ring 3. Bien plus safe, beaucoup plus limité.
        Inutile pour bosser sur de l'EDR.

Cette série utilise KMDF de bout en bout.
──[ 1. Logiciels Requis ]──

OS cible : Windows 11 Pro (l'environnement sur lequel ce cours a été monté).

Visual Studio 2022
    L'IDE standard de Microsoft. À l'install, choisis :
    "Desktop Development with C++"

    Puis ajoute ces composants individuels :

        MSVC v143 — VS 2022 C++ x64/x86 Spectre-mitigated libs
        MSVC v143 — VS 2022 C++ ARM64/ARM64EC Spectre-mitigated libs
        C++ ATL for latest v143 build tools with Spectre (x86 & x64)
        C++ ATL for latest v143 build tools with Spectre (ARM64/ARM64EC)
        C++ MFC for latest v143 build tools with Spectre (x86 & x64)
        C++ MFC for latest v143 build tools with Spectre (ARM64/ARM64EC)
        Windows Driver Kit
Visual Studio — sélection des composants individuels
Visual Studio — installation en cours
Windows SDK
    Va avec le WDK. ~3,5 Go. À installer avant le WDK.
Windows SDK — installeur
Windows Driver Kit (WDK)
    ~2 Go. Les headers kernel, les libs, le build system des drivers.
    Nécessite Visual Studio et le SDK déjà installés.
WDK — installeur
──[ 2. Configuration Système ]──

Deux réglages à changer avant de pouvoir bosser.

Mode Test Signing
    Windows refuse les drivers non signés par défaut (DSE). Le test
    signing permet de charger des drivers auto-signés ou non signés :
        bcdedit /set testsigning on
Note : le Secure Boot doit être off au préalable — test signing et
    Secure Boot ne cohabitent pas (voir l'article ELAM pour pourquoi).

Sortie Debug Kernel
    Les drivers écrivent leur sortie debug via KdPrintEx(). Pour la voir,
    active le debug kernel :
        bcdedit /debug on
bcdedit — sortie indiquant que le mode debug est activé
Ensuite, crée le filtre debug dans le registre :
        Clé de registre : HKLMSYSTEMCurrentControlSetControl
                          Session ManagerDebug Print Filter
        Nouveau DWORD :   DEFAULT = 8
Registre — DWORD Debug Print Filter mis à 8
──[ 3. Premier Projet — KMDF Hello World ]──

Crée un nouveau projet driver KMDF dans Visual Studio, ajoute un fichier source 
.c.
Visual Studio — dialogue nouveau projet driver KMDF
Visual Studio — assistant de création de projet (étape 2)
Visual Studio — ajout d'un nouveau fichier source .c
Visual Studio — fichier .c ajouté au projet
Si ntddk.h est introuvable, ajoute le chemin d'include à la main :
    C:Program Files (x86)Windows Kits10Include<build>km
VS — config des additional include directories
VS — chemin d'include ajouté
    #include <ntddk.h>
    #include <wdf.h>

    DRIVER_INITIALIZE DriverEntry;
    EVT_WDF_DRIVER_DEVICE_ADD KmdfHelloWorldEvtDeviceAdd;

    NTSTATUS DriverEntry(
        _In_ PDRIVER_OBJECT  DriverObject,
        _In_ PUNICODE_STRING RegistryPath)
    {
        NTSTATUS status;
        WDF_DRIVER_CONFIG config;

        KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
            "HelloWorld: DriverEntry\n"));

        WDF_DRIVER_CONFIG_INIT(&config, KmdfHelloWorldEvtDeviceAdd);

        status = WdfDriverCreate(
            DriverObject, RegistryPath,
            WDF_NO_OBJECT_ATTRIBUTES, &config, WDF_NO_HANDLE);

        return status;
    }

    NTSTATUS KmdfHelloWorldEvtDeviceAdd(
        _In_    WDFDRIVER       Driver,
        _Inout_ PWDFDEVICE_INIT DeviceInit)
    {
        UNREFERENCED_PARAMETER(Driver);
        NTSTATUS status;
        WDFDEVICE hDevice;

        KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
            "HelloWorld: DeviceAdd\n"));

        status = WdfDeviceCreate(&DeviceInit,
            WDF_NO_OBJECT_ATTRIBUTES, &hDevice);

        return status;
    }
VS — definitions du préprocesseur (config KMDF)
──[ 4. Exécuter le Driver ]──

Build : Build → Build Solution dans Visual Studio.
VS — menu Build Solution
Charge-le via le Service Control Manager (terminal admin) :
    sc.exe create MyDriver type=kernel binPath="C:\path\to\driver.sys"
    sc.exe start MyDriver
sc.exe — driver chargé et démarré
Décharge :
    sc.exe stop MyDriver
    sc.exe delete MyDriver
──[ 5. Débogage Kernel avec WinDbg ]──

Pour du vrai debug il te faut deux machines : un host (WinDbg) et une cible (ton 
driver). Le kernel debugger te donne les breakpoints, l'inspection mémoire,
l'introspection kernel en direct.
WinDbg — interface du kernel debugger Microsoft
Côté machine cible
    Mêmes commandes bcdedit qu'à l'étape 2, plus la cible réseau :
        bcdedit /dbgsettings net hostip:<HOST_IP> port:50000
Installe le MSI WDK Test Target sur la cible :
        "C:\Program Files (x86)\Windows Kits\10\Remote\x64\
         WDK Test Target Setup x64-x64_en-us.msi"
Monte la verbosité du debug :
        reg add "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\
                 Debug Print Filter" /v IHVDRIVER /t REG_DWORD /d 0xFFFFFFFF /f
VM cible — mode debug configuré
Côté host
    Installe WinDbg depuis le Microsoft Store.
    Configure la cible de débogage distant dans Visual Studio.
VS — config de la cible remote debugger (étape 1)
VS — config de la cible remote debugger (étape 2)
VS — config de la cible remote debugger (étape 3)
Branche WinDbg sur la cible par le réseau.
WinDbg — lancé et en attente de la cible
WinDbg — connecté au kernel cible
Commandes WinDbg utiles
    bu MyDriver!DriverEntry     Breakpoint sur DriverEntry
    g                           Continue jusqu'au prochain breakpoint
    t                           Step Into (entre dans les fonctions appelées)
    p                           Step Over (saute les fonctions appelées)
    lm                          Liste les modules chargés
    !process 0 0                Liste tous les processus
    db <addr>                   Dump les octets à l'adresse
WinDbg — en attente du lancement du processus (run et hit du breakpoint)
WinDbg — arrêté sur le breakpoint DriverEntry
WinDbg — indicateur de débogage actif
sequenceDiagram
    participant V as Visual Studio (Host)
    participant W as WinDbg (Host)
    participant T as Cible Windows

    V->>T: Déploie le fichier .sys
    W->>T: Attache via le réseau
    T->>W: Break sur DriverEntry
    Note over W: Pose des breakpoints, inspecte la mémoire
    W->>T: g (continue)
    T->>W: Sortie KdPrintEx visible
Une fois le debugger attaché, tu peux mettre en pause le kernel de la cible, 
inspecter registres et mémoire, et avancer dans ton driver instruction par
instruction.
WinDbg — sortie KdPrintEx visible après stepping