offuscation – Sam & Max http://sametmax.com Du code, du cul Wed, 30 Oct 2019 15:34:04 +0000 en-US hourly 1 https://wordpress.org/?v=4.9.7 32490438 Obfuscating Python http://sametmax.com/obfuscating-python/ http://sametmax.com/obfuscating-python/#comments Fri, 05 Apr 2013 13:55:53 +0000 http://sametmax.com/?p=4381 Python est un langage qu’il est difficile de rendre illisible. Difficile, mais pas impossible.

D’abord, les techniques habituelles de substitutions de lettres par leurs codes ASCII sont toujours valables. Le fameux easter egg import this en fait d’ailleurs usage; si vous ouvrez le fichier dont le chemin est contenu dans this.__file__, vous trouverez :

s = """Gur Mra bs Clguba, ol Gvz Crgref

Ornhgvshy vf orggre guna htyl.
Rkcyvpvg vf orggre guna vzcyvpvg.
Fvzcyr vf orggre guna pbzcyrk.
Pbzcyrk vf orggre guna pbzcyvpngrq.
Syng vf orggre guna arfgrq.
Fcnefr vf orggre guna qrafr.
Ernqnovyvgl pbhagf.
Fcrpvny pnfrf nera'g fcrpvny rabhtu gb oernx gur ehyrf.
Nygubhtu cenpgvpnyvgl orngf chevgl.
Reebef fubhyq arire cnff fvyragyl.
Hayrff rkcyvpvgyl fvyraprq.
Va gur snpr bs nzovthvgl, ershfr gur grzcgngvba gb thrff.
Gurer fubhyq or bar-- naq cersrenoyl bayl bar --boivbhf jnl gb qb vg.
Nygubhtu gung jnl znl abg or boivbhf ng svefg hayrff lbh'er Qhgpu.
Abj vf orggre guna arire.
Nygubhtu arire vf bsgra orggre guna *evtug* abj.
Vs gur vzcyrzragngvba vf uneq gb rkcynva, vg'f n onq vqrn.
Vs gur vzcyrzragngvba vf rnfl gb rkcynva, vg znl or n tbbq vqrn.
Anzrfcnprf ner bar ubaxvat terng vqrn -- yrg'f qb zber bs gubfr!"""

d = {}
for c in (65, 97):
    for i in range(26):
        d[chr(i+c)] = chr((i+13) % 26 + c)

print "".join([d.get(c, c) for c in s])

Ensuite, il y a le fait qu’il est possible de spécifier (en Python 2.7, mais plus Python 3), l’encoding du module en ROT13, base64 ou même zip. Au lieux de mettre # -*- coding: utf8 -*-, vous pouvez faire :

# -*- coding: rot13 -*-

cevag h'Fnz rg Znk, cnepr dhr obver frhy rfg zbvaf qebyr dhr pbqre n cyhfvrhef'

Mais au dela de ces petites astuces, il y a bien entendu la véritable offuscation, celle qui utilise des imbrications d’instructions capilotractées avec de multiples niveaux de nesting dans des onliners qui s’étendent sur des kilomètres en incluant des noms de variables alambiqués le tout organisé dans des structures syntaxiques volontairement obscures en détournant des capacités du langage pour en faire une indigeste bouillie immonde dont la lecture provoquera des saignement durant la phrase de vomi. Comme cette phrase.

Généralement ça passe par un usage massif des features que Guido déteste comme les lambdas ou les ;.

Il y a les classiques onliners à base de map / reduce, par exemples les 1000 premiers nombres … premiers :

print filter(None,map(lambda y:y*reduce(lambda x,y:x*y!=0, map(lambda x,y=y:y%x,range(2,int(pow(y,0.5)+1))),1),range(2,1000)))

Ensuite il y a ceux qui aiment se la jouer “mes variables ont des noms de code Fortran” :

print (lambda Ru,Ro,Iu,Io,IM,Sx,Sy:reduce(lambda x,y:x+y,map(lambda y,
Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,Sy=Sy,L=lambda yc,Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,i=IM,
Sx=Sx,Sy=Sy:reduce(lambda x,y:x+y,map(lambda x,xc=Ru,yc=yc,Ru=Ru,Ro=Ro,
i=i,Sx=Sx,F=lambda xc,yc,x,y,k,f=lambda xc,yc,x,y,k,f:(k<=0)or (x*x+y*y
>=4.0) or 1+f(xc,yc,x*x-y*y+xc,2.0*x*y+yc,k-1,f):f(xc,yc,x,y,k,f):chr(
64+F(Ru+x*(Ro-Ru)/Sx,yc,0,0,i)),range(Sx))):L(Iu+y*(Io-Iu)/Sy),range(Sy
))))(-2.1, 0.7, -1.2, 1.2, 30, 80, 24)

Ce qui va afficher cette belle composition de Mandelbrot (si votre terminal fait 80 colonnes de large) :

Mandelbrot dans un terminal

La génération procédurale : ou comment faire de Zolies choZes avec 1ko de code.

D’ailleurs, pour l’offuscation, on adore les trucs de maths parce que ça donne l’air intelligent et compliqué, et Mandelbrot est un truc très prisé puisqu’avec peu de lignes on peut outputer du Dali Période Guimauve automatiquement :

_                                      =   (
                                        255,
                                      lambda
                               V       ,B,c
                             :c   and Y(V*V+B,B,  c
                               -1)if(abs(V)<6)else
               (              2+c-4*abs(V)**-0.4)/i
                 )  ;v,      x=1500,1000;C=range(v*x
                  );import  struct;P=struct.pack;M,\
            j  ='

Notez cette fois que le code, en plus d'être particulièrement imbuvable, a été gentiment indenté pour ressembler à la figure qu'il va lui même pondre dans le fichier M.bmp que voici :

Mais bien entendu il y a des gens qui arrivent à faire des trucs moches sans entrainement. Par exemple des codeurs JS qui vous font ça:

if "longue chaine".find('chaine') != -1:

Au lieu de :

if 'chaine' in 'longue chaine':

Ou alors les programmeurs C qui font :

for x in range(0, len(ma_list)):
    print ma_list[x]

Alors qu'on a :

for x in ma_list:
    print x

Et au besoin:

for i, x in enumerate(ma_list):
    print i, x

Et à peu près la moitié des programmeurs d'autres langages qui font :

if truc == True:
    if not len(ma_list):

Alors que:

if truc:
     if not ma_list:

Marche très bien.

Je vous passe les isintance() que nous font les programmeurs Java, les check au lieu des gestions des exceptions et les gens qui écrivent les variables en camelCase. Des gens très compétents font du code horrible.

Certains trouvent que le créateur du langage a été un nazi pour avoir forcé les gens à utiliser l'indentation et les sauts de ligne ou pour avoir limité les lambdas. Quand je lis le code de certains, j'ai tendance au contraire à trouver la politique actuelle proche de l'anarchisme hippie. Interdisons les tabs. Les ";" plus de 3 fois d'affilé. Les nombres de saut de ligne qui ne sont pas standard face au PEP8. En fait faisons des syntax errors sur le PEP8. Et les syntaxes errors déclencheront des chocs électriques via le clavier.

Et on enverra tous ceux qui sont pas d'accord dans des camps d’entraînement pour qu'ils puissent tous se concentrer un peu plus sur leur code.

Sinon à quoi ça sert d'être un BDFL ?

]]> http://sametmax.com/obfuscating-python/feed/ 16 4381