Visual Basic Cracking Part 2
(SmartCheck Usage)

Written by:
Eternal Bliss
Email: Eternal_Bliss@hotmail.com
Website: http://crackmes.cjb.net

Date Released:
23rd Jan 1999

Foreword:
I'd like to say that I'm a new cracker and I'll be updating this whenever I find any new information. If you have other useful information about SmartCheck that you think will benefit Newbies, please email me.


Introduction:

Have you ever wanted to crack a VB program but not sure where to start?
Have you ever tried right-clicking on the program file and choose QuickView to see what breakpoints you can set and to your horror, there are tons of them?
Have you tried going through every single one of them hoping to hit the "JackPot"?
Well, I experienced all of the above...

This is where SmartCheck comes in handy. It is something like a deadlisting debugger that will keep a record when it is running a program and will let you go through the information at your leisure.
The disadvantage is that you must know how to use and interpret what is shown to fully understand the power of it.
I'll be showing how to use SmartCheck and a bit of interpretation of the information shown in it. This is by no means a comprehensive guide and will only serve as the start of your VB cracking "career".


SmartCheck One-Time Configuration:

Under Program Settings:-
Error Detection: "tick" all boxes except "Report errors immediately". Click here to see a picture of it.
     Advanced: "tick" first 4 boxes. Click here to see a picture as well.
                       Make sure "Suppress system API and OLE calls" is not "ticked".
Reporting: All boxes "ticked" except for "Report MouseMove events from OCX controls". Click here for picture.


How to Run the Program You Want to Crack with SmartCheck

1) Start SmartCheck first.
2) Using "File", "Open", choose the file you want to run with SC.
3) To run the program, press F5. Or you may choose "Program", "Start".
4) To stop the program, choose "Program", "End".
It best if you fiddle around with the buttons in SC especially those on the toolbar and you will know how to control SC.


What you see after running the program with SmartCheck

1) You should have 3 small windows.
2) The main window you want to see is called "Program Results window". This is the window on the left with lines added to it when you are running a program.
3) The right window can be important as well because sometimes, you might just see the correct code in it.

Program Results window

After stopping the program, you would have to analyze the information given. Before that, you must select the relevant line and then choose "View", "Show All Events". For a more detailed instruction, please refer to the "General advice on VB Cracking" section in my essay "Compare Methods and Breakpoints". In this essay, I've written some of the more common lines that you will see.


SmartCheck Information

I've used BOLD words to show that it is what you'll see in SC. Words in RED means that you have to take special note of them.


****.Text eg. Text1.Text
If you click on the "+" sign next to it, you will get other lines under it. Look for SysAllocStringLen.
eg. SysAllocStringLen(PTR:00000000, DWORD:00000029) returns LPVOID:410584

Explanation:
Get the input you typed in the TextBox and placed it in memory location 00410584
This means that you will remove the need to do a "s 30 l" search in softice. To confirm, make sure your softice is running, then run the program in SC again and check the location again. Break into the program using Softice while running the program in SC. Then type "d 00410584". If you do it correctly, you will see what you typed in that memory location.
This will not work if you run the program alone without SC because the memory location might be changed.
Another instance this will not work is when the memory location is "released".


__vbasrtcmp(String:"zzzzz",String:"yyyyy")returns DWORD:0

Explanation:
__vbastrcmp -- used for comparing Strings eg. "zzzzz" and "yyyyy"
Note: you might see your correct code compared to what you keyed in!
returns DWORD:0 -- In Softice, you will see that after this comparison, eax = 0


__vbafreestr(LPBSTR:0063F3F0)
Click on the "+" sign next to it and look for SysFreeString
eg. SysFreeString(BSTR:00410584)

Explanation:
The String located at memory location 00410584 is cleared.


