Cracker le système de protection de ShareLock (SHRLK20.DLL)
(Beaucoup de lumière peut jaillir de ce schéma de protection)

par XaVaX

(11 Février 1998) 


J'ai utilisé WEBZIP.EXE comme cible pour ce cours et, du

coup, j'ai trouvé un utilitaire très pratique.  Mon

attaque ne porte que sur le schéma de protection.



Cible	WEBZIP13.EXE  928Kb  6/1/98 

Outils	WinIce

	W32DSM89

	Hex Workshop 

	Persévérance



Vous devez pensez "encore un autre traité sur un serial number"

mais croyez-moi, cette aventure est très intéressante



Cette protection n'utilise pas les routines standards de Windows
pour récupérer les textes des boîtes de dialogue etc 
(hostile aux debuggeurs?) - nous verrons



Désassemblé WEBZIP.EXE avec W32DSM89

Dans l'en-tête du listing vous touverez la référence à sharelock:




   Import Module 020: SHRLK20.DLL



 Addr:000D9BDE hint(0000) Name: ShowAboutDialog

 Addr:000D9BF0 hint(0000) Name: PassHandle

 Addr:000D9BFE hint(0000) Name: InputUnlockCode  <** notez ça

 Addr:000D9C10 hint(0000) Name: GetTryNumber

 Addr:000D9C20 hint(0000) Name: GetTrialPeriodRemaining

 Addr:000D9C3A hint(0000) Name: CheckProtectionDLL <** et ça



Chargez le processus & cherchez 'SHRLK20.'

Posez des breakpoints sur toutes les occurrences

Coché 'Stop Auto on API' & toutes les options relatives à l' API

Appuyez sur F8 (step over) jusqu'à ce que vous arrivez ici....

Cet appel semble intéressant - notez la référence de l'Arg01 à un texte

Est-ce une vanne pour les crackers? nous verrons cela plus tard!



:004B96FF E8CC0FF5FF              call 0040A6D0



API NODOC Arg00 =

Local_Function(Arg01,Arg02,Arg03,Arg04,Arg05,Arg06,Arg07,Arg08)

API Address=004B96FF, API Return Address=004B9704

  Arg01 = 00b21b48 ->(LPDWORD)57595542 or (LPSTR)"BUYWEBZIPNOWDUDESBUYWEBZIPNOWDUDES"

  Arg02 = 0000001c

  Arg03 = 00000000

  Arg04 = 00000005

  Arg05 = 00000000

  Arg06 = 00000000

  Arg07 = 007cfc70 ->(LPDWORD)007cfcbc or (LPSTR)"¼ü|"

  Arg08 = 004b9760 ->(LPDWORD)f49f0be9 or (LPSTR)"éŸôÿëð[Y]Ã"



Le revoilà à :



:004B9713 E89009F5FF              call 0040A0A8



API NODOC Arg00 =

Local_Function(Arg01,Arg02,Arg03,Arg04,Arg05,Arg06,Arg07,Arg08)

API Address=004B9713, API Return Address=004B9718

  Arg01 = 00000000

  Arg02 = 40e161e0 ->(LPDWORD)00c90f9e or (LPSTR)""

  Arg03 = 00b21b48 ->(LPDWORD)57595542 or (LPSTR)"BUYWEBZIPNOWDUDESBUYWEBZIPNOWDUDES"

  Arg04 = 0000001c

  Arg05 = 00000000

  Arg06 = 00000005

  Arg07 = 00000000

  Arg08 = 00000000



et à:



:004B971B E870A9F4FF              call 00404090

:004B9724 E867A9F4FF              call 00404090

:004B972D E85EA9F4FF              call 00404090

:004B9736 E855A9F4FF              call 00404090

:004B973F E84CA9F4FF              call 00404090



et finalement à:



* Reference To: SHRLK20.CheckProtectionDLL, Ord:0000h

                                  |

:004B9745 E87EF9FFFF              Call 004B90C8



API NODOC Arg00 =

Local_Function(Arg01,Arg02,Arg03,Arg04,Arg05,Arg06,Arg07,Arg08)

API Address=004B9745, API Return Address=004B974A

  Arg01 = 00b21b10 ->(LPDWORD)59454b48 or 

(LPSTR)"HKEY_CURRENT_USER\Software\Microsoft\IFind"

  Arg02 = 00b27f14 ->(LPDWORD)59454b48 or

(LPSTR)"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Metrics"

  Arg03 = 00b29b08 ->(LPDWORD)5a626557 or (LPSTR)"WebZIP"

  Arg04 = 00b21af0 ->(LPDWORD)64697053 or (LPSTR)"Spidersoft"

  Arg05 = 00b3d854 ->(LPDWORD)38312f36 or (LPSTR)"6/18/1997"

  Arg06 = 00b21b48 ->(LPDWORD)57595542 or (LPSTR)"BUYWEBZIPNOWDUDESBUYWEBZIPNOWDUDES"

  Arg07 = 0000001c

  Arg08 = 00000000



