In questo articolo Indice dei contenuti 3 sezioni
Fare doppio clic su un file EXE sembra il gesto più banale del mondo, eppure in quella frazione di secondo Windows esegue una catena di operazioni piuttosto lunga. Il sistema deve capire cosa sta per avviare, verificare il file, creare un nuovo processo, preparargli lo spazio di memoria, interpretare il formato dell’eseguibile, caricare le librerie necessarie, risolvere gli indirizzi delle funzioni importate, decidere con quali privilegi il programma potrà lavorare e solo alla fine passare il controllo al codice dell’applicazione. Un EXE, in fondo, non è altro che la descrizione dettagliata di un’immagine eseguibile che il sistema usa per costruire un processo e poi mantenerlo in memoria. Il formato documentato da Microsoft si chiama Portable Executable, o PE, e lo stesso modello sta alla base tanto degli EXE quanto di moltissime DLL.
Il processo nasce così
Il punto di partenza è la funzione Win32 CreateProcess, descritta da Microsoft in modo asciutto: crea un nuovo processo e il suo thread primario, e il nuovo processo utilizza il file eseguibile indicato. Come impostazione predefinita eredita il contesto di sicurezza del processo che lo ha lanciato. Il processo funziona come contenitore e possiede uno spazio di indirizzamento virtuale, handle verso oggetti di sistema, informazioni di sicurezza, moduli caricati, variabili d’ambiente e altri dati di esecuzione. Il thread invece è ciò che esegue davvero le istruzioni sulla CPU. Vedere un nome nell’elenco del Task Manager non significa quindi che stia girando un solo flusso: dentro quel processo possono esserci decine o centinaia di thread.
Con un documento la faccenda cambia leggermente. Cliccando su un file non eseguibile, come una relazione in formato docx, Windows deve prima capire quale applicazione gestisce quel tipo di file e poi avviarla passandole il documento come argomento.
Dentro il formato PE si trovano intestazioni e sezioni che spiegano al sistema come interpretare il file: architettura di destinazione, caratteristiche dell’immagine, indirizzo di ingresso, directory varie utili al loader. Curiosità: anche gli eseguibili di oggi conservano la vecchia intestazione MZ ereditata dai tempi di DOS, sigla riconducibile a Mark Zbikowski, tra gli ingegneri Microsoft che definirono quel layout. Le sezioni più comuni sono .text con il codice eseguibile, .data con i dati modificabili, .rdata prevalentemente in sola lettura, .rsrc con icone, dialoghi e informazioni di versione, .reloc con le informazioni per correggere gli indirizzi quando l’immagine non viene caricata dove previsto. Tra tutto, il dato chiave è l’entry point, l’indirizzo da cui parte l’esecuzione una volta terminate le operazioni preliminari, che non coincide per forza con la prima funzione scritta dal programmatore.
Privilegi, avvisi e librerie
Non tutti i file EXE partono con gli stessi diritti. Un eseguibile può contenere un application manifest, metadati XML che dichiarano le sue esigenze. I tre valori più significativi sono asInvoker, highestAvailable e requireAdministrator. Nel primo caso il programma si accontenta del livello di autorizzazione di chi lo ha avviato, nel terzo dichiara di aver bisogno dei privilegi amministrativi e Windows attiva l’elevazione UAC.
Discorso diverso per Microsoft Defender SmartScreen, che sui file scaricati da Internet valuta la reputazione dell’applicazione prima di lasciarla partire e può mostrare avvisi per software poco diffuso o sospetto. I due meccanismi rispondono a domande differenti: SmartScreen si chiede se convenga fidarsi di quel programma, UAC se quel programma abbia diritto a privilegi più alti. Un’applicazione legittima può quindi generare un prompt UAC, mentre un eseguibile che non chiede nulla di amministrativo può essere bloccato per mancanza di reputazione.
Poi tocca alle DLL, le Dynamic Link Library. Quasi nessun programma contiene tutto il codice che gli serve: il PE include una Import Table con l’elenco delle librerie e delle funzioni richieste, e il loader deve localizzarle e rendere disponibili gli indirizzi. Se una libreria manca, o se una funzione importata non esiste nella versione installata, la preparazione del processo può fallire. Quando viene indicato solo il nome e non il percorso completo, Windows applica regole di ricerca precise, compreso il Safe DLL Search Mode attivo per impostazione predefinita, che sposta la directory corrente nell’ordine di ricerca per limitare i rischi. Il tema riguarda la sicurezza da vicino: se un aggressore riesce a far trovare per prima una libreria malevola con il nome atteso, si apre la strada al DLL hijacking.
Quando l’eseguibile è .NET e cosa si legge senza avviarlo
Un programma .NET usa lo stesso contenitore PE ma al suo interno ospita Intermediate Language e metadati anziché puro codice macchina. All’avvio entra in gioco il runtime, che prepara l’ambiente gestito e ricorre alla compilazione JIT per produrre le istruzioni effettive. L’estensione .exe descrive il formato di avvio, non il linguaggio di scrittura.
Molto si può scoprire ancora prima del doppio clic. Lo strumento Sigcheck, della suite Microsoft Sysinternals, estrae informazioni estese, hash, catalogo, catena di firma e manifest. Dati molto ripetitivi mostrano un’entropia bassa, mentre contenuti compressi o cifrati tendono verso valori alti. Una firma valida certifica che Windows riesce a verificare l’associazione tra file e firmatario, non la bontà del programma. Esiste infine l’overlay, byte presenti oltre la fine dell’ultima sezione descritta dagli header, che possono contenere archivi compressi, file di installazione, configurazioni o payload. La sua presenza non basta a considerare sospetto un file, dato che molti installer e programmi autoestraenti lavorano proprio così.










