
		MultiSMS Express v6.0.9
   
   Retreiving a valid serial and algorithm explained.

		          by
                 
		        L!M!T 

		  [The Exterminators]

		      March 1999
                
-------------------------------------------------------------
Program info for MultiSMS Express v6.0.9

Available @ :    http://tele-servizi.com/multisms/Index.html
Size        :    2.73 Mb
Language    :    Italian

Get the VB6IT.dll too just in case.

-------------------------------------------------------------
Tools used:

SmartCheck v6.01

-------------------------------------------------------------

The First Encounter
-------------------

Install MultiSMS Express v6.0.9.
Just answer 'Esci' to the questions during the installation
procedure, I believe it means 'OK'.

Well.. from the information displayed during the install,
we could see that the MSVBVM60.DLL and other Visual Basic
runtime files were copied. In other words, this utility
is programmed in Visual Basic, therefore we're gonna use
SmartCheck to try to get our serial and understand the
algorithm used to calculate a valid serial.

Let's go...

When the main window appears, press 'Sistema' and choose
'Registrazione programma'.

Another window pops up with some kind of EULA in Italian.
Press 'Accetto', and you're at the registration window.

In the first field you see a 'Numero di serie:' (serial number)
and in the other field you are supposed to enter your 
'Numero di registrazione' (registration number).
Just enter a number and hit 'Registra' (Register) and a window
will bark at you in Italian saying that the number you entered
was incorrect. I don't understand Italian so good, so we'll let
our good friend SmartCheck do the translation for us.



The Dissecting
--------------

Start SmartCheck, and make sure it is configured as below;

Program Settings;
                 Error detection - Check all boxes except 'Report errors immediately'
                 Advanced        - Check the 4 first boxes. Make sure that 'Suppress
                                   system API and OLE calls' is NOT checked.
                 Reporting       - All boxes checked, except for 'Report MouseMove
                                   events from OCX controls'

Make sure to visit Eternal Bliss at http://crackmes.cjb.net 
for more SmartCheck usage and configuration.

Load MultiSMS into SmartCheck by choosing 'File', 'Open' and choose
'MultiSMS.exe'. Start it by pressing F5.

Once you can see the main window of MultiSMS, press the button with
the red square (STOP) to terminate MultiSMS as we don't need to do 
anything more with MultiSMS. Otherwise you'll have zillion's of lines
in SmartCheck with Timer1_Timer. This Timer handles the rotation of the
picture in the top right corner in MultiSMS and that is not interesting.

