Decompilazione

Da Wikipedia, l'enciclopedia libera.

La decompilazione è l'attività di ingegneria inversa mediante la quale viene ricostruito il codice sorgente a partire da un file eseguibile in linguaggio macchina.

Principi di base[modifica | modifica sorgente]

Semplificando, la compilazione consiste nella traduzione del codice sorgente ad alto livello in codice oggetto a basso livello. Per mezzo di questo processo, oltre alla traduzione letterale delle istruzioni nelle equivalenti istruzioni per i processori, vengono rimpiazzate le funzioni contenute nelle librerie e rimossi i commenti inseriti dallo sviluppatore. Inoltre, il file eseguibile può essere composto da più moduli, aggregati nella fase di linking.

L'operazione inversa, non potendo ad esempio conoscersi a priori le librerie utilizzate, produce una rappresentazione attendibile ma per forza di cose meno leggibile dell'originale. I commenti originali, per inciso, sono irrimediabilmente persi.

Tale processo non riguarda soltanto i file eseguibili di programma (ad esempio i file.EXE) ma qualunque file prodotto da un processo di compilazione, come ad esempio le animazioni in Adobe Flash.

Applicazioni[modifica | modifica sorgente]

La decompilazione può essere utile nei seguenti casi:

  • Recupero di codici sorgenti perduti, avendo la necessità di modificare l’eseguibile;
  • Traduzione di codice scritto in linguaggi obsoleti non più supportati dagli strumenti di compilazione attuali;
  • Determinazione dell'esistenza di virus o software maligno nei programmi;
  • Analisi del codice per risalire agli algoritmi utilizzati.
  • Eliminazione delle protezioni degli shareware (cracking)

Storia[modifica | modifica sorgente]

La nascita dei decompilatori è contemporanea a quella dei compilatori, ma il primo vero decompilatore fu scritto da Joel Donnelly nel 1960 al Naval Electronic Labs per decompilare il codice macchina dei programmi NELIAC su un computer Remington Rand Univac M-460 Countess, progetto visionato dal Prof. Maurice Halstead che lavorò sulla decompilazione tra gli anni '60 e '70, e pubblicò tecniche che stanno alla base dei compilatori odierni.

Durante gli anni '60 la decompilazione fu usata nel processo di conversione dei programmi dalla seconda alla terza generazione; in questo modo i programmi per le macchine di terza generazione furono riscritti in maniera automatica.

Tra gli anni '70 e '80, la decompilazione fu adoperata per la portabilità dei software, documentazione, debugging, rielaborazione di codici sorgenti perduti, e modifica di file eseguibili già esistenti.

A partire dagli anni '90 in poi tale tecnica è diventa uno strumento di reverse engineering capace di ausiliare gli utenti nel controllo di programmi per verificare la presenza di codice maligno, verificare che il compilatore generi un codice corretto, tradurre programmi binari da una macchina a un'altra e capire l’implementazione di una specifica funzione di libreria.

Tecniche di decompilazione[modifica | modifica sorgente]

Decompilazione per le macchine reali[modifica | modifica sorgente]

I decompilatori per le macchine reali possono essere:

  • Pattern matching (dipendono da un particolare compilatore)
  • Indipendenti dal compilatore

Uno dei maggiori problemi nella decompilazione del codice sorgente è che non tutti i compilatori generano codice allo stesso modo perché ognuno effettua le proprie ottimizzazioni. Ciò significa che bisognerebbe attuare procedure di compilazione ben precise per ciascun compilatore, in modo da aver maggiori possibilità di capire il codice.

Per questa ragione, unita alle informazioni che vengono inevitabilmente perdute, le tecniche di decompilazione da codice macchina sono state progressivamente abbandonate o comunque utilizzate solo per esperimenti accademici.

I ricercatori in questo campo hanno così lasciato alle spalle i metodi classici di decompilazione per intraprendere strade diverse (metodi statistici) i cui risultati non sono però stati resi noti.[senza fonte]

Decompilazione per le macchine virtuali[modifica | modifica sorgente]

