sabato 22 giugno 2019

00 - Introduzione e ambiente di lavoro

Il presente corso è il risultato dell'elaborazione di una serie di appunti presi da me durante lo studio della programmazione lato kernel in ambiente Windows. Per tale motivo, i termini corso e lezioni non vanno intesi con il loro significato convenzionale in quanto non c'è alcuna velleità pedagogica o educativa. Il solo intento è quello di lasciare traccia ed evidenza, soprattutto a me stesso, di tutti gli sforzi ed il tempo che ho dedicato a questo argomento. D'altro canto, l'uso di termini come serie ed articoli (o peggio ancora tutorials) sarebbe stato anche più fuorviante in quanto, nell'immaginario collettivo, vengono associati a risorse che spiegano l'argomento in questione dando per scontato tutto il resto. Questo invece è molto più vicino ad un corso, dove viene spiegato tutto (o quasi) ed il numero di prerequisiti è ridotto al minimo. Si noti che la possibilità che alcuni dettagli non siano corretti o addirittura che intere lezioni siano da rivedere è molto alta (lasciate un commento per segnalare qualsiasi cosa). Fatta questa premessa, in questo corso si vedrà come programmare driver a 64-bit usando il linguaggio C (volendo è possibile usare anche il C++) partendo da zero.
Teoria e codice sorgente attorno a cui si svilupperà il corso prendono spunto da diverse fonti, in particolare:

- Windows Kernel Programming - Pavel Yosifovich (disponibile su leanpub.com ed Amazon)
- Documentazione Microsoft
- https://github.com/microsoft/Windows-driver-samples
- Serie di tutorial scritti da Tesla.Angela (in lingua cinese, cercare "Tesla.Angela" su github)
- https://github.com/DemonGan/Windows-Hack-Programming

Il sistema operativo di riferimento sarà Windows 10 64-bit (esclusa la Home edition) e per il test del codice verrà usata una macchina virtuale creata e gestita attraverso Hyper-V.

Per installare Hyper-V è necessario assicurarsi prima che la virtualizzazione nel BIOS sia attiva (basta cercare su google come fare in rifermento alla propria scheda madre) e, successivamente, seguire la seguente guida:
Installare Hyper-V su Windows 10

Avviare la Console di gestione di Hyper-V come amministratore e selezionare Azione -> Nuovo -> Macchina Virtuale …




In Impostazione Generazione selezionare Generazione $1$. In Configurazione di rete selezionare Default Switch o Opzione predefinita. Per il resto è sufficiente selezionare le impostazioni che vi sembrano più appropriate.




Installare Windows 10 64-bit sulla macchina virtuale appena creata. D'ora in poi questo sarà identificato come sistema operativo Guest (o semplicemente Guest) nel resto dell'articolo. Per Host invece si intenderà l'OS su cui si è installato l'hypervisor (Hyper-V) e su cui verranno sviluppati i driver. Se alla fine dell'installazione del Guest viene chiesto se si vuole consentire al PC di essere individuabile ad altri PC nella rete rispondere SI. Infine aggiornare il Guest (solitamente è conveniente aggiornare alla stessa build dell'Host per minimizzare le differenze tra le strutture interne).
Su Host, in Hyper-V, selezionare il nome della macchina virtuale con il pulsante destro del mouse e cliccare su Impostazioni. In COM 1 scegliere un nome per la pipe (ad esempio Debug) e annotarsi la stringa dopo Percorso named pipe (in questo caso è \\.\pipe\Debug).




In Guest, avviare una console di Prompt dei Comandi come amministratore e dare in successione:

bcdedit /set testsigning on
bcdedit /debug on
bcdedit /dbgsettings serial debugport:1 baudrate:115200

Assicurandosi che il numero dopo debugport sia uguale a quello della porta COM selezionata in precedenza nelle impostazioni della scheda di rete della macchina virtuale (si veda immagine sopra).
Ravviare il Guest. A questo punto è necessario che Host e Guest siano in grado di comunicare l'uno con l'altro. A questo scopo sia su Host che su Guest bisogna aprire una console di Prompt dei Comandi e dare:

ping DESKTOP-XXXXX

dove XXXXX è il nome del computer dell'altro OS (lo trovi in Pannello di Controllo -> Sistema e Sicurezza -> Sistema -> Nome computer). Per capirci, se si sta pingando prima dal prompt di Host bisogna inserire il nome del computer di Guest e successivamente pingare dal Guest inserendo il nome di Host.
Se si riscontrano problemi nel pingare, sull'OS che non si lascia pingare (cioè quello su cui non è aperto il prompt che da errore o pacchetti persi), andare in Pannello di Controllo -> Rete e Internet -> Centro Connessioni di Rete e Condivisione -> Modifica impostazioni di condivisione avanzate e mettere tutto su Attiva (sia in Individuazione rete che in Condivisione file e stampanti).




