Mi è capitato di recente di ricevere una richiesta particolare: realizzare una piccola modifica ad una applicazione web realizzata in asp.net. L'applicazione in questione era stata rilasciata compilata e senza i sorgenti acclusi.
Dopo una breve indagine, la cosa si riviera meno semplice del previsto: il collega che si occupò della realizzazione del progetto ha smarrito i sorgenti (argh!).

Che fare quindi? Riscrivere da capo l'applicazione? Nooooo! Decompiliamo la versione attualmente in produzione! :-)



Per prima cosa, diamo uno sguardo a cosa ci troviamo tra le mani: anziche' avere, come in fase di sviluppo del progetto, ad ogni pagina .ascx un corrispondente file contenente il codebehind (.ascx.vb o .ascx.cs), in una applicazione compilata e' presente solamente il file .ascx, che a sua volta 'pesca' codice da un assembly posizionato nel folder Bin, nella root dell'applicazione.

Nell'intestazione della nostra pagina troveremo quindi qualcosa del genere:

<%@ page language="vb" masterpagefile="~/MasterPage.master" autoeventwireup="false" inherits="applicazione._default, App_Web_js57z-yx" smartnavigation="False" stylesheettheme="MyTheme" %>


La proprieta' Inherits ci fornisce il nome dell'assembly che contiene il codebehind della pagina (in questo caso App_Web_js57z-yx.dll).
A questo punto abbiamo tutte le informazioni che ci servono, iniziamo a decompilare.
Scarichiamo quindi un decompilatore per .net: personalmente uso Reflector, la versione base e' gratuita e sembra fare il suo lavoro senza grossi problemi.

Una volta installato, diamo in pasto a reflector l'assembly identificato leggendo l'intestazione della pagina (App_Web_js57z-yx.dll), poi click di tasto destro sul nome apparso nell'elenco e selezionate 'Export':

Reflector a questo punto salvera' un folder contenente il sorgente estratto dall'assembly: assieme ad alcune dipendenze che, troverete anche il file contenente il codebehind della pagina:


Ci rimane da effettuare una ultima, semplicissima operazione: copiamo il file generato da reflector nella stessa directory contenente il corrispondente .ascx, rinominiamo il nostro file con la sintassi standard (nel nostro esempio default.ascx.vb oppure default.ascx.cs) e modifichiamo in questo modo l'intestazione della pagina:

<%@ page language="vb" masterpagefile="~/MasterPage.master" autoeventwireup="false" inherits="_default" CodeFile="~/default.aspx.vb" smartnavigation="False" stylesheettheme="MyTheme" %>

Compiliamo il progetto e prendiamo nota delle dipendenze che non vengono soddisfatte: ripetiamo quindi questa procedura per i rimanenti file fino a risolvere tutte le dipendenze mancanti.

Infine, ricontrolliamo il codice verificando che tutti gli eventi dei controlli siano 'collegati' nel codebehind: in caso contrario sara' necessario specificare l'handle dell'evento alla sub corrispondente.