			VBCrackMe 3 explained

Written by Etenal Bliss
Email: Eternal_Bliss@hotmail.com
Website: http://crackmes.cjb.net
         http://surf.to/crackmes
Date written: 23rd April 1999

Program Details:
Language: Visual Basic

Learning Method:
Code Explanation
Parts of Softice Codes

Viewing Method:
Use Notepad with Word Wrap switched OFF
Screen Area set to 800 X 600 pixels (Optional)

__________________________________________________________________________

			    About the Essay

This is the third of the series of explanation on how coding in VB will
affect the cracking process. In these essays, I'll also show you how crackmes
are generally written in VB. I've included my thought processes that went
through my mind while coding for this crackme.

If you have missed the first 2 essays, go to my website and get it. 
Read it first before reading this because there are some parts 
which I will not repeat here again.

I've added some of Rhytm's tutorial to make things clearer.

To fully understand what I am describing, it would help if you have the 
CrackMe running and testing certain stuff out while you read.

__________________________________________________________________________

			    About the Protection

This crackme uses a hard-coded code which is hidden using another method
different from the 1st CrackMe.

This is what I wrote in the textfile for this CrackMe:
"Find the correct hardcoded code in this CrackMe. 

What you won't see:
1) The correct code using Hexeditor
2) The correct code in Softice
3) The correct code in SmartCheck"

In this CrackMe, instead of using String Compare (VBCrackMe 1) or Variant
Compare (VBCrackMe 2), I used a variable that contains the data in Long
format. This effectively makes cracking VB programs more difficult because
there is no definite breakpoints like the previous 2 compare methods. The
compare routine is in the main code itself and not in the DLL.

Instead of hiding the code, I used the manipulation of their Ascii to make
sure that only 1 code will fit the 3 checks I created, thus only 1 code will
be accepted. There was a bug in the CrackMe due to my error in calculations 
and I'll explain it later. Because of this bug, a number of codes were
accepted instead. 8(

__________________________________________________________________________

		A brief explanation on how VB coding is done...

Other than the things I mentioned in the first 2 essays, I'd like to add some
more commands that are frequently used.

Len("word") - To get the length of the string, in this case, 4 chars
**In SmartCheck, you will see Len(String:"word") returns LONG:4

__________________________________________________________________________


				Main Code

I've copied and pasted the main routine found in this crackme which is
the protection scheme, the heart of the crackme. In the next section, I'll
go into the explanation of some of the lines.

I've altered the name of the variables a bit so that they make sense. 8P


Private Sub Command1_Click()
Dim TotalNumber As Long, TrueTotal As Long
Dim DivideNumber As Long, NumberToDivide As Long
Dim r1 As Long, e As Long, v As Long, r As Long, s As Long
On Error GoTo err1

DivideNumber = 11496889
NumberToDivide = 2147483647
r1 = 82
e = 101
v = 118
r = 114
s = 115

For z = 1 To Len(Text1.Text)
TotalNumber = TotalNumber + Asc(Mid(Text1.Text, z, 1))
Next z

TrueNumber = r1 + e + v + e + r + s + e
If TotalNumber = TrueNumber Then

If ((Asc(Mid(Text1.Text, 2, 1)) = e) And (Asc(Mid(Text1.Text, 4, 1)) = e) And (Asc(Mid(Text1.Text, 7, 1)) = e)) Then

NumberToDivide = (NumberToDivide \ s) * r1) \ r) * e) \ v)
If NumberToDivide = DivideNumber Then

Text1.Text = "You have cracked it!!"
Text1.Enabled = False
Command1.Visible = False
Command3.Visible = True
Command3.Enabled = True
Command3.Caption = "&Again!"
Command2.SetFocus
GoTo err

Else
GoTo err1
End If

Else
GoTo err1
End If

Else
err1:
Text1.Text = "Wrong! Try Again!!"
Text1.Enabled = False
Command1.Visible = False
Command3.Visible = True
Command3.Enabled = True
Command3.SetFocus
End If
err:
End Sub


__________________________________________________________________________


				Code Explanation

1) Dim TotalNumber As Long, TrueTotal As Long
   Dim DivideNumber As Long, NumberToDivide As Long
   Dim r1 As Long, e As Long, v As Long, r As Long, s As Long
==========================================================================
Like my 2nd CrackMe, I define what the variables will contain using the "Dim"
command. You will notice that I've made all the variables to contain only
Data type of Long. The usefulness of this will be shown later.


2) DivideNumber = 11496889
   NumberToDivide = 2147483647
   r1 = 82
   e = 101
   v = 118
   r = 114
   s = 115
