Sviluppo di una macchina virtuale / sandbox

2

Sono interessato ad apprendere come funziona realmente una macchina virtuale / sandbox. Ho sviluppato un emulatore 8051 e ho anche scritto un disassemblatore per x86, quindi questa parte di una macchina virtuale non è realmente il problema. Quello che mi interessa, è la funzionalità sandbox di esso. Per illustrare cosa intendo consideri questo esempio.

Supponiamo di avere una funzione che apre semplicemente un file. Quindi niente di speciale.

 int fd = open(path);

Ora, quando questo codice viene eseguito in modo nativo, andrà al sistema operativo e aprirà il file (supponendo che esista). Ora quando lo eseguo in un ambiente di macchina virtuale, il percorso specificato non è quello che vede il sistema operativo, ma piuttosto qualcosa che la VM sostituirà, reindirizzando così la chiamata aperta. Quindi quello che mi interessa è come una VM può fare ciò, quando il codice eseguito viene eseguito in modo nativo (come x86 su un x86) perché per una VM interpretata è piuttosto ovvio.

Quando cerco google per macchine virtuali, trovo solo link che parlano di interpreti come Java, LLVM o simili, ma nulla di ciò che è più dettagliato. Ho scaricato il codice sorgente da Oracle Virtual Box, ma dal momento che si tratta di una base di codice piuttosto grande, è piuttosto difficile capire che il concetto si stia semplicemente scavando in quel codice.

    
posta Devolus 23.03.2014 - 10:48
fonte

2 risposte

2

Now when I run this in a virtual machine environment, the specified path is not the one that the operating system sees, but rather something that the VM will substitute

Questo non è vero per la stragrande maggioranza delle VM (VMWare, VirtualBox, QEmu, Parallels, VirtualPC, ...) Questi sono tutti virtualizzatori hardware, non virtualizzano il sistema operativo. Quindi, la chiamata di open andrà semplicemente al sistema operativo all'interno della VM, che (in genere) non sa nemmeno che è in esecuzione all'interno di una VM. (Ci sono vantaggi in termini di prestazioni se il sistema operativo sa che è in esecuzione all'interno di una VM e parla alla VM invece di parlare all'hardware virtualizzato o emulato, ma tecnicamente non è più la virtualizzazione, è la paravirtualizzazione.)

Ovviamente, questo semplicemente spinge la domanda a un livello basso: quando il kernel del sistema operativo vuole scrivere su un blocco specifico sull'hard disk, come funziona? Bene, nel peggiore dei casi, la VM deve intercettare le chiamate del BIOS e mappare i numeri dei blocchi su qualche file sul disco rigido del sistema host. Ma qui entra in gioco la paravirtualizzazione: nessun SO moderno usa più il BIOS, usano driver specializzati. E quindi potresti semplicemente fornire un driver "virtuale" che sappia parlare direttamente con la VM.

Devi comunque mappare i numeri dei blocchi, ovviamente. La soluzione più semplice è creare un file nel sistema host che abbia le stesse dimensioni dell'hard disk emulato. Tuttavia, poiché i dischi rigidi tendono a essere per lo più vuoti, questo sarebbe uno spreco di spazio, quindi la maggior parte delle VM utilizza uno schema pigro in cui il file cresce solo quando necessario. Potrebbero anche usare la compressione.

Di cosa tu stai parlando è più simile alla virtualizzazione dell'OS (ovvero ai contenitori) della virtualizzazione dell'hardware. Ma in realtà funziona allo stesso modo: invece di virtualizzare il set di istruzioni x86, virtualizza il "Set di istruzioni ABI del kernel Linux". IOW: tratta semplicemente il Kernel Linux come un interprete per un certo linguaggio (le syscalls) e quindi mette un altro interprete in cima. Ecco come OpenVZ funziona su Linux, ad esempio, o Solaris Zones o DLPAR su IBM PowerSeries.

    
risposta data 23.03.2014 - 15:24
fonte
1

Quindi la domanda è come scrivere una sandbox, in cui un programma può funzionare e non nuocere. Assumerò Windows e nessuna collaborazione dal programma di destinazione. So di due modi, e sono entrambi piuttosto difficili.

Uno è quello di fornire un ambiente in cui ogni chiamata di sistema viene emulata. Ogni eseguibile di Windows carica DLL e chiama i punti di ingresso al loro interno, quindi è necessario fornire le proprie DLL per il caricamento del programma (tramite la propria LoadLibrary). Per ogni punto di ingresso lo passi o lo blocchi o lo modifichi in qualche modo.

L'altro è fare affidamento su una funzione "gancio" adatta integrata nel sistema operativo. Vista e versioni successive dispongono di funzionalità di sicurezza su molte API di sistema. È possibile scrivere un driver di filtro per controllare l'accesso al disco. Puoi intercettare il livello più basso della chiamata di sistema e reindirizzare quelli. Le possibilità sono infinite, ma ti assicuro che ognuna di esse è un duro lavoro.

La tipica VM O / S (VMware, HyperV) funziona a livello di driver perché l'emulazione di dispositivi e dischi è una parte necessaria per fare ciò che fa.

Questa è tutta roba piuttosto generica. Non so di risorse da citare, ma potresti certamente dare un'occhiata a Sandboxie, al client nativo di Chrome o ad uno degli altri elencati qui: link .

    
risposta data 23.03.2014 - 14:52
fonte

Leggi altre domande sui tag