Solution de esoquynthe
par elooo (mise en page par Kharneth)

Alors pour commencer, je voudrais dire à Meat que l'interface graphique de son crackme est très jolie, mais alors niveau practicité c'est un peu la misère. :p
Comment tu veux que j'énonce les serials possibles si on n'arrive déjà pas à se mettre d'accord sur les lettres affichées hein ?? :D

Bon alors on va dire que de gauche à droite et de haut en bas je vois :
Bouttons


(L'espèce de truc entre le R et le Y n'est pas cliquable)

J'ai fait ce crackme en dead listing quasi intégralement. J'ai juste posé des breakpoints sur les tests des valeurs envoyées à SendMessageA afin de récupérer l'handle des boutons dans le registre eax à chaque fois :

Code01

esi sert de compteur ici, mais sert aussi de pointeur pour le buffer Serial. En fonction des lettres cliquées, des valeurs vont être déposées dans le buffer Serial (cf commentaires ci-dessus). esi va correspondre à l'ordre des lettres cliquées.

Une fois qu'on a tapé 4 caractères, il entre dans le call de vérification (00401548 call <VERIF>). Ce call correspond à une grosse boucle <LOOP>, et on voit que le compteur est géré par esi qui sera compris entre 0 (inclus) et 2 (inclus). Donc on peut en déduire qu'il y aura 3 passages dans la boucle <LOOP>.
esi est également utilisé comme pointeur dans le buffer qui contient les valeurs attribuées lors du clic sur les lettres.


Code02
Code03
Code04
Code05

Dans la routine de vérification, on voit tout en bas, qu'il va récupérer de la pile trois valeurs, qu'il va ensuite stockée dans eax, ebx et ecx.
Puis il va additionner ces trois valeurs et la somme devra faire 0x1357E65C si l'on veut voir s'afficher un message de réussite.

On voit que 5 valeurs peuvent être pushées dans cette routine :

Mais comme il n'y a que trois pop à la fin de la routine et qu'il faut bien rétablir la pile, on comprend vite qu'il ne récupérera que trois valeurs parmi ces 5. Reste à trouver quelles sont ces 3 valeurs additionnées ensemble qui donneraient 0x1357E65C. Un rapide test me permet de constater que :

0x1337C0DE + 0x00111347 + 0x000F1237 = 0x1357E65C

Chacune de ces trois valeurs peut être pushée si un test parmi les 20 de ceux énoncés ci-dessus est validé. Par souci d'économie de place, j'ai décidé de nommer caractère1 = c1 et ainsi de suite jusqu'à c7 dans les commentaires ci-dessus. Ces commentaires mettent en évidence les conditions pour que chacune des valeurs souhaitées soit pushée.

Si on décide d'extraire toutes les bonnes valeurs à la main, en tenant compte des conditions requises, voici donc ce qu'on obtient :

Mais l'étude ne s'arrête pas là.
En effet, on a vu précédemment que seuls quatres symboles cliqués sont nécessaires pour que la routine de vérification soit appelée. En fait, les trois dernieres valeurs sont générées de manière aléatoire à l'ouverture du crackme.
Voici la routine qui se charge de ça :

Code06

Il y aura donc trois passages dans cette boucle afin que les trois valeurs soient générées puis sauvegardées en mémoire en [405103], [405104] et [405105]. Notons au passage qu'aucun de ces trois bytes ne prendra la valeur 2Dh.
Une fois ces valeurs générées, elles apparaîtront sur l'interface du crackme sous forme de symboles :

Capture01

A l'issue, la seule chose qu'il nous reste à faire, c'est de compléter le serial, en renseignant les quatre premières valeurs demandées. Chose qui sera faisable en cliquant sur les symboles présents sur le terrain investi par le moustique.

Capture02

Enfin, si nos quatre symboles cliqués permettent de former un septuplet valide avec les trois valeurs générées aléatoirement, alors, le gros symbole présent sur la tige de la plante sera modifié :

Capture03

Et voilà :)

Pour pouvoir élaborer le keygen, il ne reste qu'à récupérer ces trois valeurs générées aléatoirement en appelant CreateProcess (afin d'ouvrir le crackme), et de faire un ReadProcessMemory sur trois bytes en 00405103.


Remerciements :


elooo