Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Proteggere il codice Php con bcompiler

Breve guida allo strumento gratuito che permetter di realizzare applicazioni Php "closed source"
Breve guida allo strumento gratuito che permetter di realizzare applicazioni Php "closed source"
Link copiato negli appunti

La necessità di proteggere i sorgenti da occhi indiscreti è meno sentita nell'ambito della programmazione per il WEB rispetto a quanto accade per le applicazioni tradizionali, e questo è particolarmente vero per un linguaggio come Php che appartiene al mondo dell'"Open Source".

Eppure può capitare di voler distribuire realizzazioni che hanno richiesto un particolare impegno evitando che il primo arrivato le possa imitare, o che sia necessario consegnare al cliente una copia di valutazione senza compromettere la possibilità di essere pagati.

Prodotti rinomati come Zend Encoder e il più economico ionCoube vanno in contro a queste esigenze, ma da qualche tempo esiste anche una soluzione gratuita frutto della grande fucina PEAR/PECL (http://pecl.php.net/): stiamo parlando del "Php bytecode compiler", o bcompiler (http://pecl.php.net/package/bcompiler).

A cosa serve bcompiler?

Questa estensione consente sia di convertire i sorgenti Php in un bytecode dal quale è virtualmente impossibile ricostruire gli esatti originali, sia di elaborare tale bytecode come normale codice Php. Bcompiler è stato creato da Alan Knowles con tre obiettivi:

  1. dare la possibilità di codificare classi e librerie di funzioni in un formato proprietario
  2. creare applicazioni Php-GTK che inglobino l'interprete php.exe
  3. studiare la realizzazione di un traduttore da Php a C

Si tratta di un estensione ancora sperimentale ma che già svolge in modo soddisfacente almeno la prima funzione, ed è proprio ciò di cui ci occuperemo in questo articolo.

Cosa non può fare

Non può migliorare le performance degli script in modo sensibile: a differenza dei due prodotti commerciali citati precedentemente non genera un bytecode ottimizzato, e anche se evita la fase di compilazione del sorgente Php aggiunge l'overhead dovuto all'importazione dei dati codificati.

Installazione

Il "package" con i sorgenti per Unix è disponibile in PECL (PHP Extension Community Library ), mentre l'estensione per Windows è stata inserita tra gli "Snapshot Php".

Non ci soffermeremo sull'installazione perchè la procedura è del tutto identica a quella descritta nell'articolo Php e SQLite, una piccola grande novità, ed è ben documentata anche nel manuale PEAR. Sottolineo soltanto il fatto che bcompiler richiede almeno Php v. 4.3.0 e che l'estensione per la compressione bzip2 (php_bz2) sia stata abilitata.

Consiglio anche agli utenti Windows di sbirciare nel package per Unix perchè contiene alcuni esempi utili e la descrizione di funzioni non documentate.

Limitazioni

Nel corso dell'articolo vedremo che non è possibile codificare interi script ma soltanto librerie di funzioni, singole classi e singole costanti.

Le variabili dichiarate al di fuori di classi e funzioni vanno definite in chiaro, ma la cosa rappresenta un problema di poco conto.

Codificare e decodificare una libreria di funzioni

Sorgente Php in cui vengono dichiarate alcune funzioni

<?php

/*

File "saluti_func.php"

*/


function saludos(){

echo('Hola todos!') ;

}

function greetings(){

echo('Hello all!') ;

}

function saluti(){

echo('Ciao a tutti!') ;

}

?>

La codifica:


<?php

/*

File "functions_encoder.php"

*/


include('saluti_func.php') ;

/*

Sostituisci il tuo percorso

*/


$fp = fopen("file_codificati/saluti_func_cript.pbc","w");

bcompiler_write_header($fp);

bcompiler_write_functions_from_file($fp,'saluti.php');

bcompiler_write_footer($fp);

fclose($fp);

?>

Ecco nel dettaglio ciò che accade:

  • includiamo la "libreria" di funzioni ("saluti_func.php")
  • viene aperto l'handler del file in cui scriveremo il bytecode ("saluti_func_cript.pbc"), l'estensione è del tutto inventata
  • bcompiler_write_header inserisce l'header per i file di questo formato
  • bcompiler_write_functions_from_file crea e scrive il bytecode per tutte le funzioni. Notare che il secondo argomento è il nome del file incluso
  • bcompiler_write_footer scrive il carattere x00 che indica la fine dei dati

Qualora volessimo indicare le funzioni una ad una, anzichè in blocco, lo potremmo fare fare con bcompiler_write_function.

Risultato: aprendo il file "saluti_func_cript.pbc" vi troveremo una serie di caratteri binari

Richiamare la libreria codificata

<?php

/*

File "functions_decoder.php"

*/

/*

L'importazione, sostituisci il tuo percorso

*/


$fp = fopen("./file_codificati/saluti_func_cript.pbc","r");

bcompiler_read ($fp) ;

fclose($fp);

echo('Un saluto in Spagnolo') ;

/*

Chiama una delle funzioni,

otteniamo l'output "Hola todos!"

*/


saludos() ;

?>

Il codice è sufficiente chiaro da non richiedere troppe spiegazioni, bcompiler_read rende disponibile la dichiarazione delle varie funzioni allo script attuale.

Codifica di una o più classi

Per offuscare una serie di classi siamo costretti a nominarle una ad una:

Lo script che contiene la definizione di due classi


<?php

/*

File "saluti_class.php"

*/


class Saluto{

var $messaggio ;

function Saluto($messaggio){

$this->messaggio = $messaggio ;

}

function showMessage(){

echo( $this->messaggio ) ;

}

}//END class Saluto

/*

Una classe che specializza la precedente

*/


class Greeting extends Saluto{

function Greeting(){

$this->saluto('Hello world!') ;

}

}//END class Greeting

?>

Il bytecode viene scritto nel file "saluti_class_pbc"


<?php

/*

File: "class_encoder.php"

*/

/*

include il file con le classi da offuscare

*/


include('./saluti_class.php') ;

$fp = fopen("file_codificati/saluti_class_cript.pbc","w");

/*

È IMPORTANTE L'ORDINE: una classe estende l'altra

*/


bcompiler_write_header($fp);

bcompiler_write_class($fp,"Saluto");

bcompiler_write_class($fp,"Greeting");

bcompiler_write_footer($fp);

fclose($fp);

?>

L'importazione del bytecode e l'istanziazione di un oggetto


<?php

/*

File: "class_decoder.php"

*/

/*

apre il file che contiene il bytecode

*/


$fp = fopen("./file_codificati/saluti_class_cript.pbc","r");

/*

L'importazione

*/


bcompiler_read ($fp) ;

fclose($fp);

/*

Istanzia un oggetto da una delle classi

*/


$hello = new Greeting() ;

$hello->showMessage() ;

?>

Anche in questo caso gli esempi dovrebbero essere sufficientemente chiari, mi limito a evidenziare che nei casi in cui vi sia ereditarietà è importante l'ordine in cui le classi vengono trasferite nel bytecode.

Creare script a scadenza

Abbiamo visto come offuscare i sorgenti Php, ma questo non impedisce al possessore dell copia "trial" di un' applicazione di continuare ad utilizzarla anche oltre il tempo di valutazione prestabilito.

L'esempio successivo ci descrive una tecnica utile per nascondere delle "bombe a tempo" in uno script.


<?php

/*

File: "time_class.php"

*/

class Saluto{

var $messaggio ;

function Saluto($messaggio){

// [evaluation]

time_bomb() ;

// [/evaluation ]

$this->messaggio = $messaggio ;

}

function showMessage(){

echo( $this->messaggio ) ;

}

}//END class Saluto

?>

Nel costruttore delle classe soprastante abbiamo inserito la chiamata ad una funzione che termina lo script nel caso in cui il periodo di valutazione sia scaduto, di seguito vediamo come avviene l'esportazione in bytecode della classe e della funzione time_bomb().


<?php

/*

File: "time_class_encoder.php"

*/

/*

Dichiarazione della funzione time_bomb()

e settaggio dei parametri per la validità

*/

/*

Momento in cui avviene la codifica

*/

$today = time() ;


/*

Costante che definisce la data di inizio per la valutazione

*/


define('EVAL_START', $today) ;

function time_bomb(){


/*

validità 30 gg

*/


$valid_for = 3600 * 24 * 30 ;

if( (time() - EVAL_START ) > $valid_for){


/*

Termina subito l'esecuzione dello script

*/


exit('Periodo di valutazione scaduto') ;

}

else{

return ;

}

}//END function time_bomb()


/***

La fase di esportazione

***/

/*

Il file con la classe da offuscare

*/


include('./time_class.php') ;

$fp = fopen("file_codificati/time_class_cript.pbc","w");

bcompiler_write_header($fp);

bcompiler_write_constant($fp,"EVAL_START");

bcompiler_write_function($fp,"time_bomb");

bcompiler_write_class($fp,"Saluto");

bcompiler_write_footer($fp);

fclose($fp);

?>

La classe può essere utilizzata fino alla scadenza definita al momento della compilazione del bytecode:


<?php

/*

File: "time_class_decoder.php"

*/



/*

Il file che contiene il bytecode

*/


$fp = fopen("./file_codificati/saluti_class_cript.pbc","r");


/*

L'importazione

*/


bcompiler_read ($fp) ;

fclose($fp);


/*

Istanzia un oggetto da una delle classi

*/


$hello = new Greeting() ;

$hello->showMessage() ;

?>

bcompiler da shell

Negli esempi precedenti abbiamo utilizzato dei comuni script Php eseguiti attraverso il webserver, e questo allo scopo evitare di introdurre in un solo articolo troppi argomenti inusuali, tuttavia il modo più ortodosso per compilare il bytecode (specialmente quando abbiamo a che fare con librerie di grandi dimensioni) sarebbe quello di utilizzare Php da linea di comando.

Una volta letto l'articolo Una shell in Php anche chi fino ad oggi non conosceva questo aspetto del linguaggio riuscirà a lavorare con la versione CLI (command line) dell'interprete Php.

Avvertenze legali

È importante ricordare, senza scendere troppo nei dettagli, che non sempre è lecito distribuire codice offuscato, specialmente quando l'applicazione si serve anche di codice altrui coperto dalla licenza GPL (GNU General Public License): quest'ultima infatti si "propaga" all'applicazione nel suo complesso.

Abbiamo fatto riferimento alla "distribuzione" perchè la GPL si applica a questo ambito, mentre ciò che realizziamo su richiesta del cliente non cade nelle restrizioni imposte dal principio del "copy left".

Considerazioni finali

Il "Php Bytecode Compiler" è un progetto molto immaturo ma promettente, chi non ha bisogno di applicazioni avanzate (e costose) come Zend Encoder o ionCoube può sin d'ora trovare utile la funzionalità di offuscamento del sorgente Php.

Non è tutto qui, bcompiler si sta dimostrando un valido strumento per trasformare gli script Php in file binari "standalone" e renderne semplice la distribuzione: non abbiamo affrontato questo aspetto perchè verrà approfondito all'interno della serie di articoli su Php/GTK (http://gtk.php.net) che freephp.html.it sta proponendo in queste settimane.

Aggiornamento dell'ultimo secondo

È appena stata rilasciata l'ultima versione del
"Turck MMCache for PHP" (http://turck-mmcache.sourceforge.net/), un noto "acceleratore php": questa nuova release include anche un "encoder" gratuito che con ogni probabilità è paragonabile ai prodotti commerciali. Ce ne occuperemo molto presto!

Ti consigliamo anche