Quando un programma risulta compilato e non si ha la possibilità di disporre del relativo codice sorgente, risulta di fatto preclusa ogni possibilità di analisi dettagliata del suo comportamento. dnSpyEx è un software libero, distribuito sotto licenza GNU GPLv3, che dà modo di “smontare” i programmi .NET (e Unity) svolgendo il ruolo di disassembler e decompilatore.
dnSpyEx raccoglie l’eredità di un software dal nome molto simile – dnSpy -, che per motivi mai rivelati da un certo punto in avanti non ha più ricevuto aggiornamenti.
L’obiettivo è quello di aprire qualunque applicazione .NET e avviare attività di reverse engineering per le motivazioni più disparate. L’importante è tenere d’occhio le condizioni di licenza dei software sviluppati da soggetti terzi: se infatti si può usare dnSpyEx senza limitazioni con le applicazioni create in proprio usando Visual Studio, disassemblare e decompilare un’applicazione prodotta da altri potrebbe non essere consentito.
Cos’è e cosa permette di fare dnSpyEx
Attivamente sviluppato e aggiornato, dnSpyEx è uno strumento open source particolarmente utile per il disassemblaggio e la decompilazione di file eseguibili e librerie .NET, consentendo agli utenti di analizzare il codice sorgente e modificarlo direttamente.
Nello specifico, dnSpyEx permette di ottenere il codice sorgente dei programmi .NET a partire da versioni compilate delle applicazioni. Generalmente, il sorgente prodotto da dnSpyEx risulta facilmente comprensibile, grazie alla presenza di simboli e nomi delle variabili. Addirittura, l’Assembly Explorer dà modo di “navigare” facilmente tra le varie risorse e moduli all’interno dell’applicazione .NET analizzata.
Un’utilità come dnSpyEx si rivela utile anche per il debugging: consente di impostare dei breakpoint per analizzare il flusso del programma e monitorare le variabili in tempo reale, facilitando l’individuazione di bug o comportamenti indesiderati.
Come ciliegina sulla torta, dnSpyEx offre la possibilità di esportare il codice decompilato in un progetto Visual Studio, permettendo agli sviluppatori di continuare a lavorare sul codice in un ambiente familiare.
Come funziona dnSpyEx
Per utilizzare dnSpyEx, è necessario aprire un file eseguibile (.exe
) o una libreria (.dll
) .NET. Una volta caricato l’elemento indicato dall’utente, dnSpy ne mostra la struttura interna, inclusi i moduli utilizzati e le risorse incorporate (come immagini e icone).
Risulta quindi molto semplice esplorare il codice decompilato, apportare modifiche ove necessario e testare il comportamento del programma in tempo reale attraverso le funzionalità di debugging.
Per usare dnSpyEx, suggeriamo di scaricarne l’ultima versione facendo riferimento al repository GitHub ufficiale. È sufficiente scorrere la pagina verso il basso fino a trovare gli Assets disponibili.
Qui, si può effettuare il download del file dnSpy-net-win64.zip
per tutte le versioni di Windows a 64 bit (x86-64). dnSpyEx è un’applicazione portabile: per utilizzarla basta creare una cartella dedicata (ad esempio c:\dnSpyEx
) quindi estrarvi tutto il contenuto dell’archivio compresso.
Come disassemblare e decompilare un programma .NET
Per avviare dnSpyEx, basta fare clic sull’omonimo file eseguibile quindi agire sul menu a tendina nella barra degli strumenti a seconda che si voglia decompilare un’applicazione .NET C# o Visual Basic. Agendo sul menu File, Apri si può indicare a dnSpyEx l’eseguibile o la libreria da esaminare.
A questo punto, nel riquadro Assembly Explorer, al di sotto di PE, Riferimenti Tipo, Riferimenti e Risorse, si dovrebbe risalire al codice sorgente di tutti i form che compongono l’applicazione .NET. Fantastico, vero?
Lo sviluppatore può così indagare su comportamenti anomali di un programma, rilevare eventuali problemi di sicurezza e fare luce su tanti interrogativi che, senza poter esaminare il codice sorgente dell’applicazione .NET, resterebbero senza risposta.
Editing degli Assembly
Con dnSpyEx è possibile modificare gli assembly direttamente, lavorando a livello di codice IL o, come abbiamo visto, con linguaggi ad alto livello come C# e Visual Basic. Grazie al supporto IntelliSense, è facile aggiungere, rimuovere o modificare metodi e classi.
In un altro articolo abbiamo spiegato le differenze tra compilazione e interpretazione: il codice IL (Intermediate Language) è un linguaggio di programmazione intermedio utilizzato nella piattaforma .NET. Quando un’applicazione scritta in un linguaggio di alto livello (come C#, Visual Basic o F#) viene compilata, il codice sorgente non è immediatamente trasformato in codice macchina specifico per un determinato processore, ma subisce una traduzione in codice IL. Questo codice IL è un linguaggio astratto, indipendente dalla piattaforma, eseguito dal Common Language Runtime (CLR), la macchina virtuale di .NET.
Il codice IL è indipendente dall’architettura del processore e dal sistema operativo, il che significa che può essere eseguito su qualsiasi piattaforma che supporti CLR (come Windows, Linux o macOS). È insomma il “linguaggio comune” che collega i vari C# e Visual Basic: indipendentemente dal linguaggio di programmazione utilizzato per scrivere il codice sorgente, tutto è sempre tradotto nel medesimo codice IL.
Poiché il codice IL non è specifico per la macchina, è più facile decompilarlo rispetto al codice nativo. Per questo motivo, strumenti come dnSpyEx possono decompilare e modificare il codice IL, permettendo agli sviluppatori e ai professionisti della sicurezza di analizzare o modificare il comportamento delle applicazioni .NET.
Credit immagine in apertura: iStock.com – Kindamorphic