Virtual Drives v1.0

Tutorial de Lucifer48 [Immortal Descendants]
(17 août 1999)



Target Program: Virtual Drives v1.0
Location: http://www.geocities.com/SiliconValley/program/3076
Protection: Name/Serial (vb6)
Level: Beginner (2-3/10)



Ce tutorial peut constituer une introduction au VB6-cracking.
On fait une première approche avec Smartcheck (menu Registratin Key):

cmdRegKey_Click

  _ fmRegistration (Form) created

  + fmRegistration_Load

  + fmRegistration.Show

      + Timer2_Timer

      + cmdOK_Click		;on ouvre ICI

      _ cmdCancel_Click

Voilà la partie intéressante:

...

Asc returns Integer:76		;"L" (de Lucifer48)

Mid

Asc returns Integer:117		;"u"

Mid

...

Asc returns Integer:86		;"V" (de Virtual Drives)

Mid

...

Mid

Asc returns Integer:115		;"s"

Hex				;pour mon nom: double.dblVal=381.887707641196

Hex				;pour mon nom: Long .IVal = 822 0x00000336

Hex				;pour mon nom: Long .IVal = 1396 0x00000574

MsgBox returns Integer:1	;"Wrong information..."

Les trois Hex montrent qu'il y a trois conversions héxadécimales (le 336h, j'ai tout de suite trouvé: il s'agit de l'addition de tous les caractères des lettre de mon nom; assez fréquent dans les crackme ; j'ai découvert par la suite que 574h était aussi l'additon des caractères du mot "Virtual Drives". Mais le réel (381.887707641196), d'ou vient-il ???

On va tout savoir en utilisant Soft-ice. La première chose à faire c'est mettre un bpx MSVBVM60!__vbaStrCmp. Soft-ice s'arrête ici:

XXXX:0042581F  PUSH DWORD PTR [ESI]		;m y  n a m e . . . (wide chars)

...

XXXX:0042582A  PUSH 004048B4			;null string

...

XXXX:0042586B  CALL MSVBVM60!__vbaStrCmp	;est-ce qu'on a entré un nom ? (si oui: eax=1)

On appuie sur F5, et ça rebreak encore:

XXXX:00425EDF  PUSH DWORD PTR [EAX]		;m y  s e r i a l . . . (wide chars)

...

XXXX:00425EF3  PUSH EAX				;le bon serial

XXXX:00425EF4  CALL MSVBVM60!__vbaStrCmp	;comparaison

Pour mon nom j'obtiens donc la registration:
Name/ Lucifer48
Serial / 17E336574


Mais comment est calculé ce nombre (héxa) ?
Il faut que je me retrouve au bon endroit au moment des trois conversions pour voir ce qu'il se passe; en conséquence je place un bpx MSVBVM60!rtcHexVarFromVar (pourquoi celui là ? parce que c'est le bpx qui correspond à la notation Hex de smartcheck; tout comme MSVBVM60!rtcMidCharVar correspond à Mid, etc.).

Remarque: Trois mots sur la fontion MSVBVM60!rtcHexVarFromVar, elle convertie une variable (entière ou réelle) en chaîne de caractères. Exemple: 123 => 31 00 32 00 33 00 00 00 (wide chars,et sans oublier la taille de chaine écrite juste avant la chaîne elle-même, ici: 2*3).

Premier (des 3) break:

XXXX:00425B62  LEA  EAX,[EBP-44]		;numéro (identicateur) de la variable (ici: 5)

XXXX:00425B65  PUSH EAX				;(entier ou flottant)

XXXX:00425B66  LEA  EAX,[EBP-54]		;pointeur sur: 00 00 00 00 xx yy zz tt

XXXX:00425B69  PUSH EAX				;où ttzzyyxx est l'adresse de destination (buffer)

XXXX:00425B6A  CALL MSVBVM60!rtcHexVarFromVar   ;(attention ce n'est pas toujours vrai)

Et donc, dans mon cas j'ai vu: 17E, et là, ça a fait tilt:

En effet: "17E"+"336"+"574"="17E336574"

336h: Somme des caractères de mon nom.

574h: Somme des caractères du mot "Virtual Drives".

Il ne reste plus qu'a déterminer la provenance du "17E". Et par chance, ça se trouve juste au dessus du code ci-dessus:

XXXX:00425AFC  MOV  EAX,[EBP-24]		;574h

XXXX:00425AFF  MOV  DWORD PTR [EBP-44],00000005

XXXX:00425B06  IMUL EAX,[EBP-20]		;336h (somme du nom)

XXXX:00425B0A  JO   00425D98			;pas de débordement: no jump

XXXX:00425B10  ADD  EAX,000007B2

XXXX:00425B15  JO   00425D98			;pas de débordement: no jump

XXXX:00425B1B  MOV  [EBP-012C],EAX

XXXX:00425B21  FILD DWORD PTR [EBP-012C]	;met l'entier dans la pile FPU

XXXX:00425B27  FSTP REAL8 PTR [EBP-0134]	;retire l'entier et le stocke (précision 64 bits)

XXXX:00425B2D  FLD  REAL8 PTR [EBP-0134]	;remet dans la pile FPU (en tant que flottant ..

...						; .. = Double Real (64 bits) )

XXXX:00425B3C  FDIV REAL8 PTR [004013A0]	;division par 3010

...

XXXX:00425B55  FSTP REAL8 PTR [EBP-3C]		;sauvegarde la flottant (sur 8 octets)

Remarque: 3010 est codé: 00 00 00 00 00 84 A7 40 en format flottant, le bit de signe est le bit 7 de l'octet le plus à droite; ainsi -3010 est codé: 00 00 00 00 00 84 A7 C0.

Et donc (pour mon exemple), on retrouve bien que 547h*336h + 7B2h = 1149482

et que 1149482 / 3010 = 381.8877...

Observons que: 17Eh = 382 donc le réel est arrondi (à l'entier le plus proche).

On termine par le keygen (en classique ANSI C++):

#include 

#define MAX 48		/* dummy number... */



void main(void)

{

double a;

long add_name=0, result;

int i=-1;

char name[MAX];



printf("\nKeygen for Virtual Drives v1.0 by Lucifer48/ID\n\n");

printf("Enter your name: ");

scanf("%s",&name);



while (*(name+(++i))!='\0')

  add_name += *(name+i);



a=(double)(add_name * 0x574 + 0x7B2) / 3010;

result=(long)a;

if ((a-result)>=0.5)

  result++;



printf("Serial: %X%X%X\n",result, add_name, 0x574);

}

Difficile de faire plus court :)

Dernière Remarque: Les infos de la registration sont stockés ici: [HKEY_LOCAL_MACHINE\Software\Babylone Soft\Virtual Drives].

Vous remarquez que tout (ou presque) étant présent dans smartcheck, il fallait juste savoir interpréter ! Voilà c'est terminé, j'espère que vous avez appris quelque chose en lisant celà.

Greetings: All ID members (Volatility, Torn@do, ...), Eternal Bliss, ACiD BuRN, LaZaRus, Duelist, etc.



(c) Lucifer48. All rights reversed