Why we terminate MultiSMS so early in the process is, that your serial is
calculated at startup. Normally (read: other VB prog's) you would have to
click your way to the registration window, enter a fake serial and then
terminate the program to be able to see the routines in SmartCheck.

In SmartCheck again, go to 'View' and make sure that the following are
'checked'; 'Arguments', 'Sequence Numbers' (not necessary, but it adds some
orientation) and 'Suppressed Errors'.

Now, go to 'View' again and choose 'Show specific errors and events' if it's
not checked already.

The left window of SmartCheck is the 'Thread' of the program. It's here you
see what the program is doing. The right window displays arguments, values,
strings and so on.

Now, in the left window, look for 'MultiSMS_Load' and click the plus sign
next to it. If you can't see that, make sure that 'Show specific errors and
events' in the 'View' menu of SmartCheck is checked.

When you've clicked that, a huge amount of lines suddenly were added.
Loads of Chr$ commands and further down, some GetPrivateProfileString
commands. Then, a shitload of Double, DoEvents and Timer commands.
Not interesting. Anyway, continue down until you see 'Registrazione_Load'
and click the plus sign to expand the branch.

All those 'Form1_Load', 'Registrazione_Load' and 'MultiSMS_Load' are forms
(windows) that is displayed as the program loads or when you click a button
and a new window appears. 

The first 750 lines in this branch calculates the 'Numero di serie' by getting
your ProductId, ProductIdKey of the Windows installation and the volume information
from your harddrive. 

Since the serial number is based on the sum from this algorithm (Numero di serie),
the only thing we need is the result of this calculation. That's why we're not
interested in it. But feel free to take a look at it.

Almost directly after the GetVolumeInformation is a 'Str$' command, 
move on to the next 'Str$' further down in the branch.
This should say something like x.xxxx+00e where the x's are numbers.
If you click on this 'Str$' command, the value will be displayed in the right
window. Do you recognize that sequence of numbers? You are absolutely correct.
It's the first 10 numbers in our 'Numero di serie:'!

After this follows some 'Mid$', 'Asc$' and a few 'Val$' commands and after the
last 'Val$' in this sequence there is a 'Str$' command with a 'ByRef' value.
Click that line and watch the right window. There, my friend, is your 'Numero di
registrazione'! Don't type the dot in the end of the number when you register.
The registration number has been calculated...

So, how is this done? 


Algorithm Explained
-------------------

What you see in the left window now, is that some 'Asc$' commands are executed.
The 'Asc$' command in Visual Basic gets the ASCII value from a given character.
The problem now, is that you can't 'see' what's happening with those values
that are extracted from the 'Numero di serie:'

To get a better view, do this;
Click the SECOND 'Str$' command AFTER the GetVolumeInformation command.
Yes, we're back at the first ten numbers of our 'Numero di serie:'.
The line should have turned blue. 
Now, go to 'View' and choose 'Show all events'.

The screen changes slightly and SmartCheck is working... 

I hope you clicked the line, otherwise you could be lost... Really lost.
Hopefully, you can still see the same numbers in the right frame and the blue line
over the 'Str$' command in the left frame.

The screen has changed quite much now, and what you see now is the calls to
MSVBVM60.DLL and which functions that are called.

The 'Numero di registrazione' calculation begins at the FIRST 'Mid$' command
AFTER the 'Numero di serie' 'Str$' command.

Mid$(String:"1990944400", long:1, VARIANT:Integer:1)

(1990944400=I'm using this Numero di serie for explanation, you'll have a diff. one)

This means, what is the first (long:1) char in the String:"19909..." ?
How many chars do you want from position 1 in the string (VARIANT:Integer:1)
One char from position 1, result is 1

The __vbaStrMove put's this char away for later use.

Asc$(String:"1") returns Integer:49

This means, what is the ASCII value for the string "1"
The answer is 49 (returns Integer:49)

__vbaVarMove    moves the result (49) for later use
__vbaVarAdd     tries to add our result to the prior one. Since this was our first
                char, the formula is 0 + 49 = 49 (prior char+present char)
__vbaVarMove    moves the result (49) for later use
__vbaVarForNext I believe this is a loop function (For, Next) moving to the next
                char in the 'Numero di serie'
__vbaI4Var      Don't know what this one does..


Next char;

Mid$(String:"1990944400", long:2, VARIANT:Integer:1)

What is the second (long:2) char in the String:"19909..."?
We want one char this time too (VARIANT:Integer:1)
Take one char from position 2 in the String:"19909..."
Result is "9".

....
....



Asc$(String:"9") returns Integer:57

The ASCII value for string "9"
Result is 57. (returns Integer:57)

__vbaVarMove    moves the result (57) for later use
__vbaVarAdd     adds our prior ASCII result (49) to the present (57)
__vbaVarMove    moves the result (106) for later use
__vbaVarForNext Moves to the next loop function

This is done for the ten first numbers (chars) in the 'Numero di serie' string.
It retrieves the ASCII value for each char, adding it to the next char's ASCII
value, and so on, through the ten first chars in the 'Numero di serie' string.
Further down, you'll come across some __vbaVarMul functions.

The 'Mid$' prior to this __vbaVarMul function call takes the first NUMBER
in the 'Numero di serie' (1990944400), which is 1, and moves (__vbaStrMove) it
for later use.

Now check the sequence of the __vbaVarMul functions and what they do;

__vbaVarMul(VARIANT:Double:1.99094+00e, VARIANT:Integer:520)
                                                         |
The sum of the ASCII values------------------------------^

This takes our 'Numero di serie'(1.99094+00e) and multiplies it with the sum of
each char's ASCII value from 'Numero di serie', char by char (520)

__vbaVarMul(VARIANT:Double:1.03529e+012, VARIANT:Double:1)
                               |                        |
Value has changed!-------------^                        |
(this is the result from the prior __vbaVarMul)         |              
                                                        |
The first NUMBER in the 'Numero di serie'---------------^
(1990944400, The '1')

This takes the result of the prior __vbaVarMul (1.99094+00e * 520 = 1.03529e+012)
and multiplies it with the first NUMBER (not ASCII value) of the 'Numero di serie' 
sequence. Hence the 'Mid$' prior to the first __vbaVarMul.



Next line;
----------

__vbaR8Var(VARIANT:Double:1.03529e+012)

This takes the result from the last __vbaVarMul and multiplies it with 5.


The next 'Str$' command;
------------------------

Str$(VARIANT:ByRef Double:5.17646e+009)
__vbaStrMove(String:"5176455440" ......)

Moves the result of the __vbaR8Var and saves it for further use

The next command;
-----------------

Trim$(String:"5176455440)

Trims the string. Here is the 'Numero di registrazione'!


Algorithm...
------------

a = ASCII value of char[1]+char[2]+char[3]......+char[10] 

b = a * Numero di serie's FIRST TEN NUMBERS!

b = b * First NUMBER in 'Numero di serie'

code = b * 5

You might want to remove the three last digits from [code] to get a 
valid 'Numero di registrazione'.

Example: 1990944400 * 520 * 1 = 5176455440000
Remove the three zero's at the end and this is a valid 'Numero di registrazione'!
(for the 1990944400 Numero di serie...)


'Knowledge is neither given nor taken. It is earned.'


Regards,

L!M!T [TEX]