In this tutorial we will go over working with targets written in Visual Basic. Unfortunately, to become a well-rounded reverse engineer, we must know how to deal with these animals as there are many applications written in VB. Because this is a rather large subject, I will split it into two tutorials.

We will be looking at two crackmes, both included in the download of this tutorial. We will also be using VB Decompiler (the Lite version) which is included in the download.

As always, this tutorial, as well as all support files, can be downloaded on the tutorials



Introducing Visual Basic

Visual Basic is an event-driven language. This means that instead of a program running from beginning to end, VB reacts to events that happen in a window. This is similar to Windows programming in that events take place and call methods that are registered to handle those events, but VB differs in that most of the processing and message creation is performed in a DLL file. This file is the Visual Basic ‘runtime’.

The process of creating an application is a little different than, say, C++. You generally create a window (or dialog box) by dragging elements from a toolbox onto your window canvas. It is similar to C# .NET in this regard (and Delphi). Once you have your window built, you then create methods that will handle any events that can come from a user interacting with your windows contents; if a user clicks a button, the method you have made that handles the button event is called. If a user types in an edit box, the edit box method is called. Because the only code you are providing is the event code, most of the window’s processing is done for you. All of this processing is done in a DLL file called “msvbvm60.dll”, though the ’60′ may be different if using a different version of the runtime.

Another huge difference between Visual Basic and more traditional languages is a programmer has the option of compiling a VB application natively or in something called P-code. Native is simply assembly language, running natively on a processor, therefore OS and processor specific. P-code, on the other hand, is interpreted, much like Java and .NET, making it runnable on various operating systems. Interpreted means that, after compiling your VB application into P-code, when a user runs your application, something like a virtual machine is run, which interprets the P-code into native code for that specific operating system on-the-fly. When used, the p-code engine is a relatively simple machine that processes a series of “high-level” operation codes (“opcodes”). This engine is also stack-based, so very few arguments or functions are passed through registers.

The benefit of this is that if you install the VB runtime on, say, a Mac, then the P-code compiled application will be interpreted and run on a Mac. Switching to a Linux environment simply means running the Linux virtual machine (by installing the runtime), and voila, your app will run in Linux. Of course the downside is you take a speed hit as the code must be converted to native code before running.

Because VB applications can be compiled into P-code, the traditional debugging tools are a lot harder to use. Combine this with the fact that most of the time is spent in a DLL we don’t care about, and it can be quite challenging. The good news is that there are a couple tools out there that will help us. We will be going over these shortly.

Investigating The Target in Olly

When you first load a Visual Basic program in a debugger such as Olly, you will see a call is immediately performed into the VB DLL, where it will stay until an event happens. Because of this, VB programs are a little different to reverse engineer. The first thing you will notice is that the call stack is worthless; this is because most of the program’s running time is within a DLL file, the VB runtime DLL. We don’t care about this DLL, but we do care about the callback methods that handle events.

Another difference is in the way strings are handled. Because most of the message boxes, as well as all other window controls, are stored in resource sections, Olly won’t display strings like a traditional C or C++ program. Therefore, using strings to find relevant sections of code is usually not an option:

***If you want to see the following data yourself in Olly, load CrackmeVB1.exe.***

Another hindrance to reversing is the fact that the method calls are completely different in a VB executable. Instead of calls to such things as RegisterWindowEx and MessageBoxA, VB uses its own API calls, embedded in the runtime DLL:

Clicking through to one of these methods details the difference between VB and what we are used to:

As you can see, there are no helpful strings, no recognizable API calls.

Before we look at the tools at our disposal, let’s see what the basic file structure of a VB executable is. I have loaded CrackmeVB1.exe, which is compiled in P-code. Scrolling to the top of the code in the disassembly view, we see the list of functions in the binary:

This is a reference for the runtime for the API calls that will be needed when the program is run.

Scrolling down a little we come to the jump table. This is similar to the jump table seen in most windows binaries and is there to help with code relocation:

After this, we come to a vast sea of data. This is where the VB binary stores it’s resources. Anything from strings, to buttons, to callbacks are stored in here. One thing to note is that Visual Basic uses the actual name of a callback; so if you want “MyButtonCallback” to handle the button event, that string will be used to reference it. Because of this, you will see the various callback names embedded in this resource section:

Scrolling down (much) further, we get to the actual event callbacks. These are the user generated callback methods to handle the various events. As you can see, there is no documentation as to which callback methods each is, though we will change this later with MAP files:

Lastly we come to the Import Address Table, or IAT. We will get *much* more familiar with this in the tutorials on unpacking:

and that’s pretty much it. Obviously, this isn’t a heck of a lot of information to work with. Fortunately, we have a tool…

VB Decompiler Lite

VB Decompiler is available in both a ‘Lite’ and ‘Pro’ version, the Lite version being free (and so, the one included with this tutorial). VB Decompiler allows us to decompile Visual Basic code, that has been converted into P-code, back into the original VB source code. Well, almost anyway :) . It also allows us to view the resources embedded in the executable in a much friendlier format. Running VB Decompiler Lite, we first see the main screen:

Opening our first crackme, “CrackmeVB1.exe” and selecting the ‘Decompile’ button, we see the main project:

