Name/ Lucifer    Serial/ 17990
Name/ Lucifer    Serial/ A990
Name/ Lucifer48  Serial/ 4661

Programme  : CrackMe v1.0 (written by Cruehead / MiB)
PlateForme : Windows 95
Date       : 21h38, 14 juillet 1998
Fichier    : Crackme.exe
Outils     : Soft-ice v3.2
Ou ça?     : sur le net...
Temps passé: quelques minutes pour le crack, 1 grosse heure pour la rédaction
Cours      : 11
Matos      : Bloc-notes en 800*600


================================
1. A LA RECHERCHE D'UNE SOLUTION
================================


- Menu Help / Register / Name: Lucifer Serial: 36153615
- Je pose un BPX HMEMCPY, CTRL + D je reclick sur OK, F5, F11 et je trace...
- Je m'arperçois que les deux entrées sont enregistrées via [USER32!GetDlgItemTextA]
- F10 toujours, je passe dans kernel32, user, kernel32!_freqasm et je suis ici dans le code:

XXXX:0040121E  E87D020000   CALL USER32!DialogBoxParamA  ; <--- On sort d'ici
XXXX:00401223  83F800       CMP  EAX,00
XXXX:00401226  74BE         JZ   004011E6
XXXX:00401228  688E214000   PUSH 0040218E	         ; notre nom
XXXX:0040122D  E84C010000   CALL 0040137E                ; 1er call à explorer
XXXX:00401232  50           PUSH  EAX
XXXX:00401233  687E214000   PUSH  0040217E               ; notre nom et notre serial
XXXX:00401238  E89B010000   CALL  004013D8               ; 2e call à explorer
XXXX:0040123D  83C404       ADD   ESP,04
XXXX:00401240  58           POP   EAX
XXXX:00401241  3BC3         CMP   EAX,EBX                ; cmp intéressant...
XXXX:00401243  7407         JZ    0040214C               ; si saut: bon password
XXXX:00401345  E818010000   CALL  00401362               ; affiche une méchante boîte
XXXX:0040124A  EB9A         JMP   004011E6

On remarque que donc à l'issu du 1er call EAX contient une valeur qui caractérise le nom:
en effet le nom et d'abord mis en majuscules puis on additionne la valeur de chaque caractère
et on 'XOR 5678' si le nom ne contient pas excusivement des lettres alors EAX=1 et on 
affiche une boîte de dialogue.
Donc pour moi:
Lucifer vaut: (4C+55+43+49+46+45+52) XOR 00005678 = 0000020A XOR 00005678 = 00005472
Il va falloir trouver ce résultat... 

Explorons le 2e call (voiçi la routine complète):

XXXX:004013D8  33C0         XOR   EAX,EAX
XXXX:004013DA  33FF         XOR   EDI,EDI
XXXX:004013DC  33DB         XOR   EBX,EBX
XXXX:004013DE  8B742404     MOV   ESI,[ESP+04]          ; pointe vers notre serial
XXXX:004013E2  B00A         MOV   AL,0A
XXXX:004013E4  8A1E         MOV   BL,[ESI]              ; lit 1 à 1 les caractères...
XXXX:004013E6  84DB         TEST  BL,BL
XXXX:004013E8  740B         JZ    004013F5              ;BL est-il nul? (i.e. fin du serial)
XXXX:004013EA  80EB30       SUB   BL,30
XXXX:004013ED  0FAFF8       IMUL  EDI,EAX
XXXX:004013F0  03FB         ADD   EDI,EBX
XXXX:004013F2  46           INC   ESI                   ;caractère suivant...
XXXX:004013F3  EBED         JMP   004013E2              ;retour au début
XXXX:004013F5  81F734120000 XOR   EDI,00001234
XXXX:004013FB  8BDF         MOV   EBX,EDI
XXXX:004013FD  C3           RET

Voilà tout est là. Ce call est évident, il convertit notre serial en héxadécimal
(en supposant bien sûr que notre serial est composé de chiffres uniquement)
Donc pour moi: 36153615 vaut: 0227A90F XOR 00001234 = 0227BB3B
Ce n'est donc pas cela... (on devrait trouver 00005472)

On doit donc trouver 00005472 comme résultat.
On peut dire aussi qu'après la conversion en hexa on doit trouver 00005472 XOR 00001234
soit 00004646
Hors 4646_h = 17990_d ; on essaye:
  Name: Lucifer
  Serial: 17990

"Great work, mate!"...

Remarque: si toutefois le nom contient des chiffres ou autres symbloles (&,é,",',(,-,è,_,ç,etc.)
EAX=1 donc on doit trouver la valeur (00000001 XOR 00001234) = 00001235
Hors 1235_h = 4661_d ; on essaye...
  Name: Lucifer48
  Serial: 4661


=====================
2. D'AUTRES SOLUTIONS
=====================

En explorant le second call, vous avez remarquez qu'à aucun moment le programme ne vérifie
que le serial est composé de chiffres, il est donc possible d'inclure une quelconque
combinaison de caractères du moment que le résultat est correct.
Pour en trouver voilà une petite source pascal:

(******************************************************************)
Program cherche_des_serials;   (* by Lucifer48 *)

Var i,i2,i3,i4: byte; (* serials de 4 caracteres *)
    a: longint;

Begin
  a:=0;
  For i:=$30 to $7A do
    For i2:=$30 to $7A do
      For i3:=$30 to $7A do
        For i4:=$30 to $7A do begin
        a:=(((i-$30)*10+(i2-$30))*10+(i3-$30))*10+(i4-$30);
        if a=$4646 then writeln(chr(i),chr(i2),chr(i3),chr(i4) );
        end; {for}            (* remplacer $4646 par votre valeur *)
End.
(******************************************************************)

Il y donc d'autres serials possibles: A97D, A8C0, A990, A8AD,...
Et encore on pourrait prendre des caractère en dessous de 30_h de façon à obtenir
de grandes valeurs. exemple: "%" vaut 25_h de plus 25-30=F5, il y a donc des tonnes 
de serials possibles.

Ce n'est donc pas un crackme très difficile.