CRACK DE CRAZY GRAVITY
"Crazy gravity" c'est un vieux jeux qui tourne sous windows 95 et plus, moi je l'ai eu sur le CD : "PC Collector n°4".
Le jeu est en allemand mais puisque je parle englais, français, allemand, espagnol, flamand, papounésiens, russe, japonnais et neptuniens(couramment) j'ai aucun mal à traduire ...
Bon, bref, le jeu était pas mal, un petit peu simplet quand meme, alors je me suis dit que j'allait le cracker :
Premiere solution :
C'est tout con, les fichiers pour les niveaux on comme
extension : "cgl" et les seul niveaux sur lequels on
peut jouer sont les 3 premiers.
Il suffit donc de remplacer le nom du level que l'on veut essayer
par le nom du premier niveau : "Level01.cgl"
Deuxieme solution :
Ouai, je sais que la premiere solution, c'est de la merde !
La deuxieme solution c'est de le cracker en modifiant un byte :
Alors on essaye de s'enregistrer, on met un truc au hasard et, oh ! Comme c'est étonnant, ça marche pas ! (si ça marche courrez au bureau de tabac acheter un billet de loto !)
Il nous dit : "Die eingegebene Registriernumber bla bla", je crois que mon doctorat en traduction de l'allemand ne sert à rien ici ! on voit tous ce que ça veut dire !
Alors on désassemble le soft (zou !) et paf on as plein d'asm
(hmm bon ça !).
on part à la recherche de la phrase magique, et on l'as trouve
en : 00403473 et 0040EB2B, hmm, hmm on cherche un peu autour de
ses adresse et on trouve
* Reference To: USER32.DialogBoxParamA,
Ord:0000h
Call 004166D7
Call 00401149 <= interressant que fait
ce call ?
mov dword ptr [004171BC], eax
cmp dword ptr [004171BC], 00000000 <= et juste aprés on as un
test de eax ! :) BINGO
jne 0040349F
* Possible StringData Ref from Data Obj
->"NICHT REGISTRIERT"
push 00417177
push 00419C08
* Reference To: KERNEL32.lstrcpyA,
Ord:0000h
Call 004164D9
push 004171B8
push 00419C3A
* Reference To: KERNEL32.lstrcpyA,
Ord:0000h
Call 004164D9
push 00000030
* Possible StringData Ref from Data Obj
->"Crazy Gravity"
push 004171DB
* Possible StringData Ref from Data Obj
->"Die eingegebene Registriernummer "
->"ist ung"
push 00417189
Je tient a signaler que pour les 2 adresses, c'est exactement
la meme chose !
allons donc faire un tour du coté de l'adresse 401149, il y'as
tout plein d'instruction qui verifie si la valeur contenu dans
419C3A, on lance un petit debug (ctrl+L), on met un breakpoint
(F2) sur l'adresse 401149, et on attend, paf des le depart y
passe sur cette instruction, bon la premiere fois on as entré
aucune valeur, on s'en fout, on continue, aprés on essaye de
s'enregistrer on rentre un code bidon que l'on retient facilement
genre : "12456789" et un nom debile : "toto",
on appuye sur ok ... paf y repasse sur notre instruction, là on
va regarder se qu'il y'as en 419C3A
pour cela c'est simple :
vous voyez le truc que j'ai selectionnez ? (User Addr 1) alors remplacer 00400000 par 00419C3A et vous cliquer sur le bouton UA1 et là, oh magie notre code donc le call 00401149 sert a tester le code, si il est bon eax sera egal à 1 solution ?
un truc que j'aime bien, faire le bourrin ! il suffit de
mettre en 401149 :
mov eax, 00000001
ret
mov eax, 00000001 = B801000000
ret = C3
on met en 00401149 : B801000000C3, l'adresse 00401149, se trouve a l'adresse : 00000749 dans le fichier, alors go sur l'editeur hexa et normalement vous devez remplacer : 558BEC83C4EC par B801000000C3
on lance crazy gravity et ... y'as plus les nagscreen ! :) on va pour s'enregistrer et on rentre n'importe quoi et ça marche !
troisieme solution :
pour la troisieme solution y faut connaitre un peu l'asm, car au lieu de modifier un byte, on va chercher un pass valide ! c'est pas mieux ?
on as vu que la verification se fesait en 00401149, on va donc regarder de plus prés cette partie :
j'ai simplifier le code, et
j'ai remplacer l'adresse des variable par le nom qu'elle pourrait
avoir et je l'ai transformé en code pour masm32
donc c'est simplifié au max !
push ebp <= met ebp
dans la pile
mov ebp, esp <= met esp dans ebp
add esp, FFFFFFEC <= enleve 14 (20 en
decimal)
push ebx <= met ebx dans la pile
mov ebx, 00419C3A <= met l'adresse du numero
as testé dans ebx
cette partie verifie si
le code entré a bien une longueur de 11 caractére:
invoke lstrlenA, ebx
cmp eax, 0000000B
je continue1
xor eax, eax
jmp fin
cette partie verifie si
le premier caractére du code est egal as "C" ou
"c"
continue1 :
cmp byte ptr [ebx], 43
je continue2
cmp byte ptr [ebx], 63
je continue2
xor eax, eax
jmp fin
cette partie verifie si
le deuxiéme caractére du code est egal as "G" ou
"g"
continue2:
cmp byte ptr [ebx+01], 47
je continue3
cmp byte ptr [ebx+01], 67
je continue3
xor eax, eax
jmp fin
continue3:
mov eax, 00000002 <= met la valeur 2 dans le registre
eax
cette partie verifie si
les 5 caractére aprés les 2 premier sont des chiffres et les
stocks en tant que DWORD (4 byte), dans (ebp+(4*eax)-1C)
loop :
cmp byte ptr [ebx+eax], 30
jl codefaux2
cmp byte ptr [ebx+eax], 39
jg codefaux
movsx edx, byte ptr [ebx+eax]
add edx, FFFFFFD0
mov dword ptr [ebp+4*eax-1C], edx
jmp continue4
codefaux :
xor eax, eax
jmp fin
continue:
inc eax
cmp eax, 00000007
jl loop
cette partie verifie si
((le 1er chiffre + le 5éme + 7)mod(10) + 48 = le code ascii du 8
éme caractére)
mov eax, dword ptr [ebp-04]
add eax, dword ptr [ebp-14]
add eax, 00000007
mov ecx, 0000000A
cdq
idiv ecx
add edx, 00000030
movsx eax, byte ptr [ebx+07]
cmp edx, eax
je continue5
xor eax, eax
jmp fin
cette partie verifie si
((le 2éme chiffre + le 4éme + 9)mod(10) + 48 = le code ascii du
9 éme caractére)
continue5 :
mov eax, dword ptr [ebp-08]
add eax, dword ptr [ebp-10]
add eax, 00000009
mov ecx, 0000000A
cdq
idiv ecx
add edx, 00000030
movsx eax, byte ptr [ebx+08]
cmp edx, eax
je continue6
xor eax, eax
jmp fin
cette partie verifie si
((le 5éme chiffre + le 3éme + 4)mod(10) + 48 = le code ascii du
10 éme caractére)
continue6 :
mov eax, dword ptr [ebp-04]
add eax, dword ptr [ebp-0C]
add eax, 00000004
mov ecx, 0000000A
cdq
idiv ecx
add edx, 00000030
movsx eax, byte ptr [ebx+09]
cmp edx, eax
je continue7
xor eax, eax
jmp fin
cette partie verifie si
((le 4éme chiffre + le 5éme + 2)mod(10) + 48 = le code ascii du
11 éme caractére)
continue7 :
mov eax, dword ptr [ebp-08]
add eax, dword ptr [ebp-04]
add eax, 00000002
mov ecx, 0000000A
cdq
idiv ecx
add edx, 00000030
movsx eax, byte ptr [ebx+0A]
cmp edx, eax
je continue8
xor eax, eax
jmp 0040123B
voici l'avant derniere
partie, si on passe par là, c'est que tout les test on été
bon, on met 1 dans eax
continue8:
mov eax, 00000001
voici la fin, on
rappelle les valeur de ebx et ebp que l'on avait stocker dans la
pile au debut, et on retourne a la partie du programme qui as a
appeler cette fonction
fin :
pop ebx
mov esp, ebp
pop ebp
ret
voila donc d'abord je vais expliquer ce qu'est "mod"
quand on fait une division sans virgule, par exemple 15/7, on
as le resultat : 2 et le reste : 1
et bien "mod" donne le reste,
15/7 = 2
15 mod 7 = 1
maintenant voyons nos test :
pour simplifier : 1c = premier chiffre, 2c = deuxiéme chiffre,
etc ...
et 1x = 8éme caractére, 2x = 9éme caractére, etc ...
le 1er test verifie que le code as bien 11 caractéres
les 2 test qui suivent verifies si le code commence par CG
le 4 éme test verifie si les 5 caractéres aprés CG sont des
chiffres
notre code est donc : C G 1c 2c 3c 4c 5c 1x 2x 3x 4x
vous suivez toujours ?
le 5éme test verifie que :
((1c + 5c + 7) mod 10) +30 = 1L
le 6éme test verifie que :
((2c + 4c + 9) mod 10) +30 = 2L
le 7éme test verifie que :
((3c + 5c + 4) mod 10) +30 = 3L
le 8éme test verifie que :
((4c + 5c + 2) mod 10) +30 = 4L
et il n'yas pas de vérification par rapport au nom que l'on as entré !
on peut choisir les 5 chiffre au hasard, par exemple 19375
donc :
CG19375xxxx
a partir d'ici, mon cerveau est incapable de calculer en base
10, je passe donc en hexadecimal, désolé ...
les caractéres entre les ' sont la conversion du chiffre obtenu
en ascii ainsi 37 = '7' mais 42 = 'M' ... mais vu que le resultat
du "mod A" est toujours inferieur a A, le resultat des
operations sera compris en 30 et 39, ce qui correspond en code
ascii à un resultat enrte 0 et 9 (putain ce que je m'explique
mal) bon bref le resultat sera toujours un chiffre et jamais une
lettre !
((1+5+7)mod A)+30 = ( D mod A ) +30 = 33 = '3'
((9+7+9)mod A)+30 = ( 17 mod A ) +30 = 35 = '5'
((3+5+4)mod A)+30 = ( C mod A ) +30 = 32 = '2'
((7+5+2)mod A)+30 = ( E mod A ) +30 = 34 = '4'
donc si je me suis pas tromper le code est CG193753524
voilà c'est fini !
CONCLUSION
ce soft etait trés mal proteger, mais le jeu est pas mal mais
bien trop vieux pour que je l'achete, ils m'as amusé qu'un quart
d'heure (le temp que je le crack) :)
certain trouve la 3éme methode mieux que les autres, c'est vrai
que la 1ére methode est vraiment trés nul, mais moi je trouve
que les 2 dernieres methode se valent
si vous aimez les casses tetes, le mieux c'est la 3éme methode
bon maintenant que j'ai fait un bon gros articles de 300 pages je vais me coucher :)
CROQMORT