__vbaVarCopy(VARIANT:String:"12345", VARIANT:Empty) returns DWORD:63FA30
Click on the "+" sign next to it and look for SysAllocStringByteLen
eg. SysAllocStringByteLen(LPSTR:004023F0, DWORD:0000000C) returns LPVOID:4103CC

Explanation:
"12345" is copied to memory location 004103CC
This is similar to __vbaVarMove


__vbaVarForInit(VARIANT:Empty, PTR:0063F920, PTR:0063F91.....)

Explanation:
Set up a For...Next Loop
There will usually be __vbaVarForNext somewhere below as well.


Mid(VARIANT:String:"abcdefg", long:1, VARIANT:Integet:1)

Explanation:
Get the 1st character in the string "abcdefg" starting from location 1.
Click on the "+" sign next to it and look for SysAllocStringByteLen
eg. SysAllocStringByteLen(LPSTR:004103F0, DWORD:00000002) returns LPVOID:410434

Explanation:
"a" is copied to memory location 00410434
It is usually followed by __vbaStrVarVal(VARIATN:String"a") returns DWORD:410434


Asc(String:"T") returns Integer:84

Explanation:
Get the DEC value of T which is 84


SysFreeString(BSTR:004103F0)

Explanation:
Free memory location 004103F0
These lines are especially good for "serial fishing" because when you click on them and look at the right window, you will see what Strings are being freed. Correct codes/serials are sometimes shown here.


__vbaVarCat(VARIANT:String:"aa", VARIANT:String:"bb") returns DWORD:63F974

Explanation:
Join "bb" to "aa" to form "aabb"


__vbaFreeVar(VARIANT:String:"abcdefg")
Click on the "+" sign next to it and look for SysFreeString
eg. SysFreeString(BSTR:0041035C)

Explanation:
Free "abcdefg" from memory location 0041035C
Here, if you click on the line and look at the right window, you can also see what is being freed.


__vbaVarTstEq(VARIANT:****, VARIANT:****) returns DWORD:0

Explanation:
__vbaVarTstEq is used to compare variants. If they are not the same, DWORD=0 (so eax=0)
If they are the same, DWORD will be FFFFFFFF (so eax=FFFFFFFF)
Similar to __vbaVarCmpEq


Len(String:"Cracker") returns LONG:7

Explanation:
Get length of String "Cracker" which is 7


****.Text <-- "Wrong! Try Again!!" (String)

Explanation:
To display the String "Wrong! Try Again!!" in the Textbox


__vbaVarAdd(VARIANT:Integer:2, VARIANT:Integer:97) returns .....

Explanation:
Add 2 and 97, gives you 99
But if both are Strings instead of Integers, you will get 297 instead.


__vbaVarDiv(VARIANT:Integer:97, VARIANT:Long:1) returns.....

Explanation:
Divide 97 by 1


__vbaVarMul(VARIANT:String:"1", VARIANT:String:"2") returns ...

Explanation:
Multiply 1 by 2


__vbaVarSub(VARIANT:String:"2", VARIANT:String:"34") returns ...

Explanation:
Subtract 34 from 2, gives you -32


MsgBox(VARIANT:String:"Nope! That's not right", Integer:0, VARIANT:String:"Wrong",VARIANT.....)

Explanation:
Create a Message Box with title "Wrong" and message "Nope! That's not right"
  ;      <--Set "correct"as the "Correct Password"
entered = Text1.Text                                     <--Set "entered" as the password you entered
If correct = entered Then                              <--Compare using the Variant method
GoTo Correct Message
Else
GoTo Wrong Message
End If

There are no specific breakpoints for this type of method because the code for this comparison is in the main program and not in the VB dll file. Thus, they vary from program to program. Please refer to the section "General advice on VB Cracking" instead.
 

6) INTEGER COMPARE

This method uses two variables of Integer data type to compare with each other.
It is a data type that holds integer variables stored as 2-byte whole numbers in the range -32,768 to 32,767. The Integer data type is also used to represent enumerated values.
Therefore, one limitation to this method is that what is compared must consist of numbers only. But sometimes, in calculations routine where your Username is converted to Serial, the correct serial can be in the form of Integer.

