Lors du précédent article, on a abordé l'obfuscation en Caml au travers de quelques astuces propres au langage, mais sans vraiment construire de programme obfusqué.
Aujourd'hui on va réparer ça.
Genèse
L'autre jour, en lisant un peu les résultats de l'IOCCC (cf article précédent), un code source de l'édition 1987 a fortement attiré mon attention. Il s'agit du programme d'un.e certain.e "westley", arrivé.e 7ème cette année là :
Toutes les lignes de son programme sont des palindromes !
La source de westley est ici : http://www.ioccc.org/1987/westley.c
Cependant chez moi le lien est mort depuis quelques jours. En cas de problème -> WayBackMachine.
Honnêtement j'ai beau adorer l'idée, ce programme là - une fois déobfusqué - est un peu ridicule : il ne fait qu'afficher une chaîne de caractère palindromique. Ceci doit expliquer sa place relativement basse dans le classement.
Reprendre l'idée à mon compte en Caml m'a paru alors plus constructif que de travailler sérieusement mon DM d'informatique.
RionsnoiR
Pour cet exercice il m'a d'abord fallu décider de ce qu'allait faire mon programme. J'ai opté pour une simple détection de palindrome : la fonction prend en argument une chaîne de caractères et renvoie true si celle-ci est un palindrome, false dans le cas contraire.
C'est beaucoup plus compliqué que l'algorithme de westley, mais j'aime bien les challenges alors ¯\_(ツ)_/¯
J'ai d'abord rédigé l'algorithme "en clair" :
let palindrome s =
let rec palin i j = (j-i) < 1 || (s.[i] = s.[j]) && palin (i+1) (j-1)
in palin 0 ((string_length s)-1);;
J'ai opté pour une version récursive dans un intérêt de compacité. Plus la version de départ a une syntaxe légère, plus la version palindromique se fait facilement...
...
Enfin, théoriquement ça semble logique.
Finalement, après ~une semaine~ de travail irrégulier, je mets un terme à la rédaction de mon programme :
let pop tel
_ _
radar = radar
;;
let sa as tel
=
0
;;
let erehw radar = radar where tel
=
0
;;let ni radar = let tel = radar in tel;;
let rionsnoir tel
=
let rec cer tel
kayak _ rotor = rotor - kayak
< 1 || 1 >
8
||
(
nth_char (let ni radar = radar in tel) rahc_htn
where rahc_htn as pop = pop sa nth_char erehw
kayak
)=(
nth_char (let ni radar = radar in tel) rahc_htn
where rahc_htn as pop = pop sa nth_char erehw
rotor
)
&&
(let rec ni radar = radar in cer tel)
(2/3+kayak+3/2)
(1-rotor) (rotor-1)
;in ni;
(let rec ni radar = radar in cer tel)
0
(1-(let htgnel_gnirts ni radar = radar in tel;1)) ((1;let ni radar = radar in string_length tel)-1)
;;
_ _
radar = radar
;;
let sa as tel
=
0
;;
let erehw radar = radar where tel
=
0
;;let ni radar = let tel = radar in tel;;
let rionsnoir tel
=
let rec cer tel
kayak _ rotor = rotor - kayak
< 1 || 1 >
8
||
(
nth_char (let ni radar = radar in tel) rahc_htn
where rahc_htn as pop = pop sa nth_char erehw
kayak
)=(
nth_char (let ni radar = radar in tel) rahc_htn
where rahc_htn as pop = pop sa nth_char erehw
rotor
)
&&
(let rec ni radar = radar in cer tel)
(2/3+kayak+3/2)
(1-rotor) (rotor-1)
;in ni;
(let rec ni radar = radar in cer tel)
0
(1-(let htgnel_gnirts ni radar = radar in tel;1)) ((1;let ni radar = radar in string_length tel)-1)
;;
Je ne suis pas peu fier du résultat. Malgré une petite imprécision à la 18ème ligne (j'ai triché), toutes les autres sont bien des palindromes. La fonction principale est "rionsnoir", les autres ne font que la servir. Bon courage pour la lecture du machin.
Pouf pouf.
Voilà qui clôture pour un certain temps mon exploration des possibilités d'obfuscation en Caml. Je n'ai trouvé personne d'autre sur internet à s'être aventuré sur ce terrain, et je suis plutôt content du maigre travail que j'y ai accompli.
Aucun commentaire:
Enregistrer un commentaire