Most of this information is unimportant- mostly just file attributes etc. Notice, though, that in the project tree (under the ‘Forms’ folder) there are two forms, form1 and Form2. These are the resources associated with each form. Because there are two, we know that this application actually has two forms; One the main window and, in this case, one an about screen. Running that app confirms this:

You will also notice two additional things when running this target; The about screen is in a different language, and you cannot click the “OK” button in the about screen. If any of you have followed my tutorials on modifying binaries, you will know that, of course, this is my favorite thing about this crackme :) .

If you double click on “Form2″ in the “Forms” folder (in the project tree of VB Decompiler) we will see the various resources, along with attributes, for Form2:

Here we can see that there is one button with the text “OK”, one label with the text in a different language, and one callback method for the “OK” button event called “Command1″.

Double clicking on Form1 brings up the main window’s attributes:

Now we know several important things about this crackme; the important button is called “Check!” and has a callback method with the name of “Command2″, and Form1 is the main form we want to concern ourselves with. If you look down the tree, under the “Code” node, you will see the code that corresponds with the various forms. Opening the ‘Form1′ tree, we see that there are five callbacks, one for the “Checkit” button (Command2_Click_402FD0) and others for other buttons and mouse movements. If you run the target, you will see that the mouse movements callback is to change the color of the text when you hover over it.

What we want is Command2, as that’s our callback:

Double clicking on this shows us the actual assembly code…

The important thing about this screen is the address of the callback. All we really wanted to use VB Decompiler for (in this case) is to find the address of the callback for the “Checkit” button, which we can see is 402FD0. Going to this address in Olly (with the target loaded) shows us the beginning of the callback function:

If you set a BP here, run the target, and enter a username and serial, you will see that, after clicking the “Checkit” button, Olly pauses at our callback. We have now found our main registration callback code!!!

VB Decompiler Pro

I wanted to show what the actual P-code looks like, and for that we need VB Decompiler Pro. Unfortunately, this application requires that you buy it (… :) …) to use this function. Looking at the same code in VB Decompiler Pro looks like this:

Here, we can see the actual P-code method for the callback. First, several variables are set up. The background is changed at 4030A2, a procedure is called at 4030D9 (and it looks pretty interesting), and then what is probably our magic compare/jump is performed at address 4030E1. We can see that if the results of calling the procedure at 403800 are true, we will then jump to 4030E8. If not, we will fall through and perform the instructions beginning at address 4030E2. Taking a little time, we could actually find the patch this way, though I personally like going back to Olly to do it, as it doesn’t hurt my brain so much.

Patching the App

Going to address 402FD0, the beginning of the callback, we can see the actual code:

Setting a BP here and restarting the target, then stepping down some, we see at address 4030AA the background of the window changes color, just as we suspected from the P-code:

At address 4030E3, we see the badboy message pop up:

Looking at that area of code, we can see that right before it is a compare/jump combo:

Let’s set a BP at address 4030E1, restart the target, and see if that’s the check. When Olly pauses, changing the zero flag forces the jump at address 4030E1. Unfortunately, this doesn’t display anything. This means we want to take a closer look at the call to address 4032C0 at address 4030E3. Placing a BP here, restarting the target, and stepping in, we see the main decryption routine:

As we will see shortly, there are some very standard method calls in VB that should be memorized. Scrolling down the code, we see one of these at address 403644:

vbaVarTstEq is like StrCmp in native code- it checks two entities to see if they match. Highlighting the call down three lines at address 40364F and clicking “Enter”, Olly follows the call and we see we’re on the right track:

So we know we must make the code execute to address 403644. Looking above this at the various jumps, we find the following JE at address 40344F:

which jumps to the area of code we want:

So let’s place a BP at address 40344F, run the target, and change the zero flag to force the jump:

Now, stepping down to the JE instruction at 40364D, we obviously want to stop this from jumping over our call to the goodboy. Changing the zero flag when we land here, we see that we have in fact cracked the target:

Frequently Called Methods

As stated earlier, there are some methods that are called a lot when looking at protection schemes:


9 out of 10 times, one of these routines will be used to compare a serial with the correct one. One of these, _vbaVarTstEq, was used in the previous crackme.

Go ahead and load CrackmeVB2.exe into Olly. Performing a search of intermodular calls, we see one of our suspicious calls:

Here we see the call to _vbaStrCmp. Looking up the String.Compare method call in the Visual Basic API, we see that it takes two strings as arguments and returns an int. The return value is either -1, 0 (for equals) and 1, depending on if the first is greater than or less than the second, or zero if they are equal. This is what the call looks like in VB:

Double clicking this call in Olly, we jump to where this call is performed.

Let’s set a BP on this line and run the target:

Entering a password (I entered ’12121212′) and clicking OK, Olly breaks right where we want him to:

Looking down a little bit at address 403f40, we see our wonderful compare/jump instruction. Stepping down to there and changing the zero flag, then running the target, we see that this was our simplest crack yet :) :

There is a lot to take in here, but the most important thing is to mess around some on your own and discover how this stuff works on your own. I have included a crackme that we will be going over in the next tutorial (crackmeVB3.exe), so that you may try your hand at it. Following the same steps in this tutorial will solve this crackme as well.

In the next tutorial we will go over Smartcheck and the Point-H method, as well as creating MAP files.

-Till next time