martedì 11 gennaio 2022

06 - Comunicazione Client-Hypervisor

Finora si è usato un client al solo scopo di avviare la VMX operation. Sarebbe interessante sfruttare tale applicazione user mode anche per ricevere eventuali messaggi da parte del driver che implementa l'hypervisor, senza che si debba scomodare ogni volta il debugger. Per ricevere messaggi dal driver è necessario implementare un sistema di comunicazione client-driver. In questa lezione si userà il metodo ideato e sviluppato da Mohammad Sina Karvandi per la sua serie di tutorial Hypervisor from Scratch (si veda [1]). A grandi linee, l'idea alla base di tale sistema può essere rappresentata visivamente dalla seguente immagine.



In pratica, il driver scrive i suoi messaggi in uno tra due buffer in kernel mode. Il buffer non-immediate accumula messaggi ed evita di occupare troppi elementi dell'immediate buffer. Una volta che il non-immediate buffer è pieno viene copiato in un elemento dell'immediate buffer. Il client invia ciclicamente richieste al driver (tramite DeviceIoControl) per indicargli che è pronto a ricevere i suoi messaggi. Se il driver ne ha scritto qualcuno nell'immediate buffer allora accoda una DPC al processore corrente che verrà eseguita non appena l'IRQL associato a tale CPU sarà minore o uguale a DISPATCH_LEVEL. La funzione di callback eseguita non fa altro che copiare il messaggio dall'immediate buffer al buffer user mode, pronto per essere letto dal client.
Naturalmente ci sono molti altri dettagli da considerare e che verranno esaminati in questa lezione ma avere un quadro generale della situazione potrà aiutare non poco nel momento in cui si andrà ad analizzerà il codice.


domenica 12 dicembre 2021

05.C - Uscire dalla VMX operation

Una volta lanciato Windows 10 come guest e supportato Hyper-V, restituendogli le VM exit di sua competenza, sarebbe auspicabile trovare un modo per uscire dalla VMX operation e tornare ad eseguire il sistema operativo normalmente. L'idea è la seguente: eseguire una VMCALL dal nostro driver (in non-root operation) per indicare al nostro hypervisor (in root operation) di eseguire VMXOFF e riprendere ad eseguire codice normalmente.  Come richiamare l'attenzione dell'hypervisor tramite VMCALL è argomento ormai noto in quanto già affrontato nelle precedenti due lezioni. La vera novità è trovare un modo per ritornare ad eseguire codice una volta usciti dalla VMX operation. In realtà, anche questo è un argomento che si è già affrontato, in un certo senso, quando si voleva riprendere ad eseguire codice una volta entrati in VMX operation. Ad ogni modo, nulla verrà lasciato al caso e tutto verrà spiegato nei dettagli nel corso di questa lezione.


sabato 11 dicembre 2021

05.B - Convivere con Hyper-V

Per testare il nostro driver su una macchina virtuale gestita da Hyper-V è necessario prendere coscienza del fatto che l'hypervisor implementato in esso si mette in mezzo tra Hyper-V e Windows 10 in quanto verrà trattato come guest speciale a cui vengono passate tutte le VM exit. Questo non sarebbe un problema se, come già detto in una lezione precedente, Windows 10 non richiedesse supporto ad Hyper-V per svolgere alcuni dei suoi compiti in modo alternativo rispetto al solito. Se tutte le VM exit vengono passate al nostro hypervisor allora è necessario catturare quelle destinate a Hyper-v e ripassargliele per farle gestire a lui. La domanda è quindi: quali sono le VM exit destinate ad Hyper-V? Fortunatamente a facile rispondere a tale domanda in quanto esiste una documentazione specifica che indica quale dovrebbe essere l'interfaccia pubblica di un hypervisor conforme alle specifiche indicate da Microsoft. Il documento in questione è linkato a fine lezione nei riferimenti, si veda [5].


giovedì 9 dicembre 2021

05.A - Lanciare Windows 10 come guest

Prima di poter essere in grado di sottoporre l'intero sistema operativo correntemente in esecuzione alla supervisione del nostro hypervisor è necessario trovare un modo per lanciarlo come guest. Questa lezione (insieme alle prossime due) cercherà di spiegare un modo per ottenere tale risultato. Il codice di esempio è fortemente ispirato a quello di alcuni hypervisor (si vedano i riferimenti a fine lezione) che hanno codice sorgente consultabile pubblicamente. A loro vanno tutti riconoscimenti del caso.




L'idea di base, per lanciare Windows 10 come guest, è quella di caricare il driver del nostro hypervisor e salvare lo stato dei registri in un punto X della sua esecuzione prima di entrare in VMX operation. Fatto questo si può dirottare l'esecuzione al solo fine di entrare in tale modalità operativa, inizializzare la VMCS e lanciare il guest. In questo modo sarà sufficiente indicare al guest di riprendere ad eseguire il codice dal punto X nel nostro driver per ottenere il risultato desiderato: eseguire l'intero OS come guest. Vediamo come mettere in codice quanto appena descritto a parole.



lunedì 15 novembre 2021

4.F - Demo: Inizializzare la VMCS e lanciare il guest

In questa lezione si cercherà di mettere a frutto quanto imparato nelle lezioni precedenti creando un semplice hypervisor che esce dalla VMX operation se il guest esegue l'istruzione HLT. L'immagine seguente mostra i messaggi mostrati dal debugger che vengono generati da tale hypervisor.




Per non rendere troppo tedioso il discorso si eviterà di mostrare nuovamente il codice già analizzato nel corso delle precedenti lezioni. Il progetto completo può essere visionato cliccando sul link fornito a fine lezione.



giovedì 11 novembre 2021

04.E - VMCS: VM-entry e VM-exit control (ed information)

Le ultime tre aree che compongono la VMCS verranno esaminate in questa lezione e completeranno il discorso sull'inizializzazione dei campi che si trovano in tale struttura. La seguente immagine mostra solo due di queste tre aree ma quella mancante (VM-Entry Control) non è certamente meno importante.





mercoledì 10 novembre 2021

04.D - VMCS: VM-execution control

La VM-execution control contiene tutti quei campi in grado di controllare e governare l'esecuzione in non-root operation. In particolare, attraverso tali campi l'hypervisor può indicare quali sono le istruzioni eseguite e gli eventi generati dal guest che provocano una VM exit, e che quindi devono cedergli il controllo al fine di controllare l'esito finale di tali operazioni. L'immagine seguente fornisce una rappresentazione visiva della VM-execution control. Gli elementi con sfondo bianco rappresentano bit che appartengono al campo di bit arancione sull'estrema sinistra.




Verranno tralasciati (cioè impostati a zero) tutti quei campi\bit ritenuti marginali o non essenziali per un corso di base sulla virtualizzazione delle CPU. Allo stesso modo, verranno momentaneamente inizializzati a zero alcuni campi\bit particolarmente importanti nelle fasi successive del corso. Nelle seguenti sezioni verranno esaminati brevemente molti campi di interesse che compongono la VM-execution control. Per alcuni di questi campi verrà fornita una spiegazione più approfondita nel corso delle successive lezioni.