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