Esistono grandi differenze tra il codice macchina delle applicazioni per macchine reali (ad esempio Assembler) e il codice macchina delle applicazioni per macchine virtuali (ad esempio Bytecode). In particolare, tali differenze si riferiscono alle informazioni relative al codice sorgente che vengono conservate dentro il codice macchina.

Tra tutte le macchine virtuali la più famosa è la Java Virtual Machine il cui “codice macchina” si chiama bytecode.

Il bytecode contiene molte più informazioni rispetto al codice macchina.

Implicazioni legali[modifica | modifica sorgente]

Tale operazione viene classificata dalla legge come una forma di "copia".

Normalmente numerosi software sono sotto copyright da parte degli autori. Questo significa che copiare la stessa idea su un altro programma è proibito dalla legge.

La decompilazione è lecita solamente in alcuni casi precisi descritti nella legge 633/1941 diritto d'autore italiano all'articolo 64quater. In sintesi è possibile decompilare un eseguibile solamente se ciò è necessario per avere le informazioni utili al conseguimento dell'interoperabilità con un programma creato autonomamente, a patto che la decompilazione sia eseguita da chi possiede la licenza d'uso dell'eseguibile da decompilare e che le informazioni ricercate non siano già facilmente reperibili. Inoltre la decompilazione deve essere limitata alle parti indispensabili per l'interoperabilità. Le informazioni ottenute non possono essere utilizzate per fini diversi dall'interoperabilità né comunicate a terzi per altri fini.

La domanda circa l'utilizzazione del diritto di decompilazione prende sostanza nel momento in cui il codice sorgente originale è mantenuto segreto: per esempio, potrebbe essere necessario decompilare un sistema operativo per comprenderne il funzionamento, per poter scrivere un programma che funzioni su quella precisa piattaforma; o procedere alla decompilazione di un programma di un rivale commerciale affinché sia possibile comprendere come funzioni per poter creare un software che generi formati file in uscita compatibili.

Siamo di fronte ad un vero e proprio conflitto d'interessi. Da un lato, si ritiene importante, nell'interesse pubblico, la interoperatività dei programmi tra loro. Dall'altro lato, la segretezza del codice sorgente è una prassi molto comune di mercato: è una forma di protezione dei propri programmi da modifiche illegittime, e di raccolta d'informazioni importanti dei propri concorrenti di mercato. La Direttiva, quindi, è stata disegnata per prevenire l'utilizzazione del diritto di decompilazione affinché non sia messa in pericolo la protezione conferita dalla segretezza.

Le condizioni e le limitazioni previste per il diritto di decompilazione sono tassative. La stesura risulta spesso poco chiara, ragion per cui c'è incertezza sull'interpretazione che forniranno i tribunali in questo caso "limite". Il diritto di decompilazione dovrà, in ogni caso, essere utilizzato con estrema cautela. Ci vuole un'adeguata consulenza giuridica per non cadere in errori.

Le condizioni più importanti da rispettare si traducono nel fatto che le informazioni ottenute attraverso l'utilizzazione del diritto di decompilazione potranno essere utilizzate solo con obiettivo di garantire la interoperatività fra i programmi e non potranno essere cedute a terzi, tranne quando sia necessario al suddetto scopo. In pratica, l'unico modo per essere sicuri di ciò, è attraverso l'uso di una "stanza pulita". La procedura è la seguente:

  1. La società individua una stanza determinata come "stanza pulita". I computer sono installati nella stanza, senza collegamento ad Internet.
  2. Vengono incaricati alcuni soggetti dello staff per svolgere le attività lavorative svolte nella stanza pulita. Soltanto questi, ed altro personale specificamente autorizzato, sono legittimati ad entrare nella stanza. La stanza è utilizzata solo per decomporre ed analizzare il software. Nessuna informazione riguardante la decompilazione può essere trasmessa al di fuori della stanza (sia in forma cartacea che digitale).
  3. Una volta estratta l'informazione necessaria alla interoperatività, lo staff realizzatore della decompilazione prepara un rapporto, nel quale vengono riportate soltanto le informazioni utili alla interoperatività. Ciò può essere rimosso con sicurezza dalla stanza.
  4. Concluso il lavoro soddisfacente realizzato dalla società che realizza la decomposizione, vengono distrutti tutti i documenti e vengono formattate memorie e dischi dei computer. Soltanto a conclusione di tali operazioni la stanza pulita può tornare ad essere utilizzata senza le citate limitazioni.