Note Arg01 - endroit où la clé encryptée est conservée

dans la base de registre et Arg06 commence à nous embêter serieusement.

Rappelez vous de cela - on en aura besoin plus tard

(La clé contient les infos d'enregistrement, y compris la date d'installation

et d'expiration)

J'ai suivi la méthode de codage et c'est une simple

technique de rotation de bits qui, comme nous le verrons, ne

nécessite aucun décorticage pour être prise à défaut.



OK - utilisons maintenant WinIce

Editez WINICE.DAT rajoutez la ligne suivante sous:

; ***** Examples of export symbols that can be included for Windows 95 *****



EXP=c:\windows\system\shrlk20.dll

(Nous permet de nous arrêter sur toutes les fonctions exportées, grâce à leur nom)



Redémarrez winice et posez le breakpoint:

bpx shrlk20!InputUnlockCode



Maintenant nous sommes prêts - posez votre Wodka et/ou cigarette(s)

à portée de main

Lancez WEBZIP.EXE

Entrez n'importe quel nom & numéro et cliquez sur OK - nous sommes arrêtés à:

(les adresses seront ~+160000h celles que j'ai montrées précédemment

car elles étaient copiées directement à partir de W32DSM89)



Exported fn(): InputUnlockCode - Ord:000Bh

:00429C38 55                      push ebp

:00429C39 8BEC                    mov ebp, esp

:00429C3B 6A00                    push 00000000

:00429C3D 6A00                    push 00000000

:00429C3F 6A00                    push 00000000

:00429C41 53                      push ebx

:00429C42 56                      push esi

:00429C43 57                      push edi

:00429C44 33C0                    xor eax, eax

:00429C46 55                      push ebp

:00429C47 68A09C4200              push 00429CA0		<** initialisation

:00429C4C 64FF30                  push dword ptr fs:[eax]

:00429C4F 648920                  mov dword ptr fs:[eax], esp

:00429C52 8D45FC                  lea eax, dword ptr [ebp-04]

:00429C55 8B5510                  mov edx, dword ptr [ebp+10]

:00429C58 E80397FDFF              call 00403360		<** initialisation

:00429C5D 8B45FC                  mov eax, dword ptr [ebp-04]

:00429C60 50                      push eax

:00429C61 8D45F8                  lea eax, dword ptr [ebp-08]

:00429C64 8B550C                  mov edx, dword ptr [ebp+0C]

:00429C67 E8F496FDFF              call 00403360		<** initialisation

:00429C6C 8B45F8                  mov eax, dword ptr [ebp-08]

:00429C6F 50                      push eax

:00429C70 8D45F4                  lea eax, dword ptr [ebp-0C]

:00429C73 8B5508                  mov edx, dword ptr [ebp+08]

:00429C76 E8E596FDFF              call 00403360		<** initialisation

:00429C7B 8B45F4                  mov eax, dword ptr [ebp-0C]

:00429C7E 5A                      pop edx

:00429C7F 59                      pop ecx

:00429C80 E8B7D7FFFF              call 0042743C		<** TRACEZ CET APPEL

:00429C85 33C0                    xor eax, eax

:00429C87 5A                      pop edx

:00429C88 59                      pop ecx

:00429C89 59                      pop ecx

:00429C8A 648910                  mov dword ptr fs:[eax], edx

:00429C8D 68A79C4200              push 00429CA7

:00429C92 8D45F4                  lea eax, dword ptr [ebp-0C]

:00429C95 BA03000000              mov edx, 00000003

:00429C9A E8B595FDFF              call 00403254

:00429C9F C3                      ret

:00429CA0 E9E791FDFF              jmp 00402E8C

:00429CA5 EBEB                    jmp 00429C92

:00429CA7 5F                      pop edi

:00429CA8 5E                      pop esi

:00429CA9 5B                      pop ebx

:00429CAA 8BE5                    mov esp, ebp

:00429CAC 5D                      pop ebp

:00429CAD C20C00                  ret 000C



Les appels à 403360 contrôlent les chaînes de caractères que vous avez entrées

(longueur etc)

Note: ce code est très brouillon car il n'utilise pas les fonctions standards

de l'API Windows (ie getdlgitemtext etc)



L'appel à 0042743C effectue les manipulations et

comparaisons avec beaucoup de transformations de chaînes,

conversion en majuscules etc



:004274B0 E88B2F0000       call 0042A440

:004274B5 8BD0             mov edx, eax

:004274B7 83EAFF           sub edx, -01		<** incrémente edx

:004274BA 7410             je 004274CC		<** mauvais jump si 0

:004274BC 4A               dec edx		<** -1

:004274BD 7426             je 004274E5		<** mauvais jump si 0	

:004274BF 4A               dec edx		<** -1

:004274C0 81EA6D010000     sub edx, 0000016D	<** -16d

:004274C6 720A             jb 004274D2		<** mauvais jump si -ve

:004274C8 7411             je 004274DB		<** semble bon

:004274CA EB15             jmp 004274E1		<** sinon mauvais



Le seul saut consécutif à une comparaison réussie est je 4274DB, 

ça semble une possibilité donc changez le 1er saut à

4274BA en JMP 4274DB pour éviter les autres tests ie:



:004274B0 E88B2F0000       call 0042A440

:004274B5 8BD0             mov edx, eax

:004274B7 83EAFF           sub edx, -01		

:004274BA EB1F             jmp 004274DB		<** toujours un bon saut

:004274BC 4A               dec edx



On aurai pu aussi modifier le code pour forcer eax à avoir 

la bonne valeur lors de l'appel à 42A440 ie 0000016E mais

on n'en a pas besoins ici (quelle chance!)



Après avoir torturé les chaines de caractères on arrive au test suivant:



:004034E1 8B0E          mov ecx, dword ptr [esi] <** notre numéro(modifié)

:004034E3 8B1F          mov ebx, dword ptr [edi] <** keske cè ?

:004034E5 39D9          cmp ecx, ebx		 <** les mêmes ?

:004034E7 7558          jne 00403541		 <** TEST ECHOUE!

:004034E9 4A            dec edx		         <** compteur

:004034EA 7415          je 00403501		 <** fini si 0

:004034EC 8B4E04        mov ecx, dword ptr [esi+04]

:004034EF 8B5F04        mov ebx, dword ptr [edi+04]

:004034F2 39D9          cmp ecx, ebx		 <** teste les 4 suivants

:004034F4 754B          jne 00403541		 <** TEST ECHOUE!

:004034F6 83C608        add esi, 00000008	 <** ajuste les pointeurs

:004034F9 83C708        add edi, 00000008

:004034FC 4A            dec edx

:004034FD 75E2          jne 004034E1		 <**boucle jusqu'à ce que edx=0

:004034FF EB06          jmp 00403507		 <** TOUT C'EST BIEN PASSE		



CE test peut être viré en 'noppant'(NOP) les 2 jne

403541, le test n'échoueras jamais. 

Ainsi, le 'bon' code à [edi] ne correspond pas 

à la chaine correcte - il manque 3 caractères

On aurais pu être embêter à ce point par la

'CheckProtectionDLL' routine 

si elle faisait un test du checksum du code de la

DLL, mais ce n'est pas le cas.

Faites dès à présent une copie de SHRLK20.DLL

Appliquez les patches, grâce aux offsets donnés par

W32DSM89, avec un éditeur hexadécimal et lanceé WEBZIP.EXE à nouveau

(enlevez les breakpoints d'abord)

La boîte de dialogue 'Time Expired - Register' se présente comme d'habitude

mais n'importe quelle combinaison nom/numéro est acceptée comme valide

maintenant, le seul problème est que nous devons le faire chaque fois

que le programme est lancé - pouvons nous faire un générateur de clé

pour l'enregistrer de façon permanente? possible.



En ce point, j'ai commencé a enquêter de façon plus poussée sur le système
ShareLock et j'ai téléchargée une 'demo' de SHRLK201.ZIP pour ce faire.



Le kit "demo" inclus un GENERATEUR DE CLE !!



Assurément cette'demo' n'est pas compatible avec 

la version complète?



Croyez moi ou non, ELLE L'EST!



Vous rappelez-vous de cette chaine de caractères 

'BUYWEBZIPNOWDUDESBUYWEBZIPNOWDUDES'?

On l'a déjà vue de nombreuses fois

C'est la clé pour le générateur de clé qui, quand

elle est saisie avec le nom, crée le code correct - essayez le!.



Donc, notre longue session de crack N'ETAIT PAS NECESSAIRE!



Nous pouvons maintenant effacer notre SHRLK20.DLL, patchée dans la douleur
et recopier l'original, tous les logiciels

protégés par ce système peuvent être enregistrés en 5 minutes.
C'est une honte de voir cette protection raisonnablement correcte,

défaite par l'éternelle quête pour le roi dollar - ça arrive si souvent. 


Les programmeurs qui ont crée cette protection

doivent être plus que contrariés de cette

situation où le vendeur donne les clés gratuitement - Je ne 
pense pas que cela durera longtemps..



Comme toujours, si le logiciel fait exactement ce que vous attendiez de lui

et que vous l'utilisez régulièrement, il vaut le

prix demandé pour son achat (très raisonnable dans ce cas pour

un bon utilitaire pour le net). 



Tous les honneurs vont au +HCU pour l'inspiration



(c) 1998 XaVaX All rights reversed

Traduit par Jordan_Jr