Se ancora non si riesce a pingare si provi a modificare singolarmente le voci "Condivisione file e stampanti" e "Individuazione rete" in Pannello di Controllo -> Sistema e Sicurezza -> Windows Defender Firewall -> Impostazioni Avanzate -> Regole connessioni in entrata (modificare solo quelle voci che hanno un profilo uguale alla connessione in possesso).

In Host, controlla che SDK e WDK siano installati e che le versioni siano quelle collegate alla build di Windows 10 posseduta, si veda:

https://developer.microsoft.com/it-it/windows/downloads/sdk-archive
https://docs.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk
https://docs.microsoft.com/en-us/windows-hardware/drivers/other-wdk-downloads

In caso contrario disinstallare tutte le versioni di SDK e WDK possedute ed installare solo la versione corretta per entrambi i pacchetti. Se durante l'installazione viene chiesto se installare qualche plug-in per l'integrazione in Visual Studio rispondere SI.

In Host cercare il file WDK Test Target Setup x64-x64_en-us.msi, di solito lo si può trovare in:

C:\Program Files (x86)\Windows Kits\10\Remote\x64\WDK Test Target Setup x64-x64_en-us.msi

copiare questo file in Guest ed avviarlo, sempre in Guest.
In Host, aprire Visual Studio come amministratore poi Driver -> Test -> Configure Devices -> Add New Device.





In Display Name metti quello che vuoi. In Network Host Name metti il nome computer del Guest (DESKTOP-XXXXX). Spunta Manually configure debuggers and not provision e clicca Avanti. In Connection Type metti Serial. In Baud Rate  metti 115200. Applica la spunta a tutte le voci che seguono. In Pipe name metti quello che hai impostato in Hyper-V (ad esempio \\.\pipe\Debug). In Target Port metti com1.




Alla fine Status deve essere Configured for driver testing  e non Unavailable. Se è Unavailable controllare che il Guest sia avviato e che Target Port sia compatibile con il valore impostato per debugport (se si è impostato debugport:1, Target Port deve essere com1). Inoltre si provi a disattivare il Firewall del Guest. Se tutto questo non dovesse funzionare si provi a cercare una soluzione in rete, alla fine si trova sempre e, male che vada, si può sempre debuggare direttamente con WinDbg.




Nel Guest aprire RegEdit e aggiungere (se già non presente) la chiave "Debug Print Filter" a

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\

Aggiungere quindi una DWORD chiamata DEFAULT impostandone il valore a 8. Questo permette di visualizzare le stringhe di testo passate a DbgPrint in tool come DebugView.




Tutta questa procedura va effettuata solo una volta.
A questo punto si è pronti a sviluppare ogni tipo di driver con Visual Studio nell'Host e a debuggarlo nel Guest.

6 commenti:

  1. Risposte
    1. Corretto! Piacere di conoscerti, la combo driver+geometria nei tuoi articoli mi fa pensare che sviluppi qualche bot, oppure segui l argomento per passione?
      È pura curiosità in quanto seguo abbastanza l argomento online è non mi sono mai imbattuto in una community italiana

      Elimina
    2. Ciao, il piacere è mio. Il reverse engineering mi ha sempre affascinato molto e di conseguenza spesso prende il sopravvento anche nell'ambito di altri argomenti che mi interessano tipo sistemi operativi e game programming (just for fun, not for profit).
      Comunità italiane? Quando cerchi qualcosa di specifico sullo sviluppo di driver in italiano e ti esce il nulla o un mio articolo scritto nel 2019 allora ti accorgi che la situazione è a dir poco sconfortante. Ma è anche vero che è così ormai in tutta europa ed io c'ho fatto l'abitudine (non ci faccio neanche più caso).

      Elimina
    3. Ahah ero convinto che ci fosse anche un profit dietro alla fine, tra l'altro se vedi quelli che offrono servizi come i bot come SaaS ti rendi conto che sono delle attività anche piuttosto redditizie:
      questo in particolare esiste dai tempi in cui giocavo ad unreal tournament 2004 https://www.artificialaiming.net/forum/home.php.

      Discorso community: se la lingua non è un problema ti consiglio https://www.mpgh.net/ e https://www.reddit.com/r/ReverseEngineering/ altrimenti Twitter dove potrai trovare molti esperti di cyber-security.

      Elimina
    4. La mia è solo una passione che mi porto dietro fin dall'adolescenza, periodo che ho superato già da diverse decadi quindi puoi ben immaginare che conosca più o meno tutte le comunità sul reversing (gaming e non).

      Elimina
    5. Scusami allora avevo inteso male il tuo precedente post, buon reversing!

      Elimina