Studio, fix e modifiche al codice: anche per quello “chiuso”.

Queste sono delle obiezioni abbastanza comuni che vengono spesso tirate in ballo quando si parla di software “chiuso”, ovviamente in contrapposizione a quello definito “aperto” (che, per contro, consentirebbe tutto).

Il codice closed non si può modificare, se vuoi estenderlo non puoi farlo, se c’è un bug o una falla di sicurezza non puoi correggerli (immancabilmente virus e trojan prenderanno possesso del tuo PC; ouch!), e non puoi guardare com’è fatto per studiarlo oppure, meglio ancora, per andare a caccia delle famigerate backdoor (sicuramente ne conterrà almeno una, per farci entrare gli spioni del governo o della CIA).

Cose trite e ritrite che abbiamo sentito chissà quante volte, nella perenne diatriba fra i due modelli di distribuzione del software che, a mio avviso troppo spesso e a torto, vengono visti come mutuamente esclusivi (o stai con l’uno o con l’altro), in una sorta di logica binaria che tende ad appiattire anche le ottime capacità intellettive di cui la natura ci ha fatto dono.

Comunque affermazioni perentorie come quelle riportate sopra mi fanno un po’ sorridere, perché riportano alla mente le tante esperienze che ho avuto in passato sull’argomento, a cominciare dal mio primo computer, uno splendido (ma sfortunato, commercialmente parlando) Commodore Plus 4.

Non durò molto, soltanto un mese circa, ma grazie alla ricca dotazione di Commodore, sfruttando il monitor integrato nella ROM mi permise di disassemblare l’intero contenuto della ROM del BASIC e parte del kernel, trascrivendo il tutto su un quadernone scolastico, in modo da poterne studiare più comodamente il codice.

All’epoca lo spazio era tiranno e le prestazioni offerte dall’hardware estremamente ridotte, per cui linguaggio macchina e assembly erano i linguaggi d’elezione per lo sviluppo di codice “di spessore”, a maggior ragione per quello che veniva integrato nella ROM del computer, per cui averne un disassemblato non era come essere in possesso del sorgente originale, ma quasi.

La stessa cosa avvenne per il BASIC del Commodore 128, unica (ma più importante per me) parte non coperta dal libro “La bibbia del Commodore 128“, che riportava soltanto il disassemblato (commentato) della ROM del monitor e del kernel.

Il disassemblato del BASIC mi permise di capire come funzionava, com’era possibile estenderne le funzionalità (anche aggiungendo nuovi comandi), ma soprattutto di implementare un turbo tape per questo home computer (non ce n’erano a disposizione all’epoca, e non ricordo di averne mai visti), adattando il Flash Tape per Commodore 64 pubblicato sulle pagine di MC MicroComputer.

Passato dopo un paio d’anni all’Amiga 2000, l’occhio si posò quindi sul Turbo Pascal 3.0: prodotto ovviamente non disponibile per questa macchina, ma all’ITIS in cui studiavo lo si utilizzava per programmare, per cui mi serviva necessariamente.

L’unica soluzione era farlo girare tramite un emulatore PC (8086) interamente software, l’IBeM (precursore del ben più noto PC Task che ha spopolato su Amiga), ma che era decisamente lento, per cui mi balenò nella mente l’idea di realizzarne una versione nativa per questa macchina, dopo avere inutilmente e ingenuamente (beata gioventù) scritto una lettera all’allora Edia Borland che ne curava la commercializzazione in Italia.

Mi armai del comando DEBUG (.COM!) e di un fedele quadernone sul quale trascrivere sempre a mano (ancora niente stampante) tutto il disassemblato per studiarlo, commentarlo, e vedere in che modo era possibile realizzarne un analogo per la più amata macchina di casa Commodore.

Inutile dire che studiarmi un po’ di teoria dei compilatori e riscriverlo da zero avrebbe richiesto meno tempo (anche perché sistema operativo e processore erano completamente diversi), per cui, alla fine, abbandonai quel progetto (d’altra parte finito l’ITIS mi aspettava l’università).

Sempre con Amiga la mia sete di conoscenza mi ha portato a disassemblare altro codice (col fido Resource): in primis la ROM, in particolare Exec (sostanzialmente il kernel) per capire in che modo avveniva la sequenza di boot (in parte ne ho parlato in questo articolo), ma soprattutto il famigerato trackdisk.device per capire come veniva utilizzato il Blitter per la de/codifica delle tracce del disco in formato MFM (lavoro anch’esso inutile, visto che optai poi per l’uso della CPU).

Passato al PC, invece, mi sono dilettato nel reverse enginering di un gioco del video poker (uno dei più vecchi, che metteva a disposizione il jolly per realizzare il cosiddetto “poker jollato”), per il quale ho realizzato una monitor evoluto, cioè una sorta di disassemblatore intelligente con integrato un emulatore della macchina, che mi permetteva di aggiungere etichette alle locazioni o ai dati (e anche commenti) in tempo reale, durante l’esecuzione del codice.

Gli impegni e il lavoro mi hanno portato verso altre strade, anche se qualche anno fa il mio interesse per la virtual machine di Python mi ha condotto nuovamente a smanettare col disassemblaggio, questa volta del bytecode generato e del codice x86 emesso dal compilatore (Visual Studio), anche se per motivi diversi (cercare di migliorarne le prestazioni).

In ogni caso l’assenza del sorgente originale nelle varie occasioni descritte non ha mai rappresentato una barriera invalicabile alla conoscenza, ma anche alle modifiche, del codice prodotto da altri. Hacker e cracker esistono da tempo immemore.

Chi conosce Sysinternals sa che nemmeno le parti più nascoste del kernel di Windows sono sfuggite all’occhio di Mark Russinovich (e anche Sony ha avuto le sue gatte da pelare).

Non v’è dubbio che il sorgente originale rappresenti una gran comodità (anche se bisognerebbe vedere com’è scritto: non poche volte ho preferito riscriverlo da zero piuttosto che cercare di comprendere quello che mi si parava davanti), ma non è la condicio sine qua non per capire come funziona un pezzo di codice, e per effettuarne anche delle modifiche.

Certamente richiede skill più elevate, ma d’altra parte quando si inizia a programmare non si parte certamente col reverse engineering del codice altrui. Si tratta di un naturale processo di maturazione dello sviluppatore che lo porta ad approfondire concetti sempre più complessi, fino ad arrivare, eventualmente, a cimentarsi in operazioni come quelle descritte.

Tutto ciò potrebbe finire in futuro, con l’adozione di sistemi basati sul TCPA (di cui abbiamo già abbondantemente discusso), in quanto è possibile impedire l’accesso al codice (e quindi anche al disassemblaggio, oltre che all’esecuzione tramite debugger avanzati).

Sarà con la diffusione di questi sistemi che, a mio avviso, si potrà assistere a una dicotomia fra closed e open source, per cui avere il codice sorgente in mano potrebbe avere un peso non indifferente. Ma passerà ancora parecchio tempo prima che venga gettato l’n-esimo guanto di sfida agli hacker, che non staranno certo a guardare…

Press ESC to close