Introduction
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
page.
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:
_vbaVarTstEq
_vbaVarTstNe
_vbaVarCmpEq
_vbaStrCmp
_vbaStrComp
_vbaStrCompVar
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
R4ndom
September 3rd, 2012 on 3:31 pm
Oh boy I just came across this site and at the moment at part 11 of the tutorials. And just now you added a new tutorial, thanks man, honestly words can’t describe how grateful we are to have you with us in this world.
The title of the tutorial got me wondering; we know that apps codded in C#, Java, VB do not get “translated” into ASM code, instead Bytecode that the virtual machine reads. Not sure, I am new and sorry for my ignorance but what I want to know is:
1- Do you deal with VB and C# in the same manner? seeing as they both use .net framework and CLR I think?
2- Do we deal with JAVA code in similar fashion? guess not because different framework and different VM?
3- Do executable’s language plays a huge role when RE? meaning if you know how to RE C++ programs, would it be similar to RE exes that are not codded in C++?
Sorry for my English, and I hope I didn’t bother you with my questions.
Thanks!
September 3rd, 2012 on 4:11 pm
You do not deal with .NET languages and Java in the same way. There are tools for each of those that help with reverse engineering.
And you deal with all languages that compile to native code the same. You deal with all ‘interpreted’ languages differently.
September 3rd, 2012 on 5:26 pm
Thanks for taking your time and answering my questions!
September 9th, 2012 on 2:57 am
What about enabling a button in a VB program, how can we do that?
September 9th, 2012 on 4:26 pm
I thought about including that but the tutorial was getting too long as it was! Maybe I’ll do a separate tut on that.
September 10th, 2012 on 5:34 am
Thanks.
For those readers interested in understanding how programs like VB Decompiler can actually all that info about a VB program, I recommend this paper I’ve just found, “Visual Basic Reversed – A decompiling approach”: http://www.reteam.org/papers/e46.pdf
September 10th, 2012 on 5:34 am
…can actually *gather* all that info
September 11th, 2012 on 12:30 pm
is there any way to bypass a form in visual basic p-code ???
for example i want to by pass form1. when some one open the exe it automatically opens the next form or form2 insted of calling form1 ???
September 11th, 2012 on 2:43 pm
NOP out the call to create form when dealing with form1
September 12th, 2012 on 12:30 pm
what is your email address can you see the target for me i tried every possibilty but failed :-p
September 12th, 2012 on 2:47 pm
Click “Contact” on the top of any web page to email me.
June 7th, 2013 on 7:32 am
What i do not realize is if truth be told how you’re not actually much more neatly-favored than you might be now. You are so intelligent. You understand thus considerably in terms of this matter, produced me for my part imagine it from a lot of varied angles. Its like men and women aren’t involved except it is one thing to do with Woman gaga! Your personal stuffs nice. At all times care for it up!