Confirm the format
Run the free VBScanner on the folder. It reads the file headers and tells you what built each EXE, DLL or OCX and whether it is P-Code, native or IL.
Our VB6 decompiler reads a compiled Visual Basic 6 program — an EXE, an ActiveX DLL or an OCX
control — and rebuilds the project: the .vbp, every form with its controls and
.frx resources, modules, classes, and the code behind them as readable Basic. It
handles both ways VB6 could compile: native x86 machine code, the hard case and our
specialty, and P-Code. Use it yourself with a license, or let us run the recovery.
See three native VB6 programs decompiled next to their original source →
Every VB5 and VB6 binary carries a VB5! header. From it the decompiler walks the
project information block to the object table: forms, standard modules, classes, user
controls, property pages, user documents and designers, each with its own object info and
type information. Form layouts are not text inside the EXE — each control's design-time
properties are a persisted property stream, which the engine reads back through COM using
VB6.OLB, and external OCX controls are instantiated by CLSID and asked to load their
own saved state. Pictures and other binary resources are split back out into .frx files.
The code is where the two kinds of VB6 program part ways. In the IDE you chose Compile to
Native Code or Compile to P-Code. A P-Code build imports only the runtime's interpreter
entry points (ProcCallEngine, MethCallEngine) and carries a token stream;
a native build imports the full __vba* helper set and carries real x86 machine code.
The decompiler tells them apart from the import table and uses a completely separate engine for
each. This page is mostly about the native engine; P-Code has its
own page.
A .vbp with Form=, Module=, Class=, UserControl=, PropertyPage=, UserDocument= and Designer= entries, MDI forms and menus, plus the Object= and Reference= lines for every OCX and type library the original used. ActiveX DLLs and OCX controls come back as proper ActiveX projects.
Each procedure is disassembled and folded back into VB idioms: If / ElseIf / Else, Do While, For / Next, Select Case (including compiled jump tables), string operations and comparisons, file I/O (Open For Binary, Get, Put, Line Input, Print #), Load / Unload, Is Nothing, and control arrays such as lblSkillName(i).Caption.
Win32 Declare statements are emitted once with their signatures, and well-known Win32 constants are substituted back for their numeric values.
The runtime's record descriptors let the engine rebuild every Type with its members and sizes, fixed-length strings included. On our Dungeon benchmark UDT_00405710 is the original MapType, field for field.
A Dim block opens every procedure, with types inferred from how each local is used — String, Long, Integer, a control class, a class you defined, or Variant when nothing narrows it.
Form and control names, class method names, event handlers with their parameter names, Public form procedures, Declare names and control property names all come back as written.
Every change to the native engine is gated against programs whose original source we hold, so
the numbers below are counts, not impressions. Placeholders are the markers the engine leaves
where it will not guess — an unresolved condition is <cond>, an unresolved
argument <arg>, an unresolved method call UnkVCall.
| Benchmark | Metric | Then → now |
|---|---|---|
| Dungeon (native VB6 game, full source) | Unresolved conditions | 426 → 65 |
GoTo fallbacks in place of structured blocks | 925 → 413 | |
Garbage compares (0 <> 0) | 77 → 7 | |
| Locals given a concrete type | 49% of 507 | |
| RPG World Online Auto-Updater | Unresolved method calls | 57 → 0 in the current build |
| Rodent's Revenge | Rebuilt project | compiles and runs |
Judge the output yourself — three native VB6 recoveries, line for line →
Local variable names, module-level global names, the names of standard-module procedures and of Private form procedures, user-defined type and field names, and user constants — both the names and, because the compiler inlines them, the values. Comments were never compiled in the first place.
The decompiler gives each of these a stable, readable placeholder — var_18,
arg_8, proc_401F20, global_0041B1A0,
field_C, UDT_00405710 — that your team renames as it reads. Where a
condition or argument cannot be proven, it is marked <cond> or
<arg> rather than filled in. A confident wrong answer is worse than an honest
gap, and the Dism view in the software shows the underlying instructions for any line you
doubt.
Run the free VBScanner on the folder. It reads the file headers and tells you what built each EXE, DLL or OCX and whether it is P-Code, native or IL.
License the software — $299 for one computer or $1,499 for your whole organization with the command line — and run it on your own machine. Nothing leaves your network.
Request a free evaluation. We examine the binary, tell you exactly what comes back, and quote a fixed price and timeline. Hand-finishing of anything the engine marks is included.
Yes. A VB6 EXE keeps the complete form layouts, the project structure, event-handler names, class method names and Declare signatures, and its code is either P-Code (decoded token by token) or native x86 (lifted back to Basic). What you get is a project that opens in VB6 with readable code and placeholder names where the compiler stripped the originals.
It matters for how faithful the code comes back: P-Code keeps more structure, native needs the reconstruction engine. The free VBScanner reads the VB5! header and tells you which you have in seconds. Both are supported.
Yes. ActiveX DLLs and OCX controls are rebuilt as ActiveX DLL and ActiveX Control projects with their public classes and user controls in place.
Frequently it loads and, after renaming placeholders and adding any missing declarations, compiles; our Rodent's Revenge benchmark rebuilds to a running EXE. The fastest route is to open the generated .vbp in VB6 and let the compiler's errors drive the clean-up. The evaluation tells you what to expect for your specific program before you commit.
UPX-packed programs are detected and unpacked automatically on a working copy. Other packers and protectors are assessed during the free evaluation, and a memory dump can be decompiled from an offset.
The evaluation is free and tells you exactly what your binary yields before you spend anything. Or license the decompiler and run it in-house today.