Questo procedimento non può essere realizzato alla luce del sole. Nella pratica soltanto un'azienda con risorse notevoli sarà in grado di ricavare profitto dal diritto di decomposizione.

Protezione dalla decompilazione[modifica | modifica sorgente]

Proteggere il codice dalla decompilazione è un obiettivo difficilmente raggiungibile. Si possono tuttavia adottare degli espedienti opportuni, limitare l’operazione di decompilazione da parte di utenti meno esperti, o almeno si può complicare la vita dei novelli cracker.

Prendiamo in esame Java, che a differenza degli altri linguaggi di programmazione ha come scopo primordiale funzionare su qualunque genere di hadware dotato di un'implementazione della Virtual Machine. In pratica quando compiliamo un listato Java, il.class che ricaviamo non è codificato nel linguaggio macchina di uno specifico processore, ma è "tradotto" in una sorta di "macro-linguaggio". Dunque a eseguire il.class in questione non sarà il processore ma un software che interpreta i bytecode e esegue le istruzioni codificate. Analogamente a quanto avviene per qualsiasi altro linguaggio di programmazione, il codice generato dopo la compilazione può sempre essere disassemblato. Però, i file.class creati dal compilatore Java, e destinati ad una macchina virtuale, conservano un numero di informazioni relative al codice sorgente assai maggiore rispetto a un.exe tradizionale. Questo rende più facile la realizzazione di software che consentono un processo di reverse engineering molto accurato, che va ben oltre il processo di disassemblaggio. Infatti, esistono in rete diversi programmi sia freeware che commerciali, che consentono la decompilazione vera e propria dei file class. Questi software sono capaci di ricreare un codice sorgente che differisce veramente di poco da quello originario.

Si ricorre generalmente all’offuscamento del codice. Tale tecnica consiste nel complicare il codice in fase di programmazione rendendone più difficile la comprensione degli algoritmi. Un esempio di offuscamento può essere ad esempio trasformare una semplice operazione come

c = a * b;

in

c = 0
while(b-- > 0)
   c = c + a;

Questa tecnica può almeno scoraggiare i cracker alle prime armi quando si troveranno a cercare di comprendere il listato. Un altro tipico esempio è la modifica dei nomi delle variabili e dei metodi con nomi senza senso.

Un’altra tecnica ancora adoperata per proteggersi dalla decompilazione è quella di modificare il bytecode dei class file in maniera tale da non comprometterne la funzionalità ma generare degli errori nei programmi di decompilazione. Questo per sfruttare i bachi dei decompilatori.

Ammettendo che questi ultimi svolgono un compito molto complesso, partiamo dal presupposto che presentino sempre dei bug e si cerca di individuarli e sfruttarli. Se tale decompilatore è un eseguibile, realizzato ad esempio in C o in altro linguaggio compilato, si può sfruttare uno dei principali punti deboli di tali linguaggi: gli overflow. Una prima idea che viene in mente, analizzando il linguaggio Java, è che quest’ultimo non pone limiti alla lunghezza dei nomi delle variabili. Inseriamo una variabile jolly, all’interno della classe da proteggere con un nome molto lungo.

Inseriamo inoltre, all’interno della classe da proteggere, un metodo inutile che dichiara 514 variabili locali. Questo secondo espediente provoca un incremento del codice di poco superiore al Kbyte.

Esistono altre tecniche per offuscare i codici come ad esempio la criptazione delle classi. Tuttavia non è necessario ricorrere alla modifica manuale del bytecode poiché esistono programmi creati esclusivamente a questo scopo.

Voci correlate[modifica | modifica sorgente]

Collegamenti esterni[modifica | modifica sorgente]

legge 633/1941

Informatica Portale Informatica: accedi alle voci di Wikipedia che trattano di Informatica