Note I have not virus scanned or tested all of the apps linked to in this page! user beware!

So today we are going to cover some resources on reversing VB6.

VB6 can be compiled to either native or pcode. Even when native the program flow is not linear from the entry point but is based on form, module and class structures passed into the vb runtime at startup. IDA can have a hard time locating everything however the vb.idc by Reginald Wong helps a lot. I am not aware of any vb6 pcode loaders for IDA yet so I would not recommend it for this case.

While these structures are not documented by MS reverse engineers have stepped in and figured a lot of its inner operations.

If you want to really get to the core of it take a look at the following resources:

Another great resource on the vb6 structures is the retired vb-decompiler.theautomaters.com message board. I was able to work with one of the admins to restore the board to flat html files so all that great info was not lost to the ages. The files are also available for download in both zip and chm format. Many thanks to MrUnleaded for helping resurrect this data!

So first thing..we need something that parses these VB6 structures and can tell us the project structure and where each function is in the binary. This is valid for both native and pcode projects and is all defined in the vb structures. From this we can determine the number of forms, classes, user controls, modules etc. For forms we can recover the form definition and objects used, along with their properties. At this stage we can also recover offsets for the code in all of the functions and even names for things like event handlers or public classes (in ActiveX dlls)

For this we can use a commercial app such as vb-decompiler.org ($99 home/$230 business) or VB-Reformer (free/$58 pro)

Free alternatives also exist. The formerly commercial, now open source semi-vbdecompiler by vbgamer45 looks very cool. (installer here)

Also be sure to check out p32dasm and racevb. For the sake of history you can also check out exdec by Josephco (possible newer version here)

There also exists some runtime analysis tools for VB6 apps. For native code Numega SmartCheck is an interesting tool that may be of some help if you can find it. Another tool I havent had a chance to play with yet is vb6tracer by Jurriaan Bremer and Marion Marschalek.

My favorite tool, and one that was like magic to me back in the day, is the WKTVBDE pcode v1.4 and v4.3 debugger by Mr. Silver & Mr. Snow. Also check out this tools help file for a listing of the vb opcodes, number of arguments etc. The VB P-code Information article by Mr Silver also goes into details on how the vb6 runtime processes pcode and how they implemented their debugger.

If your working with older versions of VB different tools apply. VB3 had a decompiler called DoDi's VB decompiler. (newer version. There is also an untested port of this is the vb semi-decompiler repo as well as on psc (local copy)

That should fill your noodle for a while.

Research I still want to do:
  • pour over the open source semi-vbdecompiler
  • probe the inner operation of the vb6 runtime and WKTVBDE debugger.
  • experiment with runtime tracing as found in smartcheck and vb6tracer.
  • get a firm understanding of vb pcode and try writing a decompiler for it
The WKTVBDE debugger design is interesting. A loader is used to inject the debugger dll into the target process. The target isnt actually running using the debug api, but a series of hooks on all of the vbruntime pcode handlers which are held in a table. The entire UI it presents and which controls program flow is running in the target process! What they wrote is quite extensive, debugging that would have been painful! I tried contacting the authors to see if they would ever consider releasing it open source since its so old and hasnt been updated in a long time. I never heard back though. I might end up recreating it.

Smartcheck uses a combination of techniques. It runs the target process in its own debugger, but also injects some substantial hook dlls. If you have time run hook explorer over a binary that is under analysis by smart check. Its interesting.

If you are dealing with vba pcode in office thats a different thing. You might want to look at pcodedmp





As kind of a catch all I am going to include some vb5 materials here as well.
Vb5sp3ds Contents:
	\dll\MSCDRun.dbg
	\dll\MSConDes.dbg
	\dll\MSRDO20.dbg
	\dll\MSVBVM50.dbg
	\dll\VB5DB.dbg
	\dll\vb5en.dbg
	\dll\vb5ide.dbg
	\dll\VBA5.dbg
	\exe\VB5.dbg
	\ocx\comct232.dbg
	\ocx\ComCtl32.dbg
	\ocx\ComDlg32.dbg
	\ocx\DBList32.dbg
	\ocx\mci32.dbg
	\ocx\MSComm32.dbg
	\ocx\msflxgrd.dbg
	\ocx\msinet.dbg
	\ocx\msmapi32.dbg
	\ocx\MSMask32.dbg
	\ocx\MSRDC20.dbg
	\ocx\mswinsck.dbg
	\ocx\PicClp32.dbg
	\ocx\RichTx32.dbg
	\ocx\SysInfo.dbg
	\ocx\tabctl32.dbg
Also I diffed the names in the pcode.engine between vb5/6. Some name changes but functions looks the same except:
	table,index,vb6name,vb5name
	5 3     StAryRecMove        InValidExCode       
	5 4     StAryRecCopy        InValidExCode       
	5 1D    Bos                 InValidExCode                 
	5 32    CDargRefUdt         InValidExCode       
	5 33    CVarRefUdt          InValidExCode 
Additionally vb6 adds more entries to the last table (vb5 has 0x33, vb6 0x45)
	table,index,InstrSize,xx,name
	5, &H34, 5, 0, "CVarUdt"
	5, &H35, 3, 0, "StUdtVar"
	5, &H36, 3, 1, "StAryVar" 
	5, &H37, 3, 0, "CopyBytesZero"
	5, &H38, 5, 0, "FLdZeroAry"
	5, &H39, 3, 1, "FStVarZero"
	5, &H3A, 7, 0, "CVarAryUdt"
	5, &H3B, 7, 0, "RedimVarUdt"
	5, &H3C, 7, 0, "RedimPreserveVarUdt"
	5, &H3D, 5, 1, "VarLateMemLdRfVar"
	5, &H3E, 7, 1, "VarLateMemCallLdRfVar"  
	5, &H41, 5, 1, "VarLateMemLdVar"
	5, &H42, 7, 0, "VarLateMemCallLdVar"
	5, &H43, 3, 1, "VarLateMemSt"
	5, &H44, 5, 0, "VarLateMemCallSt"
	5, &H45, 5, 0, "VarLateMemStAd"
This is 21 new pcodes for vb6
Also 33 new Exports added to vb6:
	__vbaRedimVar2
	__vbaVarLateMemCallLd
	__vbaVarLateMemCallLdRf
	__vbaVarLateMemCallSt
	__vbaVarLateMemSt
	__vbaVarLateMemStAd
	__vbaVarZero
	__vbaAryConstruct2
	__vbaAryRecCopy
	__vbaAryRecMove
	__vbaCVarAryUdt
	__vbaCopyBytesZero
	TipCreateInstanceProject2
	EbGetErrorInfo
	__vbaLdZeroAry
	__vbaRedimPreserveVar2
	__vbaUdtVar
	rtcFormatNumber
	rtcFormatCurrency
	rtcFormatPercent
	rtcFormatDateTime
	rtcWeekdayName
	rtcMonthName
	rtcFilter
	rtcInStrRev
	rtcJoin
	rtcSplit
	rtcReplace
	rtcStrReverse
	rtcRound
	rtcCallByName
	rtcCreateObject2
	rtcStrConvVar2