==========================================================================
These few lines are to tell the variables what their values are. If you see
step 1, you will notice that all these values will be of the Long Data Type.
One thing I found out was that by defining the values as Long, you will
not see these numbers if you open up the CrackMe using a HexEditor.
Therefore, it is another way of hiding numbers. But because Long Data Type
can only contain numbers, it is kind of limited by the fact that other chars
can not be hidden in this way.

Variables r1, e, v, r, s are the ascii values the code. As for DivideNumber
and NumberToDivide, that's where the bug started. 8(


3) For z = 1 To Len(Text1.Text)
   TotalNumber = TotalNumber + Asc(Mid(Text1.Text, z, 1))
   Next z
==========================================================================
This is the classical For...Next statement with some functions in it.
"For z = 1 To Len(Text1.Text)" will tell the CrackMe to make a loop of n
times where n is the length of the code you type in the textbox.
(Therefore, "Len(Text1.Text)")

"TotalNumber = TotalNumber + Asc(Mid(Text1.Text, z, 1))" is to add
up the Ascii value of individual characters found in the code you typed.
Remeber the function of "Mid" and "Asc"? Here, "Mid" will be performed first
to get the char and then "Asc" will convert it to its Ascii value.

"Next z" will tell the CrackMe to increase the value in z until it is equal
to the length of the code you typed.


4) TrueNumber = r1 + e + v + e + r + s + e
==========================================================================
This line tells the CrackMe to add up all the values of the variables I
defined earlier. If you noticed, the code is "Reverse". 8P


5) If TotalNumber = TrueNumber Then
==========================================================================
This is where the check occurs (the classical If...Then)
"TotalNumber" is the variable containing the sum of the ascii values of the
code you typed while "TrueNumber" is the correct ascii value.
Looking at this, you will notice that there will be a lot of possible values
for this CrackMe. Therefore, I coded for 2 more checks to make sure that only
1 code is accepted.

This is what Rhytm wrote in his tutorial:
:00402DC9 8945C8          mov dword ptr [ebp-38], eax
:00402DCC 8B45C0          mov eax, dword ptr [ebp-40]
:00402DCF 3B45C8          cmp eax, dword ptr [ebp-38]
:00402DD2 0F85B9060000    jne 00403491			<-- Important Compare

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

Well just look at the values behind ebp-xx, add them together (Total: 2DC).
You'll notice that the characters form the word "Reverse"
This value is compared with the total of the the ascii values of your serial..
Enter the serial and you've reversed this program !!!!
Now I tried to enter a code containing my nickname and some other characters 
that form a total of 2DC. And it didn't work :((
So there is more work to do for us :)



6) If ((Asc(Mid(Text1.Text, 2, 1)) = e) And (Asc(Mid(Text1.Text, 4, 1)) = e) 
   And (Asc(Mid(Text1.Text, 7, 1)) = e)) Then
==========================================================================
This is the second check. Again, the functions of "Asc" and "Mid" come into
use. This line will check the 2nd, 4th and 7th char of the code you entered
to make sure that they have the same value as the variable "e" which is 101 
and that is the ascii value of the char "e". Remember that the code is 
"Reverse".

This is what Rhytm wrote in his tutorial:
Open smartcheck, load the program enter the correct code and take a look 
at the new information:

MID(Variant:String:"Reverse",long:2,Variant:Integer:1)
MID(Variant:String:"Reverse",long:4,Variant:Integer:1)
MID(Variant:String:"Reverse",long:7,Variant:Integer:1)

Thus we see that the program checks is the characters at position 2, 4 and 7 
are the same as the ones in the word reverse. 
Knowing this we can find ourselves some other good serials.
Examples:
Reserve,Veserre,Peveste etc..
You could have done this at the SoftICE way too, two of the checks would 
be at addresses: 403115 and 403147  

End quote....

Well, the bug has shown...

7) NumberToDivide = (NumberToDivide \ s) * r1) \ r) * e) \ v)
If NumberToDivide = DivideNumber Then
==========================================================================
This is where the bug is. I have defined the variables "NumberToDivide" and
"DivideNumber" so that following the math routine of 
"(NumberToDivide \ s) * r1) \ r) * e) \ v)", "NumberToDivide" will be a 
specific value obtainable if the code is "Reverse". But due to error in my
coding, I used the values of "s", "r1", "r", "e" and "v" for the routine which
leads to the following "If...Then" statement will always be true. 
Thus, only 2 checks are effective. This 3rd check is rendered useless.

What I intended to do was to use the ascii values of the 1st, 2nd, 3rd, 5th
and 6th char of the code you typed to perform the math routine. Instead,
I used the variables I defined.