An example of the code is like this:

Dim correct As Integer, entered As Integer     <--Defines "correct" and "entered" as Integer
correct = Correct Password                           <--Set "correct"as the "Correct Password"
entered = Text1.Text                                      <--Set "entered" as the password you entered
If correct = entered Then                                <--Compare using the Variant method
GoTo Correct Message
Else
GoTo Wrong Message
End If

There are no specific breakpoints for this type of method because the code for this comparison is in the main program and not in the VB dll file. Thus, they vary from program to program. Please refer to the section "General advice on VB Cracking" instead.
 

7) BYTE COMPARE

This method uses two variables of Byte data type to compare with each other.
It is a data type used to hold positive integer numbers ranging from 0-255. Byte variables are stored as single, unsigned 8-bit (1-byte) numbers.
Therefore, one limitation to this method is that what is compared must consist of numbers and only to the limit of 255. But sometimes, in calculations routine where your Username is converted to Serial, the correct serial can be in the form of Byte.

An example of the code is like this:

Dim correct As Byte, entered As Byte     <--Defines "correct" and "entered" as Byte
correct = Correct Password                   <--Set "correct"as the "Correct Password"
entered = Text1.Text                              <--Set "entered" as the password you entered
If correct = entered Then                        <--Compare using the Variant method
GoTo Correct Message
Else
GoTo Wrong Message
End If

There are no specific breakpoints for this type of method because the code for this comparison is in the main program and not in the VB dll file. Thus, they vary from program to program. Please refer to the section "General advice on VB Cracking" instead.
 

8) CURRENCY COMPARE

This method uses two variables of Currency data type to compare with each other. Yes, it might sound weird, but it works!!
It is a data type with a range of -922,337,203,685,477.5808 to 922,337,203,685,477.5807. Use this data type for calculations involving money and for fixed-point calculations where accuracy is particularly important.
Therefore, one limitation to this method is that what is compared must consist of numbers only. But sometimes, in calculations routine where your Username is converted to Serial, the correct serial can be in the form of Currency.

An example of the code is like this:

Dim correct As Currency, entered As Currency   <--Defines "correct" and "entered" as Currency
correct = Correct Password                               <--Set "correct"as the "Correct Password"
entered = Text1.Text                                           <--Set "entered" as the password you entered
If correct = entered Then                                    <--Compare using the Variant method
GoTo Correct Message
Else
GoTo Wrong Message
End If

There are no specific breakpoints for this type of method because the code for this comparison is in the main program and not in the VB dll file. Thus, they vary from program to program. Please refer to the section "General advice on VB Cracking" instead.


So, does that mean that with these 8 compare methods, we can break into every single compare routine? The answer is NO. This is because, I also realise that other than these 8, comparison can be made between Currency and String, Variant and Long etc...
So, I've created this table...

Compare Table

 
String
Variant
Long
Currency
Single
Double
Integer
Byte
String
Normal
V
SD
SC
SS
SD
SD
SD
Variant
-
Normal
V
V
V
V
V
V
Long
-
-
Normal
__vbaFpCmpCy
Sin to D
DC
DC
DC
Currency
-
-
-
Normal
__vbaFpCmpCy
__vbaFpCmpCy
__vbaFpCmpCy
__vbaFpCmpCy
Single
-
-
-
-
Normal
DC
DC
DC
Double
-
-
-
-
-
Normal
DC
DC
Integer
-
-
-
-
-
-
Normal
DC
Byte
-
-
-
-
-
-
-
Normal

V   = Variant Compare
SD = String is converted to Double before comparing
SC = String is converted to Currency before comparing
SS = String is converted to Single before comparing
Sin to D = Single is converted to Double before comparing
DC = Direct comparison
__vbaFpCmpCy = Floating point Compare Currency

