Virtual Drives v1.0

Tutorial by Lucifer48 [Immortal Descendants]
(August 17th, 1999)



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



You can consider this essay as an introduction to VB6-cracking.
We are doing a first approch with Smartcheck (Registration Key menu):
cmdRegKey_Click
  _ fmRegistration (Form) created
  + fmRegistration_Load
  + fmRegistration.Show
      + Timer2_Timer
      + cmdOK_Click		;HERE
      _ cmdCancel_Click
This is the interesting part:
...
Asc returns Integer:76		;"L" (of Lucifer48)
Mid
Asc returns Integer:117		;"u"
Mid
...
Asc returns Integer:86		;"V" (of Virtual Drives)
Mid
...
Mid
Asc returns Integer:115		;"s"
Hex				;for my name: double.dblVal=381.887707641196
Hex				;for my name: Long .IVal = 822 0x00000336
Hex				;for my name: Long .IVal = 1396 0x00000574
MsgBox returns Integer:1	;"Wrong information..."
The three Hex show that there are three hexa conversions (for 336h, i know that it is the add of each characters of my name (pretty common in crackme); i discovered later that 574h was the add of the characters of the word "Virtual Drives". But this real (381.887707641196), where does it come from ???

We will know it by using Soft-ice. The first thing to do, putting a bpx MSVBVM60!__vbaStrCmp. Soft-ice stop here:
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	;is a name entered ? (if so: eax=1)
I press F5, and it breaks again:
XXXX:00425EDF  PUSH DWORD PTR [EAX]		;m y  s e r i a l . . . (wide chars)
...
XXXX:00425EF3  PUSH EAX				;the good serial
XXXX:00425EF4  CALL MSVBVM60!__vbaStrCmp	;comparison
For my name, i get the registration:
Name/ Lucifer48
Serial / 17E336574


But how is computed this (hex) number ?
I'd better look in the code when the three hex functions are performed; so i put a bpx MSVBVM60!rtcHexVarFromVar (why this one ? because it is the bpx which coincide with the notation Hex of smartcheck; same thing with MSVBVM60!rtcMidCharVar and Mid, etc.).

Remark: Few words about the MSVBVM60!rtcHexVarFromVar function, it converts a (integer or real) variable (variant) into a string. Example: 123 => 31 00 32 00 33 00 00 00 (wide chars, and just before the string, the length is stored, in my case: 2*3).

First (of the 3) break:
XXXX:00425B62  LEA  EAX,[EBP-44]		;number (dentifier) of the variant (here: 5)
XXXX:00425B65  PUSH EAX				;(integer or float)
XXXX:00425B66  LEA  EAX,[EBP-54]		;pointer on: 00 00 00 00 xx yy zz tt
XXXX:00425B69  PUSH EAX				;where ttzzyyxx is the address of a buffer
XXXX:00425B6A  CALL MSVBVM60!rtcHexVarFromVar   ;(warning, it is not all the time true)
And so, in my case i saw: 17E, and at this moment, i understood everything:
Indeed: "17E"+"336"+"574"="17E336574"
336h: Add of the characters of my name.
574h: Add of the characters of the word "Virtual Drives".
Stay now to find, how is computed the "17E". And by luck, it is located just above the first hex function:
XXXX:00425AFC  MOV  EAX,[EBP-24]		;574h
XXXX:00425AFF  MOV  DWORD PTR [EBP-44],00000005
XXXX:00425B06  IMUL EAX,[EBP-20]		;336h (name's add)
XXXX:00425B0A  JO   00425D98			;no overflow: no jump
XXXX:00425B10  ADD  EAX,000007B2
XXXX:00425B15  JO   00425D98			;no overflow: no jump
XXXX:00425B1B  MOV  [EBP-012C],EAX
XXXX:00425B21  FILD DWORD PTR [EBP-012C]	;push the integer in the FPU stack
XXXX:00425B27  FSTP REAL8 PTR [EBP-0134]	;pop the same integer and save it (format 64 bit)
XXXX:00425B2D  FLD  REAL8 PTR [EBP-0134]	;put the number in the FPU stack (it is now a float ..
...						; .. = Double Real (64 bit) )
XXXX:00425B3C  FDIV REAL8 PTR [004013A0]	;division by 3010
...
XXXX:00425B55  FSTP REAL8 PTR [EBP-3C]		;the the (float) result (on 8 bytes)
Remark: 3010 is coded: 00 00 00 00 00 84 A7 40 in this float format, the sign bit is the 7th bit of the most rigth byte; then -3010 is coded: 00 00 00 00 00 84 A7 C0.
For my example: 547h*336h + 7B2h = 1149482
and 1149482 / 3010 = 381.8877...
We see that: 17Eh = 382 so the real is rounded (to the nearest integer).
We finish with the keygen (in classic 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);
}
Difficult to make it smaller :)

Last Remark: Registration datas are stored here: [HKEY_LOCAL_MACHINE\Software\Babylone Soft\Virtual Drives].

You notice that (almost) all was notified by smartcheck. Well... it is the end, i hope you learn something by reading this.

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



(c) Lucifer48. All rights reversed