8) Text1.Text = "You have cracked it!!"
   Text1.Enabled = False
   Command1.Visible = False
   Command3.Visible = True
   Command3.Enabled = True
   Command3.Caption = "&Again!"
   Command2.SetFocus
   GoTo err
==========================================================================
This whole chunk of codes is to show in the textbox "You have cracked it!!"
when you entered the correct code and go to the end of the routine.


9) Else
   GoTo err1
   End If
   Else
   GoTo err1
   End If
==========================================================================
Notice 2 similar blocks of codes? The "Else...End If" is used twice here
for these two "If...Then" statements.
i) "If ((Asc(Mid(Text1.Text, 2, 1)) = e) And (Asc(Mid(Text1.Text, 4, 1)) = e) 
   And (Asc(Mid(Text1.Text, 7, 1)) = e)) Then"
ii)"If NumberToDivide = DivideNumber Then"

The "Else" here means that if the "If...Then" statement is not correct,
it will perform the function within it, thus "GoTo err1".
"Goto err1" tells the CrackMe to go to the location where there is a "pointer"
named as "err1:" and will show the "Wrong! Try Again!!" message in the textbox.


10) Else
    err1:
    Text1.Text = "Wrong! Try Again!!"
    Text1.Enabled = False
    Command1.Visible = False
    Command3.Visible = True
    Command3.Enabled = True
    Command3.SetFocus
    End If
==========================================================================
This is the final "Else" statement for the first "If...Then" statement which
is "If TotalNumber = TrueNumber Then"

That is how VB works. If there are a few "If...Then" statements, the "End If"
will be given to the closest "If...Then" statement unless it already have one.
Eg.
If...Then -----------------
     If...Then ---------   |
          If...Then -   |  |
                     |  |  |
          End If    -   |  |
     End If ------------   | 
End If --------------------


"err1:" is a "pointer" for the CrackMe. In each of the "If...Then" statements,
if the code entered is incorrect, the CrackMe will go to this part when the
command "GoTo err1" is given.

__________________________________________________________________________

		How to Crack such VB protection schemes

In this 3rd CrackMe, there is no use of the String or Variant Compare and thus
no compare breakpoints can be utilised. When Rhytm cracked the first check,
he showed the codes seen in Softice and these codes are in the main program
and not in the DLL file. Thus, there is no breakpoints like __vbaStrComp
nor __vbaVarTstEq.

To break such a routine, SmartCheck is quite valuable because it shows a lot
of information without you having to trace through all the junk codes VB
uses. But, in SC, you will never see the compare done at all.

Softice is superior in this sense. Like what Rhytm did, he is able to
see the compare in Softice. I quote again:

:00402DCC 8B45C0          mov eax, dword ptr [ebp-40]
:00402DCF 3B45C8          cmp eax, dword ptr [ebp-38] <-- Important Compare
:00402DD2 0F85B9060000    jne 00403491		      <-- Jump if not Equal

See that? Just two lines will determine the fate of the code you entered.
This is something like a cracker's nightmare. If all shareware authors uses
other Data Types instead of "String" and "Variant", it would be quite hellish
to crack VB programs. Firstly, Smartcheck will not be as useful and there will
be no fixed breakpoints to use. Let's hope not a lot of them read this essay. 8P

One possible breakpoint I can think of if a shareware author uses 
Long Data type is __vbai4str
"__vbaI4Str" changes the value type from "String" to "Long". So, it might
be worth trying out if "__vbaStrComp" and "__vbaVarTstEq" don't work.

__________________________________________________________________________

			Additional points


For other breakpoints and compare methods, you can get my two essays on VB
cracking found on my website.

SmartCheck logfile with the source is included together with this textfile
"Debug3.zip". Unzip everything in it and double click on the debug3.sce file. 

If you have installed SmartCheck, SmartCheck will open up and the usual
lot of information is shown. However, in this case, since the source code is
included, when you click on threads in Command1_Click line, you will see
how the source code is processed and how it is presented in SmartCheck.
A definite learning experience for those who are struggling with SmartCheck usage.
The first Command1_Click shows the lines processed when the correct code is
entered. The second Command1_Click shows the lines processed when the code
entered is wrong.

__________________________________________________________________________

				End of File

I would like to thank Jeff for giving me this idea of writing essays on how
I created my CrackMe, what commands will result in what breakpoints to use
in Softice and how SmartCheck's usefulness is exploited.

Thanks to Rhytm for cracking my CrackMe as well. 8)

All the best to those reading this essay in VB cracking!