From this, you will probably realise by using Softice without other tools, you will have a hellish time trying to figure out what sort of breakpoints to set near the compare routine. This is where SmartCheck comes in handy... Look below on how to use SmartCheck in general VB cracking.


POSSIBLE BREAKPOINTS

There are a lot of them and I've just listed down the commonest few.

1) Data Type Conversion
i) String to Byte or Integer: __vbai2str
ii) String to Long: __vbai4str
iii) String to Single: __vbar4str
iv) String to Double: __vbar8str
v) String to Currency: VarCyFromStr (for VB6. You have to have oleaut32.dll in your winice.dat)
vi) Integer to String: VarBstrFromI2 (for VB6. You have to have oleaut32.dll in your winice.dat)

2) Moving Data
i) String to memory: __vbaStrCopy
ii) Variant to memory: __vbaVarCopy or __vbaVarMove

3) Mathematical
i) Addition: __vbavaradd             <--Adding Variants
ii) Subtraction: __vbavarsub        <--Subtracting Variants
iii) Multiplication: __vbavarmul      <--Multiplying Variants
iv) Division: __vbavaridiv            <--Dividing Variant to get answer in Integer
v) XOR: __vbavarxor                 <--XOR

4) Miscellaneous
i) __vbavarfornext           <--Used in codes where there is a For... Next... Statement (Loop)
ii) __vbafreestr
iii) __vbafreeobj
iv) __vbastrvarval            <--Get the value from a specific location in a String
v) multibytetowidechar
vi) rtcMsgBox
vii) __vbavarcat               <--Joining 2 Variants together
viii) __vbafreevar
ix) __vbaobjset


General advice on VB Cracking:

The unique part of VB cracking is that there is SmartCheck to help us. It is a very useful program and you should learn how to use it well. Or at least understand what it is showing. We often use Softice in programs written in other languages and W32Dasm. W32Dasm is more or less useless in VB cracking. But luckily, we have SmartCheck. I'll try and give a brief account of how to go about cracking using both SmartCheck and Softice at the same time.

1) As a rule thumb, run the program a few times. Try and see what messages are shown, the way the program acts.

2) Use SmartCheck to run the program. For general settings of SmartCheck, you can find it on the website stated on top of this essay. After running once and trying to register, close the program down (Not SmartCheck). When you choose "Show All Events", a whole chunk of information can be seen. And it is very easy not to find the lines you need. So, click on the line you want before choosing "Show All Events". Usually, it is xxxxxx_Click. xxxxxx is the name of the button refered to by the program. For programmers that are too lazy to change the name, it is usually CommandX_Click where X starts from 1.

3) Look for __vbastrcomp, __vbastrcmp or __vbavartsteq first. If you are lucky, you might just see the correct code being compared to the one you entered.

4) If you can't find the 3 of them, most probably the program uses the other comparison methods. Now, go through the lines and look for the Bugger-off message. A few lines above it, there are usually the few __vba commands I listed. Start from the one nearest to the Bugger-off message line. Set your breakpoint using it. Count the number of occurence of the breakpoint you set and use F5 in Softice to return to the program and break again.

For example, if you set __vbafreestr, there might be a lot of them used after you click on the register button. And if the specific breakpoint you want is shown to be the 10th __vbafreestr in SmartCheck, you have to press F5 nine times to get to the 10th __vbafreestr.

Remember that if you are cracking a VB6 program, add msvbvm60! in front.

5) Run the program, enter whatever is needed and click to register. Softice WILL break unless you set the breakpoint wrongly. One weird thing I discover in VB6 is that I need to set the breakpoint FIRST before I run the program. Remember that. It might apply to older VB versions.

6) Start tracing into EVERY call and display any suspicious register changes. It won't take you long since you are near to the Bugger-off message. If you did not come across anything suspicious, go back to SmartCheck and look for the next breakpoint. The previous breakpoint might be after the compare routine.