[ - Intro - Explications - L'outil expliqué - Liens - Notes de fin - ] |
[ - Tutoriaux : Variable d'enregistrement ~ Winrar 3.0b7 ~ Notepad - ] |
Ce logiciel va mettre à
profit, la notion de variable d'enregistrement.
Winrar est un archiveur
bien plus puissant que Winzip puisqu'il vous propose de compresser vos
données ( fichiers, etc ) sous le format ZIP ou RAR et qu'il décompresse
de plus en plus de formats différents ( LZH, CAB, ARJ, etc... voir
même des compressions utilisées sous UNIX et LINUX. ).
Je vous conseille vivement
d'acheter ce logiciel.
J'espèrais pouvoir
présenter le crack de Winrar 3.0 final, mais il semblerait que le
décès d'un des membres de l'éditeur du logiciel ait
retardé sa sortie. Donc, on fera avec la dernière release
en date la 3.0 Béta 7. ( Update du 24 / 05 /2002, la version Final
3.0 est sortie ainsi que la version française correspondante. )
Le crack que je vous présente
est extrêmement simple et basique. En effet, depuis la version 2.50,
la protection n'a quasiment pas bougé. La seule différence
notable est que le logiciel pouvait être enregistré via un
nom + serial dans un boite de dialogue ; or depuis la 2.90, cela est fait
au travers d'un keyfile.
Comme je disais, ce logiciel
est d'une simplicité déconcertante à cracker ; toutefois,
si vous faites un tour sur ALTAVISTA, le moteur à cracks, vous verez
que certains ont beaucoup de mal à le faire ! ( un crack pour la
version Béta2 ou 3 je crois, où le trial n'est pas mort,
sic ! ).
Dans le même sens,
vous trouverez un nombre important de tutoriaux pour craquer ce logiciel.
La méthode que je
vais utiliser, est celle que j'utilise depuis la 2.50 et qui me parait
le plus simple. Vous pouvez toutefois jeter un coup d'oeil sur le tut très
intéressant de Christal sur la version 2.80 qui propose d'utiliser
le keyfile.
A l'inverse, Winrar est
loin d'être évident à keygenner. Selon ce que Acidburn
/ The Analyst a rapporté sur Madchat, le contrôle du serial
utilise de la cryptographie...
De plus, je vais montrer comment on peut réinjecter le crack dans l'install de la façon, la plus simple qui soit.
Emplacement : http://www.rarlab.com
Outils : W32Dasm 8.93, Hexworkshop
2.54
A
la recherche des protections.
Le
crack.
Réinjecter
le crack dans l'install.
(
Update ) Quoi de neuf dans la version 3.0 française ?
Je le répéte mais ça sert toujours : avant toute chose, on lance le logiciel pour voir un peut le comportement.
Le caption
Vous lancez le logiciel et la première chose que vous voyez, c'est le truc ci-dessous.
Evaluation copy = copie d'évaluation
Donc déjà
ça, c'est pas bon.
Le About
Si vous cliquez dans le Help
du menu, vous avez plusieurs choix qui s'offrent à vous... Cliquez
sur "Abour Winrar".
Et hop, on a la chose suivante
:
Quand vous avez lancé l'install, vous avez constaté qu'une phrase vous signale que vous avez un temps d'évaluation de 40 Jours. Le About vous le rappelle si vous aviez oublié.
Le Time Trial
Maintenant que l'on connait
le temps d'évaluation, testons un peu le comportement du logiciel
après 40 jours. Fermez Winrar et cliquez sur l'horloge de Windows.
Ajoutez 3 mois et relancez Winrar.
Si vous allez voir de nouveau
dans le About, vous tombez sur la même boite qu'avant, mais celle-là
en plus :
Voilà, voilà,
un Nag-screen qui venir sporadiquement se manifester pour vous rappeller
que c'est 40 jours et pas plus.
Les fonctions désactivées
Allez, une petite dernière
pour la route.
Winrar a aussi des fonctions
désactivées un peu comme une démo mais si vous vous
souvenez du début, j'ai précisé que l'on pouvait enregistrer
le logiciel alors pas de panique, les fonctions sont réellement
présentes dans le logiciel.
Voici donc ce que vous aurez
si vous cliquez sur Options / Settings / General et que vous cochez sur
"Log errors to file".
Récapitulatifs.
- Time Trial de 40 jours
avec Nag-Screen si dépassé.
- Caption "Evaluation Copy".
- "40 days trial copy" dans
le About.
- Fonctions désactivées.
Maintenant que nous avons
toutes nos informations, recherchons ce que cela donne dans le code de
Winrar.
Là, encore je me
répéte mais je fais 1 copie de Winrar.exe que je désassemble
avec W32Dasm et l'original, je m'en serts pour le crack. S'il y a besoin
de revenir à la version avant modification, copiez le Winrar.exe
que vous utilisez avec W32Dasm.
Donc W32Dasm --> Ouvrir
-->COPIE DE WINRAR.EXE
On jete un coup d'oeil dans les Strings Data Reference et on voit plein de choses intéressantes :
....................................................................................
String
Resource ID=00106: "Available in registered version only."
....................................................................................
String
Resource ID=00871: "Thank you for support"
String
Resource ID=00872: "Correct registration"
String
Resource ID=00873: "evaluation copy"
String
Resource ID=00874: "only %d days left to buy a license"
....................................................................................
String
Resource ID=00960: "Registered to"
....................................................................................
"rarreg."
"rarreg.*"
"rarreg.key"
....................................................................................
"regcode"
"regedit
/e "%s" HKEY_CURRENT_USER\Software\Win"
"regedit
-s "%s""
"registration"
"regname"
"REMINDER"
....................................................................................
Voilà, voilà,
autant dire que l'on a beaucoup de choix possibles.
Pour le crack que je propose,
je suis toujours la même méthode depuis la 2.50, à
savoir utiliser la chaîne de caractère "evaluation copy".
Donc on clique dessus, on
tombe sur une ligne du désassemblage. On reclique dessus pour voir
si cette chaîne n'est pas utilisée autre part.. Non, ce n'est
pas le cas.
On est ici :
:0043F89C
50
push eax
:0043F89D
E8AE780300
call 00477150
:0043F8A2
83C40C
add esp, 0000000C
:0043F8A5
803DF4DC480000 cmp
byte ptr [0048DCF4], 00 <==
[0048DCF4] = 00 ?
:0043F8AC
757A
jne 0043F928 <==
non, alors saute en 43F928
:0043F8AE
A18CDF4900
mov eax, dword ptr [0049DF8C]
:0043F8B3
83F814
cmp eax, 00000014 <==
eax= 14 ( 20 décimal ) ?
:0043F8B6
7C05
jl 0043F8BD <==
si moins saute en 43F8BD
:0043F8B8
83F828
cmp eax, 00000028 <==
eax= 28 ( 40 décimal ) ?
:0043F8BB
7C1D
jl 0043F8DA <==
si moins saute en 43F8DA
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043F8B6(C)
|
*
Possible Reference to String Resource ID=00873: "evaluation copy" <==
notre phrase
|
:0043F8BD
B869030000
mov eax, 00000369
:0043F8C2
E8C9F2FCFF
call 0040EB90
:0043F8C7
50
push eax
Donc, il est évident
que nous ne devons pas avoir la phrase. Si on remonte plus haut, on trouve
3 tests + sauts. Regardons vers quoi, ils envoient.
1er saut
:0043F8A5
803DF4DC480000 cmp
byte ptr [0048DCF4], 00 <==
[0048DCF4] = 00 ?
:0043F8AC
757A
jne 0043F928 <==
non, alors saute en 43F928
On
tombe ici :
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043F8AC(C)
|
:0043F928
54
push esp
:0043F929
FF35BCAF4900
push dword ptr [0049AFBC]
*
Reference To: USER32.SetWindowTextA, Ord:0000h
|
:0043F92F
E88C1D0400
Call 004816C0
:0043F934
81C400040000
add esp, 00000400
:0043F93A
C3
ret <== on revient de la fonction
Pas
de phrase affiché, c'est peut-être le bon choix.
2ème saut
3ème saut
NB ( non utile pour le crack
) : Si vous regardez bien, on retrouve dans une variable le nombre de jours
utilisés !
Reprennons
notre crack. On a vu que le saut suivant était le plus intéressant
:
Donc, il faudrait que nous
ayons la variable placé en 48DCF4 de la mémoire à
01, comme ça le saut se fait et plus de "evaluation copy" dans le
Caption.
Cherchons
donc avec "Find text" dans le menu "Search" de W32Dasm, l'expression suivante
: mov byte ptr
[0048DCF4],
Au
final, on trouve
:004364D0
B001
mov al, 01
* Referenced
by a (U)nconditional or (C)onditional Jump at Addresses:
[0048DCF4]
se comporte comme une variable d'enregistrement.
* Referenced
by a CALL at Addresses:
* Possible
StringData Ref from Data Obj ->"rarreg.*" <==
tiens ? !!!! : )
En
cours de route de cette longue fonction, on tombe sur des :
Donc
eax est bien initialisé par cette fonction.
Je
fais donc mon patch ici.
Je
reviens au début de la fonction :
* Referenced
by a CALL at Addresses:
et
je remplace en 40BA40 par
Ce
qui donne après avoir patché :
* Referenced
by a CALL at Addresses:
Donc
en résumé, le programme rentre dans ce call, mets eax à
1 et sort du call ! Voilà, c'est pas plus dur ! Le reste du code
du call original ne sera jamais exécuté donc c'est bon !
As-t-on
terminé ?
:00441283
803DF0D6480000 cmp
byte ptr [0048D6F0], 00
Donc
il faut aussi patché cette ligne. Je propose la chose suivante :
On
relance le programme et on contrôle les protections rencontrées...
Time trial, fonctions désactivées et "evalution copy" dans
le caption, tout a disparu et est redevenu normal. On a "émulé"
le mode enregistré.
:0043F8B3 83F814
cmp eax, 00000014 <==
eax= 14 ( 20 décimal ) ?
:0043F8B6 7C05
jl 0043F8BD <==
si moins saute en 43F8BD
Celui-ci nous emméne
pas loin puisque l'on retombe 5 bytes plus loin, sur "evaluation copy".
Donc, c'est pas le bon.
:0043F8B8 83F828
cmp eax, 00000028 <==
eax= 28 ( 40 décimal ) ?
:0043F8BB 7C1D
jl 0043F8DA <==
si moins saute en 43F8DA
On
tombe ici :
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043F8BB(C)
|
:0043F8DA
B928000000
mov ecx, 00000028
*
Possible Reference to String Resource ID=00874: "only %d days left to buy
a license"
|
:0043F8DF
B86A030000
mov eax, 0000036A
:0043F8E4
2B0D8CDF4900
sub ecx, dword ptr [0049DF8C]
:0043F8EA
51
push ecx
On affiche "encore %d jours
avant d'acheter une license". Donc c'est pas le bon choix.
En effet, sur les sauts,
on a vu la chose suivante :
:0043F8AE
A18CDF4900
mov eax, dword ptr [0049DF8C] <== ICI !!!!
le nombre de jours utilisés !
:0043F8B3
83F814
cmp eax, 00000014 <==
eax= 14 ( 20 décimal ) ?
:0043F8B6
7C05
jl 0043F8BD <==
si moins saute en 43F8BD
:0043F8B8
83F828
cmp eax, 00000028 <==
eax= 28 ( 40 décimal ) ?
:0043F8BB
7C1D
jl 0043F8DA <==
si moins saute en 43F8DA
Et
donc si l'on reprend le code :
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043F8BB(C)
|
:0043F8DA
B928000000
mov ecx, 00000028 <== ecx= 28 ( 40 décimal
)
*
Possible Reference to String Resource ID=00874: "only %d days left to buy
a license"
|
:0043F8DF
B86A030000
mov eax, 0000036A
:0043F8E4
2B0D8CDF4900
sub ecx, dword ptr [0049DF8C] <==
ecx=ecx - nombre de jours utilisés
:0043F8EA
51
push ecx <== ecx = le nombre de jours restants
! Qui va remplacer à l'affichage %d.
:0043F8A5
803DF4DC480000 cmp
byte ptr [0048DCF4], 00 <==
[0048DCF4] = 00 ?
:0043F8AC
757A
jne 0043F928 <==
non, alors saute en 43F928
Cherchons dans le programme,
où cette variable est initialisée.
Le top serait d'avoir une
chose du genre :
mov
byte ptr [0048DCF4], 00 <== [0048DCF4]
= 00
ou
mov
byte ptr [0048DCF4], 01 <== [0048DCF4]
= 01
mais
on peut avoir aussi :
mov
byte ptr [0048DCF4], al <== [0048DCF4]
= al ( avec al =00 ou al = 01 )
ou
mov
byte ptr [0048DCF4], bl <== [0048DCF4]
= bl ( avec bl =00 ou bl = 01 )
NB
: Remettez le désassemblage au début pour que "Find text"
commence au début du désassemblage et non de la position
courante.
:004364D2
E86955FDFF
call 0040BA40 <== une fonction
:004364D7
8BD8
mov ebx, eax <== ebx =eax
:004364D9
881DF4DC4800
mov byte ptr [0048DCF4], bl <== ICI
:004364DF
84DB
test bl, bl
:004364E1
7425
je 00436508
:004364E3
6A30
push 00000030
*
Possible Reference to String Resource ID=00872: "Correct registration"
|
:004364E5
B868030000
mov eax, 00000368
...................................................................................
...................................................................................
:00436700
33C0
xor eax, eax
:00436702
E83953FDFF
call 0040BA40 <== encore cette fonction
:00436707
A2F4DC4800
mov byte ptr [0048DCF4], al <== ICI
:0043670C
33C0
xor eax, eax
:0043670E
E9270E0000
jmp 0043753A
...................................................................................
...................................................................................
:0043E5F5
E8862E0400
Call 00481480
:0043E5FA
B001
mov al, 01
:0043E5FC
E83FD4FCFF
call 0040BA40 <== encore encore cette fonction
:0043E601
A2F4DC4800
mov byte ptr [0048DCF4], al <== ICI
:0043E606
6A00
push 00000000
:0043E608
FF35BCAF4900
push dword ptr [0049AFBC]
...................................................................................
...................................................................................
:0043EF36
B001
mov al, 01
:0043EF38
E803CBFCFF
call 0040BA40 <== encore ( X3 ) cette fonction
: )
:0043EF3D
8BD8
mov ebx, eax <== ebx =eax
:0043EF3F
881DF4DC4800
mov byte ptr [0048DCF4], bl <== ICI
:0043EF45
84DB
test bl, bl
:0043EF47
750A
jne 0043EF53
*
Possible StringData Ref from Data Obj ->"???"
|
:0043EF49
B813654800
mov eax, 00486513
...................................................................................
...................................................................................
:00441283
803DF0D6480000 cmp
byte ptr [0048D6F0], 00
:0044128A
7507
jne 00441293
:0044128C
C605F4DC480000 mov
byte ptr [0048DCF4], 00 <== ICI
|:00441281(C),
:0044128A(C)
|
:00441293
C605A4594A0001 mov
byte ptr [004A59A4], 01
...................................................................................
...................................................................................
Voilà,
voilà, donc il serait intéressant de rentrer dans ce call
0040BA40 pour voir s'il nous renvoit pas une
valeur pour eax, du style : enregistré => eax= 01, pas enregistré
=> eax=00.
|:004364D2
, :00436702 , :0043E5FC , :0043EF38
|
:0040BA40
55
push ebp
:0040BA41
8BEC
mov ebp, esp
:0040BA43
81C404F0FFFF
add esp, FFFFF004
:0040BA49
50
push eax
:0040BA4A
81C448FDFFFF
add esp, FFFFFD48
:0040BA50
53
push ebx
:0040BA51
56
push esi
:0040BA52
57
push edi
:0040BA53
8885E3FEFFFF
mov byte ptr [ebp+FFFFFEE3], al
:0040BA59
BEF0D64800
mov esi, 0048D6F0
:0040BA5E
B838324800
mov eax, 00483238
:0040BA63
E8D07D0600
call 00473838
:0040BA68
8D95C8FAFFFF
lea edx, dword ptr [ebp+FFFFFAC8]
|
:0040BA6E
B85F2E4800
mov eax, 00482E5F
:0040BA73
E815F5FFFF
call 0040AF8D
:0040BA78
84C0
test al, al
...................................................................................
...................................................................................
*
Possible StringData Ref from Data Obj ->"70c2441db366d92ea7be1342b3bf629026ba92bb675f06"
->"e684bdd34511097434" <== tiens ? !!!!
bis : )
|
:0040BF6E
B9852F4800
mov ecx, 00482F85
...................................................................................
...................................................................................
*
Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040BA8B(U),
:0040BAFB(U), :0040BC21(U), :0040BC71(U), :0040BDE9(U)
|:0040BE93(U),
:0040BF06(U), :0040BFA4(U), :0040C035(U)
|
:0040C05F
5F
pop edi
:0040C060
5E
pop esi
:0040C061
5B
pop ebx
:0040C062
8BE5
mov esp, ebp
:0040C064
5D
pop ebp
:0040C065
C3
ret <== fin de notre fonction
pop
eax <== initialise eax avec le contenu
de la pile
mov
edx, dword ptr [ebp+FFFFFEE4]
mov
dword ptr fs:[00000000], edx
jmp
0040C05F<== saute vers la fin de notre
fonction
|:004364D2
, :00436702 , :0043E5FC , :0043EF38
|
:0040BA40
55
push ebp
:0040BA41
8BEC
mov ebp, esp
:0040BA43
81C404F0FFFF
add esp, FFFFF004
:0040BA49
50
push eax
:0040BA4A
81C448FDFFFF
add esp, FFFFFD48
:0040BA50
53
push ebx
:0040BA51
56
push esi
:0040BA52
57
push edi
xor
eax,eax ( 33C0
)
inc
eax ( 40 )
ret(
C3 )
|:004364D2
, :00436702 , :0043E5FC , :0043EF38
|
:0040BA40
33C0
xor eax, eax <== eax =0
:0040BA42
40
inc eax <== eax = eax +1 = 1 donc al =
1
:0040BA43
C3
ret <== fin de notre fonction
:0040BA44
C404F0
les eax, dword ptr [eax+8*esi]
:0040BA47
FFFF
BYTE 2 DUP(0ffh)
:0040BA49
50
push eax
A
notre niveau, on peut se contenter de ce genre de crack avec W32Dasm.
En
fait pas encore !
Si
vous vous rappelez quand j'ai fait mon "Find text" avec mov
byte ptr [0048DCF4], j'ai trouvé plusieurs
possibilités toutes appellant notre call dèsormais patché...
mais il restait une dernière possibilité qui ne le fesait
pas :
:0044128A
7507
jne 00441293
:0044128C
C605F4DC480000 mov
byte ptr [0048DCF4], 00 <== ICI
:0044128C
C605F4DC480000 mov
byte ptr [0048DCF4], 00
devient
:0044128C
C605F4DC480001 mov
byte ptr [0048DCF4], 01
En
cliquant dans le About, vous avez la chose suivante :
Le "40 days trial copy" a
disparu au profit d'un "Registered to".
En bref, Winrar voit sa
variable d'enregistrement toujours à 01 donc comme enregistré
et donc réajuste le logiciel en mode complet. Dans le About, il
affiche ce "enregistré à + le nom de l'utilisateur".
Or ici, on n'apporte pas
d'informations !
Comme je vous l'ai dit,
Winrar s'enregistre avec les informations d'un keyfile : RARREG.KEY.
Et on n'a pas ce fichier !
Donc la solution la plus
simple pour rendre ce soft présentable est de flatter votre EGO
!
Recherchez sous votre éditeur
hexadécimal, la chaîne de caractère en Unicode "Registered
to" par "Lise Grim" par exemple ! Attention de respecter le nombre de caractères
et le mode Unicode de "Registered to".
Il est possible d'exploiter
le RARREG.KEY afin d'avoir un "Registered to + nom + infos supplémentaires".
Mais cela améne à l'usage de Softice pour comprendre le call.
Maintenant que WINRAR.EXE
est patché, pourquoi ne pas le réinjecter dans l'install,
ce qui fera qu'à chaque installation, le logiciel sera déjà
cracké.
Je n'ai pas encore vu la
chose expliquée et pourtant, elle est vraiment simple à faire.
Winrar est un archiveur qui
propose de créer des installeurs éxécutables pour
Windows à la manière d'InstallShield, WISE et autres...
Il est donc logique que
l'install de Winrar en soit un, sinon c'est vraiment faire de la contre-pub
sur son produit.
Faites un click droit sur l'install de Winrar. Vous verrez directement un "Open With Winrar" ou un menu Winrar contenant cette phrase.
Vous voyez que Winrar ouvre
son propre install sans problème. Comme une archive Zip ou RAR,
fesons glisser dans la fenêtre une copie de WINRAR.EXE patché
qui doit remplacer le WINRAR.EXE original de l'install.
Une fenêtre vous demande
des informations, cliquez sur Ok.
Bang ! Une Fenêtre
apparait :
Winrar propose en effet de "locker" l'archive afin qu'elle ne soit pas modifiée.. On va changer ça de façon logique. En effet, si l'archive est lockée, c'est que Winrar la reconnait comme telle. Eh bien, on va faire de telle sorte que Winrar ne reconnaisse plus ce paramètre !
Sous W32Dasm, on cherche
" Cannot modify locked archive" dans les Strings Data Reference.
Et on le trouve ici :
* Referenced
by a (U)nconditional or (C)onditional Jump at Address:
|:00401FE2(C)
|
:00401FFF
80BBD05B000000 cmp
byte ptr [ebx+00005BD0], 00
:00402006
7420
je 00402028 <== saute vers la suite
:00402008
F6C201
test dl, 01
:0040200B
751B
jne 00402028<== saute vers la suite
* Possible
Reference to String Resource ID=00711: "Cannot modify locked archive"
|
:0040200D
B8C7020000
mov eax, 000002C7
:00402012
E879CB0000
call 0040EB90
:00402017
50
push eax
:00402018
83C315
add ebx, 00000015
:0040201B
53
push ebx
:0040201C
E84F670300
call 00438770
:00402021
83C408
add esp, 00000008
:00402024
B001
mov al, 01
:00402026
5B
pop ebx
:00402027
C3
ret
Bon vous avez deviné,
je pense :
00401FFF
80BBD05B000000 cmp
byte ptr [ebx+00005BD0], 00
:00402006
7420
je 00402028
devient
00401FFF
80BBD05B000000 cmp
byte ptr [ebx+00005BD0], 00
:00402006
EB20
jmp 00402028
Et hop, l'install contient
notre version de WINRAR.EXE crackée ( et éventuellement notre
RARREG.KEY ) !
Et bien rien ! Du moins en
terme de protection.
La zone mémoire pour
la variable d'enregistrement a été plaçée par
la compilation en [0048DD1C] et le call est en 40BA4C.
Autant dire que si vous
suivez le crack présenté avant, vous n'aurez pas de difficultés.