VBReFormer 6.4 Released with support of for/next and array-related statements decompilation
As annouced previously, we just release the Free and Professional editions of VBReFormer 6.4.
This new version improve such a lot the decompiler engine and this is one of the most important release I’ve done until now.
The decompiler engine has been improved as it can now perform variable type determination. This means that VBReFormer is now able to guess the type of a variable and argument from its use inside the code.
We also added for/next support, and multi-dimensional array-related statements decompilation.
Example:
Original source code:
Private Sub Command1_Click() Dim myArr1(0 To 20, 14 To 50, 25 To 45) As String MsgBox UBound(myArr1) MsgBox LBound(myArr1) Dim myArr2() As Long ReDim myArr2(0 To 40, 30 To 55) MsgBox UBound(myArr2) MsgBox LBound(myArr2) End Sub
Recovered source code:
Private Sub Command1_Click() Dim var_2 (0 To 20, 14 To 50, 25 To 45) As String var_3 = MsgBox(UBound(var_2, 1), 0) var_8 = MsgBox(LBound(var_2, 1), 0) Dim var_9() As Long ReDim var_9(0 To 40, 30 To 55) var_10 = MsgBox(UBound(var_11, 1), 0) var_12 = MsgBox(LBound(var_11, 1), 0, , , var_13) End Sub
Lot of other improvement has been made, here is the full details:
New: Improved support of file I/O operation statements:
- __vbaGetOwner4
- __vbaGetOwner3
- __vbaGet3
New: Improved support of error statements:
- __vbaOnError
- __vbaResume
- __vbaGenerateBoundsError
New: Improved support of array-related statements:
- __vbaAryLock
- __vbaRedim
- __vbaRedimPreserve
- __vbaAryConstruct2
New: Improved support of FOR / NEXT loop-related statements:
- __vbaForEachAry
- __vbaNextEachAry
- __vbaExitEachAry
- __vbaForEachCollVar
- __vbaForEachVar
- __vbaForEachCollAd
- __vbaNextEachCollVar
- __vbaNextEachCollAd
- __vbaExitEachColl
- __vbaExitEachVar
- __vbaCyForInit
- __vbaVarForInit
- __vbaVarForNext
- __vbaRaiseEvent
- __vbaErase
New: Improved support of internal system statements:
- __vbaSetSystemError
- __vbaFreeVar
- __vbaFreeObj
- __vbaFreeStr
- __vbaFreeStrList
- __vbaFreeObjList
- __vbaFreeVarList
New: Improved support of string statements:
- rtcCompareBstr
- rtcInStrChar
New: Other improved statements:
- __vbaObjIs
- __vbaStopExe
- VarPtr
New: support of type consistency at decompilation time, this means that the decompiler engine can now be determinist about variable type
New: Support of OLE, PropertyPage, and UserDocument elements in GUI recovery & edition
New: Support of COM / OLE property edition
New: New settings windows that allows to:
- edit colors of source code’s syntax highlighting
- choose if you want only Visual Basic, assembly, or both (mixed) differently for viewing and saving
- choose your own prefix for private method and private variable name
- load (or not) the project in Visual Basic, or the destination folder once you saved it
Fixed issue on Import Table use
Fixed issue on Font properties in property editor and GUI edition
Fixed issue on saving settings
Fixed issue on default language setting (French was setup by default, now replaced by English language).
Fixed issue on VBReFormer setup packages for x64 Windows operating system
Fixed issue at loading some ActiveX libraries (“Run-time error `339`; Component `MSCOMCT2.OCX or one of its dependencies not correctly registered. “)
Fixed issue on resource viewer
Fixed issue on re-opening a VB6 application / library previously edited with VBReFormer Pro
Fixed issue on resource image preview, export, and replacement
Fixed issue on false negative detection of VBReFormer by antivirus or browsers as malicious software
Fixed “Object not found” exception at opening some executable
Fixed “About” dialog
VBCompTester discontinued: Use VBReFormer Free Edition instead
You all know that Visual Basic 6 allows you to choose between Native Code and P-Code compilation.
Because one of the most recurrent questions of my customers was if VBReFormer Pro will support decompilation of their application, due to the simple fact they don’t know if it was compiled in Native or P-Code, I’ve made a tool called “VBCompTester”, some years ago, which show you if a binary file (.exe, .dll, .ocx, etc.) was compiled using Visual Basic 5 / 6 and with what compilation mode (native or P-Code ?).
I have also made this tools because VBReFormer Free edition was not supporting decompilation at all, while VBReFormer Pro does. Then, you were not able to know, by using the free version, if the Pro one will support your application.
But the past year I decided to make VBReFormer Free and VBReFormer Professional from the same wood in order to give a real idea of VBReFormer Professional capabilities by using the free version.
Then, since June 2014, the both version of VBReFormer, free and pro, have the same features, but limited in the case of the Free edition.
Here are the main limitation of the Free Edition:
decompilation engine will not show name of code-inside object property in Free Edition. It will show something like “Me.[PROPERTY NOT VISIBLE IN FREE EDITION]” or “Me. [METHOD NOT VISIBLE IN FREE EDITION](param1, param2, param3)” in free edition; the feature of edition of GUI interface is not supported in Free Edition.
Since the Free Edition can now be used has a demonstration version of the Professional Edition of VBReFormer, I decided to discontinue the tool VBCompTester.
You can, and I advise you to use VBReFormer Free edition in order to know if your binary is made with Native or PCode option.
If you want to know more about the difference between the both compilation modes, you can read the following article: The truth about Native Code VS P-Code.
See you very very soon with a new version of VBReFormer which is gonna be the most powerful version I have made. 🙂
VBReFormer 6.2 Released with support of Unicode System & +11000 Win32 APIs
I’m delighted to announce that we’ve released VBReFormer 6.2 Professional Edition.
New features and improvements in this release include:
– Support of Windows UNICODE settings & applications in disassembling, decompiling, and editing Visual Basic 5 & 6 applications ;
– Exclusive support of +9000 others Win32 APIs (up to a total of 11 000 APIs) ;
– Support of Left & Right properties for ActiveX / OLE related objects ;
– Support of GUI interface Font properties edition ;
– Improved support of If / Then / Else / End If, Select Case […], and Loop / While statements ;
– Improved support of GUI Code for ActiveX / OLE related objects.
This release also include major fix for issues :
– Fixed issue in saving edited Visual Basic application with UNICODE environment ;
– Fixed issue in recovering executable resource images ;
– Fixed issue in « Options » dialog, taking account of your choice about APIs related decompilation ;
– Fixed issue in adding a new property to a GUI object .
New website: Decompiler-VB.Net V3.0 Launch !
I’m very excited to have finally launched the new version of Decompiler-VB.Net website (V3.0) after a full year of development!
Yes, I finally decided to communicate after a long period of development and testing. It’s all been completely re-coded from the ground up, and definitelly yes, the new website is officially up!
Totally renovated and multi-language, it will allow me to fulfill your orders faster, to answer your questions more quickly and it will allow you to track and verify your orders and licenses more easily.
The new website is currently translated in French and English, but we plan to add many other languages. Italian, Spanish, and Chinese language will be soon available.
My goals with the new website were to make it faster, easier to navigate for users, and easier for us to manage and update.
The website will now be updated more regularly to improve your comfort by being clearer and more interactive.
Have fun and see you soon !
The truth about P-Code
I. Introduction
This article has been written to provide a better and essential information to users of decompilers since I got many complaints from customers of others Visual Basic decompilers because their application weren’t recovered by these decompilers.
The reason is, when you write a Visual Basic 6.0 application you may choose a P-Code or Native code compilation, then your application will be compiled to P-Code or Native code which are very different approaches of compilation, so the decompilation will be different too.
There is a question you may absolutely ask yourself when you need a decompiler for a specific application: Is my application compiled into native or P-Code mode ?
The main problem is that a lot of users got a P-Code decompiler in order to decompile their application, but released with Native Code…
In fact, P-Code decompiler are today almost useless because 90% of Visual Basic 6 application are released with Native Code mode. This article will explain first the difference between P-Code and Native code, and then explain why the rate of Native code application is so important compared to P-Code applications. I. P-Code Versus Native Code
When you write a line of code in the IDE, Visual Basic breaks it down into expressions and encodes the expressions into a preliminary format called op-codes. In other words, each line is partially precompiled as it is written. Some lines contain shared information that cannot be precompiled independently (mainly Dim statements and procedure definitions). This is why you have to restart if you change certain lines in break mode. The opcodes are compiled into p-code instructions when you compile (in the background if you have the Compile On Demand and Background Compile options set).
At run time, the p-code interpreter works through the program, decoding and executing p-code instructions. These p-code instructions are smaller than equivalent native code instructions, thus dramatically reducing the size of the executable program. But the system must load the p-code interpreter into memory in addition to the code, and it must decode each instruction.
It’s a different story with native code. You start with the same opcodes, but instead of translating to p-code instructions, the compiler translates to native instructions. Because you’re not going to be expecting an instant response while stepping through native code instructions in the IDE, the compiler can look at code from a greater distance; it can analyze blocks of code and find ways to eliminate inefficiency and duplication. The compiler philosophy is that, since you compile only once, you can take as long as you want to analyze as much code as necessary to generate the best results possible.
These two approaches create a disjunction. How can you guarantee that such different ways of analyzing code will generate the same results? Well, you can’t. In fact, if you look at the Advanced Optimizations dialog box (available from the Compile tab of the Project Properties dialog box) you’ll see a warning: “Enabling the following optimizations might prevent correct execution of your program.” This might sound like an admission of failure, but welcome to the real world of compilers. Users of other compiled languages understand that optimization is a bonus. If it works, great. If not, turn it off.
On the other hand, very few developers are going to be used to the idea of working in an interpreter during development but releasing compiled code. Most compilers have a debug mode for fast compiles and a release mode for fast code. Visual Basic doesn’t worry about fast compiles because it has a no-compile mode that is faster than the fastest compiler. You get the best of both worlds, but it’s going to take a little while for people to really trust the compiler to generate code that they can’t easily see and debug.
Source : http://vb.mvps.org/hardcore/html/p-codeversusnativecode.htm
II. Proportion of P-Code application in the world
The amount of P-Code developed application is very small compared to Native Code developed application (90% of Visual Basic 6 applications are compiled with Native Code setting -default setting in VB6-), that is one of the reason why I decided to develop VBReFormer more for Native Code than for P-Code.
The massive number of Visual Basic Native application compared to P-Code applications is probably more important due to the fact the default value in the compiler is set up to « Native Code », and of course because native application are almost fast than C++ applications contrary to P-Code applications.
Before choosing a decompiler you must know if it was released for Native application, or for P-Code applications, and if your application was released in P-Code or Native mode.
Note that P-Code is more easy to decompile than Native Code because of it’s high level property.
C#: How to add some SortField to a CrystalReportViewer by using reflection
I’m currently working on a client’s project on migrating an important management application initially developed in VB6 to C# by using decompilation since the client lost his source code. This is my first .Net related post.
The application uses many external components, including the powerful Crystal Report component.
While I was working on this new version I faced a problem with the .Net implementation of Crystal Report.
Actually, with Visual Basic 6.0 it was an easy task to add one or many sort fields to a report document in order to sort the result by field (for example by “Lastname”, “Firstname”, “Id”, or other).
It’s not the case with .Net implementation of Crystal Report Document, on which you cannot dynamically add sort field to your report. You must add the sort field when you’re editing your report template. It’s not really convenient when you don’t know how many fields must be sorted when creating the document.
The reason of this missing is not really clear since it’s an existing feature on Visual Basic 6.0. We will learn here how to add many SortField to the ReportDocument of a CrystalReportViewer, using reflection.
Imagine you have to sort the request’s result by “Firstname”, “Lastname”, and “Id” fields, using the Crystal report document with the variable “Filename” as the report document path, and the variable “srcDataSet” dataset as the data source:
string[] sortFieldNames = new string[] { "Firstname", "Lastname", "ID" }; ReportDocument reportDocument = new ReportDocument(); reportDocument.FileName = String.Format("rassdk://{0}", Filename); reportDocument.SetDataSource(srcDataSet.Tables[0]); SortFields targetSortField = reportDocument.DataDefinition.SortFields;
Here we can modify the sort field (only if existing in the document):
DatabaseFieldDefinition fieldDef = reportDocument.Database.Tables["REPORTS"].Fields["FIRSTNAME"]; targetSortField[0].Field = fieldDef; targetSortField[0].SortDirection = CrystalDecisions.Shared.SortDirection.AscendingOrder;
But impossible to add directly a new field to that SortFields collection because no method allows performing action:
Actually, it’s possible to add a new sort field using the mother inherited class of each used component.
First we get the “SortFields” mother’s class of type (CrystalDecisions.ReportAppServer.DataDefModel.SortsClass ) by using the RasSorts private accessor of the SortFields object:
MethodInfo getRasSorts = targetSortField.GetType().GetMethod("get_RasSorts", BindingFlags.NonPublic | BindingFlags.Instance); object rasSorts = getRasSorts.Invoke(targetSortField, System.Type.EmptyTypes);
It return an object of type CrystalDecisions.ReportAppServer.DataDefModel.SortsClass.
Now we can access to the private “Add” method of the mother’s class:
MethodInfo addSort = rasSorts.GetType().GetMethod("Add");
The description of that method show that it accept one parameter of type CrystalDecisions.ReportAppServer.DataDefModel.ISCRSort.
ISCRSort is an interface, so we have to create a new instance of a class that implement the ISCRSort interface. That class is called “SortClass” and come from the “CrystalDecisions.ReportAppServer.DataDefModel” assembly.
Assembly rasAssembly = getRasSorts.ReturnType.Assembly; ConstructorInfo ciRasSort = rasAssembly.GetType("CrystalDecisions.ReportAppServer.DataDefModel.SortClass").GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, System.Type.EmptyTypes, null); object rasSort = ciRasSort.Invoke(System.Type.EmptyTypes);
Our “rasSort” object now instantiate the SortClass class, implementing ISCRSort.
Once the SortClass object is created, we must complete it with valid field, else it will return an error on execution.
The SortClass class uses the “RasField” accessor to define the field which will be sorted.
MethodInfo setSortField = rasSort.GetType().GetMethod("set_SortField", BindingFlags.Public |BindingFlags.Instance);
But this method only accepts an object implementing the ISCRField interface:
Void set_SortField(CrystalDecisions.ReportAppServer.DataDefModel.ISCRField);
So we have to extract the object of our field object (called fieldDef) that implement the ISCRField interface, it can be done with the “RasField” accessor of our DatabaseFieldDefinition object called “fieldDef”:
MethodInfo getRasField = fieldDef.GetType().GetMethod("get_RasField", BindingFlags.NonPublic |BindingFlags.Instance); object rasField = getRasField.Invoke(fieldDef, System.Type.EmptyTypes);
And now, the final touch, we add it to the collection:
addSort.Invoke(rasSorts, new object[] { rasSort });
Your new sort field has been adding to the SortFields collection, and you can now modify it:
int n = reportDocument.DataDefinition.SortFields.Count - 1; reportDocument.DataDefinition.SortFields[n].SortDirection = CrystalDecisions.Shared.SortDirection.AscendingOrder; reportDocument.DataDefinition.SortFields[n].Field = fieldDef;
That’s all.
VBReFormer: CrackMe Sample #1
Now that VBReFormer is a well advanced decompiler for Visual Basic application, I was searching for some unsolved crackmes in order to made sample of decompiling for learning purpose.
The website Crackmes.de contains an impressive number of crackmes applications, a perfect source of samples.
For the first sample of CrackMe solving with VBReFormer Professional I decided to take “Step 2” from yudi (more informations).
I will show you, step by step, how it’s simple to solve the yudi’s Step 2 using VBReFormer Professional.
- Running the application:
We can see that a serial is generated using the name of the user.
How the serial is generated? See the following step.
- Now we just open the “Step 2.exe” file with VBReFormer Professional and getting the following result:
- We will now take a look to the first method loaded on Visual Basic application.
We can see on this capture that the “Label4” visibility is set to False (not visible) at the beginning of the application.
Take a look to that control in the resource editor of VBReFormer and you will agree that it’s the control that show the message “Registered user!”
We now need to know where the “Label4” control visibility is set to true, and what does the “Timer1” control.
- The analysis of the Timer1 control is interesting but not very useful for the following of this tutorial.
We can see here that the “Timer1_Timer” function is called every second by “Timer1” control in order to check that no debuggers, and if one is running, to close it.
We can note that it also close any MessageBox windows.
- Now we are looking for the code under the “Try” button which check if the key match with the name.
That “Try” button is the “Command1” button in VBReFormer:
Then just look to the Command1_Click() function in order to see the algorithm of key checking:
The algorithm seems a little complicated for newbie, but complete and without any syntax and source code error from VBReFormer.
That’s a great thing for us; we will be able to test the application into the Visual Basic IDE later (to make a key generator for example).
By analyzing the code we can see the following:
Set var_pv2 = Me.Text1() var_pv3 = var_pv2.Text() var_pv10 = (var_pv3) var_pv11 = (Date$) & (" ") var_pv12 = (var_pv11) & (Time$) var_pv13 = (var_pv12)
This part of code is showing us that the key is generated from the Name, but also with the Date and the Time !
That’s meaning it’s almost impossible to generate a key that does not expire the following second.
- In order to made the Key Generator, save the project with VBReFormer, and open it with Visual Basic 6.
When it’s opened into the Visual Basic IDE, remove the debugger watching functions and just keep the following:
o Command1_Click
o Command2_Click
Now remove the following conditions block from Command1_Click function:
If (var_num8) Then var_pv6 = ("Hey") var_pv7 = ("need something") var_pv9 = MsgBox(var_pv7, 4160, var_pv6) End If
These block are showing an alert when the “Name” field and when the “Key” field are empty, but it’s not usefull for a keygen.
At the end of the Command1_Click function we can see the serial check condition:
Set var_pv2 = Me.Text2() var_pv3 = var_pv2.Text() var_pv21 = (var_pv3) var_pv22 = ((var_pv19 Like var_pv21)) If (((var_pv22) = (True))) Then Set var_pv2 = Me.Label4() var_pv2.Visible() = True End If
That code is checking that the serial (stored in var_pv19 variable) generated from the name with the algorithm is the same than the one entered in the “Serial” field (Text2.Text).
To show the generated serial, we just need to replace that condition block by the following line of code:
You must also remove the following line of code which remove the content of the both fields:
Set var_pv2 = Me.Text1() var_pv2.Text() = "" Set var_pv2 = Me.Text2() var_pv2.Text() = "" Set var_pv2 = Me.Text1()
After all change and simplifications, we have the following keygen code:
Private Sub Command1_Click() var_pv10 = Text1.Text var_pv13 = Date$ & " " & Time$ For var_pv14 = 1 To Len(var_pv13) Step 1 If IsNumeric(Mid$(var_pv13, CLng(var_pv14), 1)) Then var_pv15 = Asc(Mid$(var_pv13, CLng(var_pv14), 1)) If var_pv14 <= Len(var_pv10) Then var_pv16 = Str(Asc(Mid$(var_pv10, CLng(var_pv14), 1))) var_pv16 = Right$(var_pv16, 1) var_pv16 = Val(var_pv16) End If var_pv18 = var_pv18 & Chr$(CLng(var_pv15 + 17 + var_pv16)) var_pv18 = var_pv18 & Chr$(CLng(var_pv15 + 17 + var_pv16 * 2)) End If Next var_pv14 For var_pv14 = 1 To 24 Step 4 var_pv19 = var_pv19 & Mid$(var_pv18, CLng(var_pv14), 4) & "-" Next var_pv14 var_pv20 = Len(var_pv19) - 1 var_pv19 = Mid$(var_pv19, 1, var_pv20) Text2.Text = var_pv19 End Sub
- We now have to test our keygen:
- The first window is the windows of our KeyGen created from the original crackme, and the second window is the one of the original Crackme, with the key from the KeyGen.
The result is that our keygen work perfectly!
Just note that the use of date and time make your key valid for only 1 minute after having generated it.
Is it possible to bypass that limitation?
Yes it is ! In fact, to get the “Registered user!” message you even don’t need a key generator. By reading the code you can see that the operator used to perform a comparison between the both string key is the “Like” operator.
The “like” operator allows to comparate a string and a pattern…
Then you just can set “*” into the serial field and you will have a key which will be valid at anytime, with any name:
Source code of the key generator can be downloaded here:
http://www.decompiler-vb.net/documentation/crackmes/step_2.zip
Enjoy it !
VBReFormer: How to alter a Visual Basic 6.0 application
One of the most exiting feature of VBReFormer is design edition mode for binaries Visual Basic applications.
I have done this webcast to show that we can easily edit and alter an executable written with Visual Basic 6 with help of my half-decompiler VBReFormer 2007 Professional Edition.
For more information about VBReFormer: http://www.decompiler-vb.net/.
[WEBCAST ERROR]
New release: VBReFormer 5.4 Professional
I’m proud to announce the release and availability of VBReFormer Professional 5.4 (for licensed users).
The updated version of VBReFormer can be downloaded from your client account!
http://www.decompiler-vb.net/account.aspx
What’s new in VBReFormer Professional 5.4 ?
1. The analysis engine for disassembling and decompiling has been modified to recover language structure information (in order to decompile If/End If/Do/Loop/While blocks).
Then VBReFormer is now able to decompile simple conditions block like If/End If and Do/Loop/While conditions block.
2. The event name from controls is now back and shown on the code.
3. Conditions with Variant type and floating points type (Single and Double) is now supported because we included lot of news Visual Basic Virtual Machine functions:
__vbaVarTstEq
__vbaVarTstGe
__vbaVarTstGt
__vbaVarTstLe
__vbaVarTstLt
__vbaVarTstNe
4. An important bugfix has been applied. The problem was that VBReFormer sometime crashed on loading application on Windows XP, and was not showing every code from Visual Basic objects (vb6.old library was not properly setup).
5. New preference setting: You can now choose if you want to show only assembly code, only Visual Basic code, or the both.
Opening of the blog
Hi there, I’m Sylvain Bruyere, and welcome to my blog.
For those who don’t know who I am, in two words: I’m the author of VBReFormer, freelance developer focused on Microsoft development technologies in which I have a fair amount of experience, but that isn’t the whole story. I also have experience in security research, and a wide range of experience in reverse engineering.
Therefore, I have been partner of Microsoft for a while when I was student (Microsoft Most Valuable Student, then Microsoft Student Partner).
This new blog will allow me to express myself with the utmost freedom.
Decompilers, disassemblers, reverse engineering, security, C#, Visual Basic, .NET Framework, Visual Studio, SQL Server, Linq are as many topics that come to mind and which will soon be the subject of tickets here.
So bookmark this page and come back to read and comment on posts there!
C-u soon !
Sylvain