Showing posts with label unmaintainable code. Show all posts
Showing posts with label unmaintainable code. Show all posts

Sunday, December 18, 2011

Code Obfuscation (Example 1)

Following through the series of posts about code obfuscation and unmaintainable code, I want to show here a C code snippet:


#define x(y,z) z , y
#define y(z,x) x z
#define a(b,c) c##b
#define x167 }
#define x879 x167;
#define x798 '\0'x879
#define x98 {
#define _ a(ain,m)
#define __ ()
#define b(c,d) a(c,d)
#define w a(ar,ch)
w ____[] = x98 x(0154, x(0145, 0110)), 108, 111, 30+02, 87, 0x6f, 0162, 0x6c, 0x64, x798
w ___[] = x98 '%', 's', x(x798, '\n')
_ __ x98 y((___, ____),a(ntf,pri)); x167


This is indeed a full working program, and the techniques used here to screw the code are simple enough. What's the actual purpose of this program?

Compile & running it (or gcc -E) are good means to see in its internals.

No further explanation is being given here, as I consider this to be easy enough!

Saturday, March 12, 2011

Come scrivere codice incomprensibile: camuffaggio

Molte delle abilità alla base della scrittura di codice incomprensibile è l'arte del camuffagio: nascondere le cose, o farle apparire per quello che non sono. Molte di queste abilità dipendono da fatto che il compilatore è più bravo dell'occhio umano nel fare fini distinzioni.


Codice che si maschera da commento, e viceversa
Un'ottima idea è quella di includere del codice commentato, che però non sembra esserlo:

for(j = 0; j %lt; array_len; j += 8) { 
   total += array[j+0]; 
   total += array[j+1]; 
   total += array[j+2]; /* Il corpo principale
   total += array[j+3]; * del ciclo è espanso
   total += array[j+4]; * per aumentarne la
   total += array[j+5]; * velocità
   total += array[j+6]; */
   total += array[j+7]; 
}

Se non ci fosse il coloratore della sintassi, qualcuno si accorgerebbe mai che quattro righe di codice sono commentate?


Wednesday, February 17, 2010

Come scrivere codice incomprensibile

Non attribuire alla malizia ciò che può essere spiegato con l'incompetenza.
- Napoleone -

Nell'interesse di creare opportunità di assunzione nel campo della programmazione, comincio a pubblicare oggi una serie di consigli su come scrivere del codice che risulti talmente difficile da gestire che le persone che prenderanno il posto dopo di voi impiegheranno anni per fare persino le modifiche più semplici. Inoltre, se seguirete queste regole rigorosamente, vi assicurerete un lavoro per tutta la vita, dal momento che nessuno tranne voi avrà una minima speranza di gestire il codice. E forse, se avrete seguito le regole in modo religioso, nemmeno voi sarete più in grado di farlo!!!

Ovviamente non bisogna abusarne: il codice non dovrà sembrare senza speranze, ma lo dovrà essere e basta. Altrimenti ci potrebbe essere il rischio che venga riscritto o risistemato.

Quidquid latine dictum sit, altum sonatur.
- Tutto quello che viene detto in latino, sembra importante -

Per giocare dei buoni tiri al programmatore che deve modificare il vostro codice, dovete capire come ragiona. Ha davanti a sé il vostro enorme programma. Non ha tempo per leggerlo tutto, tanto meno per capirlo. Vuole trovare rapidamente il punto in cui fare la modifica, effettuarla, farlo girare e non trovare alcun effetto collaterale causato dalla modifica.

Vede il vostro codice attraverso un tubo di cartone della carta igienica: riesce a vedere soltanto un piccolissimo pezzetto di programma per volta. Quello di cui volete essere sicuri è che non riesca mai a tirar fuori l'immagine completa, muovendosi in questo modo. Volete far sì che gli risulti il più difficile possibile trovare il codice che sta cercando. Ma ancor più importante, volete togliergli a tutti i costi la possibilità di ignorare qualcosa che avete scritto.

I programmatori sono cullati nel compiacimento dalle convenzioni. Ogni tanto, violando subdolamente le convenzioni, lo obbligherete a leggere ogni singola riga del vostro codice con la lente di ingrandimento.

Forse vi siete già fatti l'idea che ogni caratteristica di ogni linguaggio può rendere il codice ingestibile. Non è così: soltanto se male utilizzata a dovere.



E quindi, cominciamo questa serie di consigli con qualcosa di concreto. I compilatori del C trasformano la sintassi di accesso ad elementi degli array in un modo che può essere facilmente utilizzato per far lacrimare gli occhi di qualsiasi programmatore che sta leggendo il vostro codice. In particolare, vale questa relazione:
  • myArray[i], viene trasformato in
  • *(myArray + i), che è equivalente a
  • *(i + myArray), che a sua volta è equivalente a
  • i[myArray].
I più esperti avranno già mille idee su come utilizzare questa tecnica in modo appropriato. Per camuffare le cose ancora di più, si può generare l'indice tramite una funzione:

int myfunc(int q, int p) {
return p%q;
}
...
myfunc(6291, 8)[Array];

Che, ovviamente, corrisponde ad un semplicissimo:
Array[8];
Ma... quanto tempo in più ci vuole per capirlo?