#!/bin/bash # php-obfuscator # 2005-01-28 Offuscatore per PHP. cat > /dev/null < "$2" else echo "$is_cgi" > "$2" fi if [ $metti_copyright = yes ]; then echo -ne "" >> "$2" fi php -q -w "$1" | sed -e 's/ } / }\n/g' -e 's/ ; / ;\n/g' >> "$2" } function EstraiNomiVars() # # Estrae tutti i nomi di var. e nomi campi dal file $1 su stdout. # { sed -r 's/\$([_a-zA-Z]\w*)/\n$\1\n/g' "$1" | grep '^\$' | tr -d '$' | # Ignora le variabili di sistema $_POST, $_GET, ecc.; ignora $this: grep -v -e '^_[A-Z]' -e '^this$' } function EstraiNomiFuncs() # # Estrae nomi funzione dal file $1 su stdout. # { # Estrai nomi funzioni: grep '^[[:space:]]*function[[:space:]]' "$1" | sed -r 's/^[[:space:]]*function[[:space:]]+([_a-zA-Z]\w*).*/\1/' } function SostituisciNomiVars() # # E' dato il file $1. # Sostituisci tutti i nomi di var. e campi come dal file $vars. # { while read v1 v2; do sed -r -e "s/\\\$$v1\\>/\$$v2/g" -e "s/->$v1\\>/->$v2/g" "$1" > "$1.tmp" mv "$1.tmp" "$1" done < $vars } function SostituisciNomiFuncs() # # E' dato il file $1. # Sostituisci tutti i nomi di funzione come dal file $funcs. # FIXME: il caso func@... e' gestito male. # Ho tolto questi: # -e "s/\"$f1\"/'$f2'/g" \ # -e "s/'$f1'/'$f2'/g" \ # NOTA: se il nome di funzione include il nome modulo come in "f@m", allora # la striga deve essere tra virgolette singole o doppie, altrim. PHP da' # errore "parse error, unexpected '@' in ...". { while read f1 f2; do sed -r -e "s/\\<$f1\\(/$f2(/g" \ -e "s/\\<$f1\\)/'$f2')/g" \ -e "s/\\<$f1,/'$f2',/g" \ -e "s/'$f1@/'$f2@/g" \ -e "s/\"$f1@/\"$f2@/g" \ "$1" > "$1.tmp" mv "$1.tmp" "$1" done < $funcs } function Fase1() # # Ripulisce il codice di tutti i file. # Estrae i nomi di variabili e campi nel file $vars. # Estrae i nomi di funzione nel file $funcs. # Risultano i file ripuliti *.tmp e i file $vars e $funcs. # { local i f > $vars > $funcs i=0 while [ $i -lt $N ]; do f="${fn[$i]}" if [ $remove_comments = yes ]; then Ripulisci "$f" "$f.tmp" else cp "$f" "$f.tmp" fi if [ $obfuscate_variables = yes ]; then EstraiNomiVars "$f.tmp" >> $vars fi if [ $obfuscate_functions = yes ]; then EstraiNomiFuncs "$f" >> $funcs fi i=$((i+1)) done } function Fase2() # # Sostituisce in tutti i file i nomi delle variabili, dei campi e delle # funzioni con nomi anonimi. # Quindi ricopia i file *.tmp negli originali *, preservando UID:GID e # permessi. # { local i f i=0 while [ $i -lt $N ]; do f="${fn[$i]}" echo -n "> $f: variabili," if [ $obfuscate_variables = yes ]; then SostituisciNomiVars "$f.tmp" fi echo -n " funzioni" if [ $obfuscate_functions = yes ]; then SostituisciNomiFuncs "$f.tmp" fi echo "." cat "$f.tmp" > "$f" rm "$f.tmp" i=$((i+1)) done } function Help() { echo "Usage: $PROGNAME [options] [file...]" echo echo "Options:" echo echo "-r Remove comments and spaces" echo "-v Obfuscate variables and object fields" echo "-f Obfuscate function names" echo "-a Just like -r -v -f" echo "-C copyright_message" echo " Add this copyright message as a comment" echo "-F Obscured named preserve the original name (for tests)" echo "-h, --help" echo " Show this help and terminate" echo "--version" echo " Show program name and version and terminate" } function Version() { echo "$PROGNAME $VERSION" } function ParseArguments() # Parse options. Collect file names in ${fn[0..$N-1]}. { N=0 while [ $# -gt 0 ]; do case "$1" in -a) remove_comments=yes obfuscate_variables=yes obfuscate_functions=yes ;; -r) remove_comments=yes ;; -v) obfuscate_variables=yes ;; -f) obfuscate_functions=yes ;; -C) metti_copyright=yes shift copyright="$1" ;; -F) fake_substitutions=yes ;; -h|--help) Help; exit 0 ;; --version) Version ; exit 0 ;; -*) echo "$PROGNAME: unknow option '$1'. Try --help for help." >&2 ;; *) if [ ! -r "$1" ]; then echo "$PROGNAME: the file '$1' don't exists or is not readable - will ignore" >&2 elif [ ! -f "$1" ]; then echo "$PROGNAME: '$1' isn't a regular file - will ignore" >&2 else fn[$N]="$1" N=$((N+1)) fi ;; esac shift done } # # MAIN # ParseArguments "$@" # Ripulisci sorgenti ed estrai nomi variabili e funzioni: echo "Estrazione nomi var e funzioni..." Fase1 echo "Generazione tabelle delle sostituzioni..." # Genera tabella sostituzioni nomi variabili: if [ -s "$vars" ]; then n=1 # Ordina le var.: le prime sono quelle usate piu' spesso, che cosi' # avranno un nome piu' breve: sort $vars | uniq -c | sort -n -r | while read x v; do if [ $fake_substitutions = yes ]; then echo "$v v_$v" else printf "%s v_%x\n" $v $n fi n=$((n+1)) done > "$vars.tmp" mv "$vars.tmp" "$vars" fi # Genera tabella sostituzioni nomi funzioni: if [ -s "$funcs" ]; then n=1 # FIXME: dovrei mettere per prime le funzioni usate piu' spesso, ma non # ho il conteggio di frequenza. sort $funcs | uniq -c | while read c f; do if [ $c -gt 1 ]; then echo "ATTENZIONE: la funzione '$f' risulta definita $c volte." >&2 fi if [ $fake_substitutions = yes ]; then echo "$f f_$f" else printf "%s f_%x\n" $f $n fi n=$((n+1)) done > "$funcs.tmp" mv "$funcs.tmp" "$funcs" fi # Esegui sostituzioni: echo "Eseguo sostituzioni..." Fase2 #[ -e $vars ] && rm $vars #[ -e $funcs ] && rm $funcs # FINE.