Offuscamento del codice ( obfuscated code )
Offuscamento del codice ( obfuscated code )
metodologia per rendere incomprensibile
la lettura del codice sorgente
In pratica , come farsi male da soli.
ultimo aggiornamento: 28.12.2009
Premessa
Ovviamente un buon codice dovrebbe essere strutturato in modo da essere consultabile facilmente
E' questo e' esattamente il contrario di quanto viene fatto con le tecniche di oscuramento
del codice.
Quindi un operazione tanto insensata come quella di rendere astruso il proprio codice
andrebbe fortemente evitata nei progetti reali.
Vi sono pero' circostanze in cui puo' essere utile rendere illeggibile il proprio codice,
perche' ad esempio, lo si vuole protteggere da tentativi di copiatura e reverse engineering.
In tal caso e' utile processare il proprio originale e ben strutturato codice
con un secondo programma che lo renda difficilemte interpretabile.
Ma in ogni caso non e' male che il codice di partenza sia sempre ben strutturato e chiaro.
XOR ( or esclusivo )
Un metodo per nascondere un testo e' quello di suddividere il singolo carattere
in due caratteri che uniti tramite operatore xor riportano al carattere originale.
In tal caso il carattere e verrebbe sostituito da una operatione
di xor tra i caratteri 'Q' e '4'
$ perl -e 'print qq^Q^^qq^4^ '
e
ovvero:
[Q] 10001010 xor [4] 00101100 ==> [e] 10100110
ed il mio indirizzo e.mail 'enzo.arlati@libero.it' verra' sostituito
dalle stringhe (QWKXXRDUWLY0XQUUJXTXD) e (4917v369680p487087z10)
la cui unione tramite operazione xor ristampera' l'indirizzo e-mail originale.
$ perl -e 'print qq^QWKXXRDUWLY0XQUUJXTXD^^qq^4917v369680p487087z10^ ' enzo.arlati@libero.it
Ed il sommo poeta ?
E forse un giorno tutti ci siamo lamentati di quanto fosse difficile
comprendere i versi della Divina Commedia.
E per chi non li ricordasse, eccoli di seguito,
i famosi versi introduttivi al suo poema:
Nel mezzo del cammin di nostra vita
mi ritrovai per una selva oscura,
che la diritta via era smarrita.
Ahi quanto a dir qual era e' cosa dura
esta selva selvaggia e aspra e forte
che nel pensier rinova la paura!
Tant' e' amara che poco e' piu' morte;
ma per trattar del ben ch'i' vi trovai,
diro' de l'altre cose ch'i' v'ho scorte.
E impararli a memoria era una noia non da poco.
Ma se il sommo Dante avesse masticato un po' di perl
avrebbe potuto dare il meglio di se' stesso con rinnovata poetica
magari riscrivendo i versi del primo canto come segue;
$ perl -e 'print qq^0UTVTPMBWKWWTDVUTYPXSQXOWWJFDWTCXLSMXPMFYMFVARXHDQJKLXRFGWYGWTWBQLCROKUXRPTWGRQCXDDRHGPQ
KQKTTATWKKPFSYRY0QQQDFSWGXKXIQQFFDBYXTSBVQRRXQYBXWQBKSXRAGTEFPYGUYGRXFSRTPXYPTVAEAXWUPRVJFS
YWQPGVWXSCPWBQWELGXWXNSGUWHFWABSJOF0RYMAEPTGUUUGXDPXPHGWPVEQYMBQLBTTXJCQGGTYNAPBTBGPBBQAIUR
XQVPXDQQRYHLCPYBKYOUQNYSQEXMWTQUUVVTBAQLTWAPBPPKYLHCJPVYGTYKCPXP^^qq^~08v95788k328d549496s5
1o989266t5182G59m40949731h448k963f42516t812913cA607p86g6811003h190k495t29699922wXSq98q53293
7k9i584f5784t607q7ux2619w5792R7235e55514y474025399y5t72539w0p49826S495g824s3591827l519782g9
6h66402kELd379fe5sg48459d305h7839e4~m289et97874|M98n150t6516603i174q456d29u0ol59y696948bS78
77jw04u9q78634l7825b38l0kh5m89y476975vZ^ '
Lo stesso comando, non rovinato dall' impaginazione, e' disponibile nella textarea seguente:
Dalla logica alla pratica
Ora che la logica e' chiara rimane la parte piu' impegnativa,
quella di trovare e arruolare una dozzina di amanuensi che con certosina
cura selezionino le coppie di caratteri che unite da un or esclusivo diano
il testo desiderato.
Oppure, in alternativa, scrivere qualche linea di codice che, dato il notro
testo calcolino per noi la sequenza delle due stringhe offuscate necessarie,
come mostrato nel listato che segue.
#!/usr/bin/perl
use strict;
my ( $s1, $s2, $s3, $s4, $ix, $c1, $c2, $c3, $strinp );
my ( @lst );
$strinp =
"";
while ( <STDIN> ){ $strinp .=
$_; }
# =====================================================================
chomp $strinp;
print "BASE STRING: ($strinp) \n";
# =====================================================================
$s2 =
"";
$s3 =
"";
@lst =
split( //, $strinp );
foreach $c1 ( @lst )
{
( $c2, $c3 ) =
match_char( $c1 );
$s2 =
$s2 .
$c2;
$s3 =
$s3 .
$c3;
}
# =====================================================================
print "XOR STRING 1: ($s2) \n";
print "XOR STRING 2: ($s3) \n";
# =====================================================================
$s4 =
qq^$s2^^
qq^$s3^;
print "RESULT: perl -e 'print qq^$s2^^qq^$s3^ ' => $s4 \n";
# =====================================================================
# =====================================================================
# SUBROUTINES
# =====================================================================
sub match_char
{
my( $inchar ) =
@_;
my( $i, $c, $c1, $c2, $found );
$found =
0;
# if( ord($inchar) > 126 ) { $inchar = ' '; }
# =====================================================================
for( $i =
1; $i <
20; $i++
)
{
$ix =
int(rand(25)) +
65;
$c =
chr($ix);
$c1 =
qq^$c^^
qq^$inchar^;
if( ord($c1) >
47 &&
ord($c1) <
58 ) { $found =
1; last; }
if( ord($c1) >
64 &&
ord($c1) <
91 ) { $found =
1; last; }
if( ord($c1) >
97 &&
ord($c1) <
127 ) { $found =
1; last; }
}
# =====================================================================
if( $found ==
0 )
{
for( $i =
48; $i <
127; $i++
)
{
$c =
chr($i);
$c1 =
qq^$c^^
qq^$inchar^;
if( ord($c1) >
47 &&
ord($c1) <
58 ) { $found =
1; last; }
if( ord($c1) >
64 &&
ord($c1) <
91 ) { $found =
1; last; }
if( ord($c1) >
97 &&
ord($c1) <
127 ) { $found =
1; last; }
}
}
# =====================================================================
# printf " [%s] %s + [%s] %s => [%s] %s \n",
# $inchar, unpack("b8", $inchar ) ,
# $c, unpack("b8", $c ) ,
# $c1, unpack("b8", $c1 ) ;
# =====================================================================
return ( $c, $c1 );
} # ________ sub match_char