Virtual Drives v1.0
Tutorial by Lucifer48 [Immortal Descendants]
(August 17th, 1999)
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