CrackMe No. 4
by Andrénalin


Tutorial de Lucifer48 [Immortal Descendants]
(25 Août 1999)



C'est du VB6 (personnellement, je trouve ça largement plus facile à cracker que le VB5). En utilisant SmartCheck (ou tout bêtement, un petit peu d'observation), on se rend compte que qu'il y a un timer; ce qui veut dire: le serial est testé en boucle (comme winamp par exemple). J'entre illico quelques chiffres: 1, 9, 9, 9,... et je pose un bpx hmemcpy. F10, F10, on sort de MSVBVM60!.text et on arrive à VB_CRKME4!.text:
CALL [EAX+000000A0]
CMP  EAX,ESI
JGE  ...
PUSH 00000A0
Hmemcpy s'arrête ici à plusieurs endroits:
	XXXX:0040B24F et XXXX:0040B320
	XXXX:00406B2F et XXXX:00406B00
	XXXX:00408EBF et XXXX:00408F90
	(j'en ai peut-être oublié ?)
En regardant les adresses, on voit tout de suite que le timer exécute les routines bien distinctent: en effet, XXXX:0040B24F et XXXX:0040B320 sont peu éloignés et appartiennent à la même routine (il en est de même pour XXXX:00408EBF et XXXX:00408F90; ... ).

On a donc plusieurs procédures à analyser; et les adresses ci-dessus correspondent grosso-modo au début de la procédure de vérification, on a plus qu'a tracer pour voir ce qu'il se passe.

Etudions la première routine sur laquelle on tombe (ici en XXXX:0040B24F):
XXXX:0040B3A1  MOV  [EBP-00B4],ESI
XXXX:0040B3A7  MOV  [EBP-00C4],ESI
XXXX:0040B3AD  CALL [MSVBVM60!__vbaLenVar]		;d *(eax+8) pour voir son serial...
On arrive à une boucle:
XXXX:0040B432  CALL [MSVBVM60!rtcMidCharCharBstr]
...
XXXX:0040B444  CALL [MSVBVM60!rtcAnsiValueBstr]		;résultat en al
...
XXXX:0040B469  FLD  REAL8 PTR [EBP-030C]		;notre valeur ascii
XXXX:0040B46F  FADD REAL8 PTR [EBP-00CC]		;+1 (dans mon cas)
...
XXXX:0040B489  CALL [MSVBVM60!rtcHexBstrFromVar]	;conversion en héxa du résultat (ci-dessus)
...
XXXX:0040B505  CALL [MSVBVM60!__vbaVarForNext]		;NEXT (de la boucle)
Donc la boucle traite un à un les caractères de mon serial, il s'ensuit une logique comparaison:
XXXX:0040B51A  PUSH EAX
XXXX:0040B51B  MOV  DWORD PTR [EBP-00AC], 00401E50
XXXX:0040B525  MOV  DWORD PTR [EBP-00B4], 00008008
XXXX:0040B52F  CALL [MSVBVM60!__vbaVarTstEq]		;égal ?
XXXX:0040B535  TEST  AX,AX
Remarque: Voilà qu'il y a en 00401E50:
"0817E747D7AFF7C7F82836D74RR7A7F7E7B7C7D826D81KE7B7C"

Pour mon serial (1999), j'obtient: 0323A3A3A (le zéro est ajouté devant, mais le reste c'est facile à comprendre...)

Sachant que notre serial est issu de la fonction [MSVBVM60!rtcHexBstrFromVar], on ne pourra jamais obtenir un serial avec des R dedans, conclusion le test n'est jamais vérifié.

En poursuivant, on voit 15 fois la même routine, et à chaque fois la comparaison via [MSVBVM60!__vbaVarTstEq] ne convient pas; la chaine comparée avec notre serial tranformé contient des caractères non héxadécimaux (R, K, W, Q, ...).

Donc on va aller voir du côté de des autres routines... (c'est toujours des tonnes et des tonnes de fois la même chose...) et puis finalement, j'ai trouvé le bon endroit:
XXXX:004065E3  PUSH ECX
XXXX:004065E4  MOV  DWORD PTR [EBP-00AC], 00402390
XXXX:004065EE  MOV  DWORD PTR [EBP-00B4], 00008008
XXXX:004065F8  CALL [MSVBVM60!__vbaVarTstEq]
La chaîne en 00402390 est: "0817E747D7A7D7C7F82836D74747A7F7E7B7C7D826D817E7B7C", ça pourrait convenir !

Je regarde à l'instruction FADD (dans la boucle juste au-dessus), et je vois +19, et là, on se rend bien compte que ça va pas du tout ! On est bien loin des 82... J'ai pourtant parcouru toutes les chaînes en mémoire, c'est la seule qui puisse convenir...

Je décide donc de voir d'ou vient ce +19, et finalement je trouve facilement:
XXXX:004064A2  CALL [MSVBVM60!__vbaVarForInit]		;FOR (début de la boucle)
...
XXXX:004064C7  CALL [MSVBVM60!rtcR8ValFromBstr]		;lit les deux premiers caractères.
XXXX:004064CD  FSTP REAL8 PTR [EBP-00CC]		;pop
Mon 19 vient donc de mon serial 1999. Il faut donc que je choisisse judicieusement les deux premiers charactères du serial, pour que ça conincide.

Remarque: X* ou X# donne X ( X={0,1,...,9} ).

Sachant qu'on veut obtenir 81 7E (81-7E=3); on a 6 possibilités de couple:
4-1; 5-2; 6-3; 7-4; 8-5; 9-4

On doit obtenir 6D (plus petite valeur):

2Ah ("*") + 41d = 53h		23h ("#") + 41d = 4Ch
2Ah ("*") + 52d = 5Eh		23h ("#") + 52d = 57h
2Ah ("*") + 63d = 69h		23h ("#") + 63d = 62h
2Ah ("*") + 74d = 74h		23h ("#") + 74d = 6Dh  OUI!!!!!!
Donc le serial commence par 74. On soustrait donc 74d (=4Ah), à toute la chaine (en 00402390):
0 37 34 2A 33 30 33 32 35 38 39 23 2A 2A 30 35 34 31 32 33 38 23 37 34 31 32
ce qui donne:

Serial/ 74*3032589#**0541238#7412

REGISTRIERT !!! Sehr gut !!!!

Greetings: All ID members (Volatility, Torn@do, ...), Eternal Bliss, ACiD BuRN, Duelist, LaZaRuS, people on #cracking4newbies, french crackers, ...



(c) Lucifer48. All rights reversed