IamSickOfInventingNewNames CrackMe
by LaZaRuS
Tutorial de Lucifer48 [Immortal Descendants]
(24 Octobre 1999)
Encore un énorme crackme écrit en C++ builder. Le code n'est pas difficule à comprendre, on va juste
expliquer ici comment résoudre l'algorithme en quelques secondes. Et on va aussi montrer qu'il y a
largement plus que 2400 combinaisons possibles. Allons-y !
Petit bpx hmemcpy comme d'habitude pour rentrer dans le code.
XXXX:004015D9 LEA EAX, [EBP-04] ;d *eax : mon serial
XXXX:004015DC CALL 00454090 ;taille du serial, résultat en eax
XXXX:004015E1 CMP EAX, 14 ;20 caractères pour le serial
XXXX:004015E4 JNZ 004016DA ;jmp = mauvaise taille
On arrive à la première des trois boucles:
XXXX:004015EC MOV [EBP-38], EDX ;edx=0
XXXX:004015EF MOV DWORD PTR [EBP-3C], 1 ;initialise l'indice de boucle
XXXX:004015F6 LEA EAX, [EBP-04] ;d *eax : mon serial
XXXX:004015F9 MOV EDX, [EBP-3C]
XXXX:004015FC CALL 0040172C ;équivalent à: MOV EAX,[EAX+EDX]
XXXX:00401601 MOVSX ECX, BYTE PTR [EAX] ;lit un à un les caractères du serial
XXXX:00401604 ADD [EBP-38], ECX ;addition du tout
XXXX:00401607 INC DWORD PTR [EBP-3C]
XXXX:0040160A CMP DWORD PTR [EBP-3C], 15
XXXX:0040160E JL 004015F6
Cette boucle additionne donc tous les caractères du serial (résultat en dword ptr [EBP-38]). Passons
à la suite (deuxième boucle).
XXXX:00401620 MOV EDX, [EBP-44] ;indice de boucle
XXXX:00401623 ADD EDX, EDX
XXXX:00401625 INC EDX
XXXX:00401626 LEA EAX, [EBP-04] ;d *eax : mon serial
XXXX:00401629 CALL 0040172C ;positionne le serial sur le edx-ème caractère
XXXX:0040162E MOV BL, [EAX] ;lecture d'un caractère
...
XXXX:0040163B CALL 0040172C
XXXX:00401640 XOR BL, [EAX] ;xor avec le caractère suivant
XXXX:00401642 MOVSX ECX, BL
...
XXXX:00401648 MOV [EAX*4+EBP-70], ECX ;les dword sont gardés en mémoire
...
XXXX:00401653 ADD [EBP-40], ECX ;addition de ces 10 dword
XXXX:00401656 INC DWORD PTR [EBP-44]
XXXX:00401659 CMP DWORD PTR [EBP-44], 0A
XXXX:0040165D JL 00401620
Cette précédente boucle XORise deux à deux les caractères et sauvegarde le résultat en mémoire (pour la
troisième boucle). Ces dix dword sont additionnés et le résultat est stocké en dword ptr [EBP-40].
Dernière boucle:
XXXX:0040167C MOV ECX, [EDX*4+EBP-70] ;lit un des 10 dword
XXXX:00401680 MOV EAX, [EBP-48] ;indice de boucle
XXXX:00401683 ADD EAX, EAX
XXXX:00401685 ADD ECX, [EAX*4+EBP-6C] ;on l'additionne avec le suivant
...
XXXX:0040169D IMUL EAX, [EBP-74] ;multiplication des 5 nouveaux dword
XXXX:004016A1 MOV [EBP-74], EAX
XXXX:004016A4 INC DWORD PTR [EBP-48],
XXXX:004016A7 CMP DWORD PTR [EBP-48], 05
XXXX:004016AB JL 00401677
Les 10 dword obtenus à l'issue de la deuxième boucle sont additionnés deux à deux pour former 5 nouveaux dword,
qui sont multipliés entre eux; ce qui donne: dword ptr [EBP-74]. Voilà maintenant la comparaison:
XXXX:004016AD MOV EDX, [EBP-38]
XXXX:004016B0 OR EDX, [EBP-40]
XXXX:004016B3 OR EDX, [EBP-74]
XXXX:004016B6 MOV [EBP-34], EDX
XXXX:004016B9 CMP DWORD PTR [EBP-34], 024AFFCF
XXXX:004016C0 JNZ 004016DA
Résumons la situation:
Les 20 octets du serial: x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20
: ----- ----- ----- ----- ------ ------- ------- ------- ------- -------
Xor 2 par 2 : y1 y2 y3 y4 y5 y6 y7 y8 y9 y10
dword ptr [EBP-38]= x1+x2+x3+...+x20
dword ptr [EBP-40]= y1+y2+y3+...+y10
dword ptr [EBP-74]= (y1+y2)*(y3+y4)*(y5+y6)*(y7+y8)*(y9+y10)
on doit avoir: [EBP-38] OR [EBP-40] OR [EBP-74] = 024AFFCF
Un peu d'intuition (plutôt du bon sens) nous amène à dire que, même dans le pire des cas:
[EBP-38] OR [EBP-40] < 1000h
On fait, dans un premier temps, on va chercher à trouver: z1*z2*z3*z4*z5 = 024AF??? (en faisant le
changement de variable évident z1=y1+y2; z2=... ).
Ci-joint dans le fichier .zip ma source pour trouver 5 valeurs susceptibles de
convenir. Au bout de quelques secondes, on trouve une première combinaison:
y1+y2 = 3Fh
y3+y4 = 3Ah
y5+y6 = 2Fh
y7+y8 = 20h
y9+y10 = 7h
y1+y2+y3+y4+y5+y6+y7+y8+y9+y10 = 000000CFh
(y1+y2)*(y3+y4)*(y5+y6)*(y7+y8)*(y9+y10) = 024AFEC0h
000000CFh OR 024AFEC0h = 024AFECFh
Wow, à un bit près c'est presque parfait ! Il reste maintenant à trouver les x1, ..., x20 de telle façon que
024AFECFh OR [EBP-38] = 024AFFCF. Voilà mon résultat:
x1= 7Ah ('z') x8= 6Bh ('k') x15=43h ('C')
x2= 65h ('e') x9= 4Fh ('O') x16=53h ('S')
x3= 79h ('y') x10=58h ('X') x17=4Ah ('J')
x4= 59h ('Y') x11=49h ('I') x18=4Eh ('N')
x5= 77h ('w') x12=51h ('Q') x19=44h ('D')
x6= 6Ah ('j') x13=42h ('B') x20=47h ('G')
x7= 76h ('v') x14=52h ('R') dword ptr [EBP-38] = 701h
Serial: zeyYwjvkOXIQBRCSJNDG
Juste un dernier mot sur le nombre de combinaisons: à la base, on peut permuter les 5 paquets
(= quatre caractères), ce qui fait déjà 5!=120 possibilités. Un paquet peut se disposer de 8 façons
possibles (en effet, on peut permuter x1x2 et x3x4 et chacun de ces sous-paquets (composés de 2
caractères) peuvent prendre deux positions (ex: x1x2 et x2x1) ). Ce qui fait: 8*120 = 960 et n'oublions
pas qu'il y a 5 paquets, ce qui fait au total: 5*8*120 = 4800 possibilités (rien que pour mon serial).
Et je suis sûr qu'il est possible de trouver (avec un peu de patience) un autre serial (composé de chiffres
et de symboles) qui n'aurait aucun ou très peu de caractères en commum avec celui ci-dessus.
Greetings: All ID members (Volatility, Torn@do, alpine, ...), SiFLyiNG, Eternal Bliss, ACiD BuRN,
LaZaRuS, ... and wonderful people in #cracking4newbies & #win32asm (LLama, WazerPup, X-Calibre, MisterE, ...).
(c) Lucifer48. All rights reserved & reversed