vbsourcecoderecovery.com / our recovery engine · v2.0 build 2.0.10

The Recovery Engine

Recover native‑compiled VB6 executables — real x86 machine code — back into editable Basic: procedures, forms, modules and classes. It also decompiles VB P‑Code, handles VB 1 to 5, and reconstructs .NET assemblies to C#/VB.NET.

Everything below was produced by the engine. On the left is the original, hand-written source; on the right is what it recovered from the compiled program. Jump to the examples ↓

// the hard part

Native VB6 decompilation — not just a disassembly

Most VB tools stop at P‑Code. Our engine goes after native‑compiled VB6 — the binaries that were built straight to x86 machine code — finds each procedure, and lifts it back into readable Basic. All three examples further down are native VB6 programs. Every other format — VB1 through VB5, VB6 P‑Code, QuickBASIC, twinBASIC and .NET — has its own proof page.

01

Native VB6 code recovery

The headline. Lifts native-compiled x86 procedures back into readable VB — events, module and class methods — with their logic, strings and API calls. A raw disassembly (Dism) view sits alongside, and UPX-packed binaries can be decompiled from an offset.

02

Project reconstruction

Rebuilds the .vbp plus every form, module, class, user control, property page and designer — ready to reopen in the VB6 IDE.

03

Form & control reconstruction

Reads the compiled form streams via COM (vb6.olb) to restore controls, properties and layout — with a control/form editor and a startup-form patcher.

04

P-Code decompiling

Programs compiled to VB 4/5/6 P‑Code are decompiled too: procedures, string literals, API calls and reconstructed control flow.

05

VB 1 to 5 support

Decompiles every 16-bit generation — VB 1 through 4 — with structured code, text forms and real event-handler names (VB1 even returns real variable names from its symbol table). Native VB5 is handled like native VB6.

06

.NET → C#, VB.NET & IL

Reconstructs classes, fields, properties and methods to C# and VB.NET with a full IL disassembly, and can build a Visual Studio solution.

07

Resource extraction

Pulls wmf, ico, cur, gif, bmp, jpg and dib images back out of the binary.

08

Headless CLI / batch mode

Decompile files and generate projects or solutions from a script — no window, no prompts, exit codes and a log.

// side by side

Original source vs. decompiled output

Three real native-compiled VB6 programs run through our recovery engine. All three were built to x86 machine code, and all three kept their original source — so you can judge the native recovery line for line. Pick a project, then a file, and compare.

Files
Original source
Recovered output
Reading the output: keyword type / constant string number comment decompiler-synthesized name

Names like var_18, arg_C, proc_401760, loc_00411AB0, global_00423088 and UnkVCall_000002B4h are generated by the decompiler — VB doesn't store those names in the binary, so they're reconstructed from stack offsets and call targets. Names it can recover (public event handlers, API declares, control names) come back exactly as written.

// native engine

Inside the native code engine

Reading P‑Code is the easy part. The hard part — the part most tools skip — is lifting native x86 machine code back to Basic. That work lives in one ~18,000-line engine with 330+ specialized passes, driven by an x86 disassembler. Here is what it actually does, procedure by procedure.

01

Disassemble

Discovers each procedure — including frameless functions found from their call sites — and linearly disassembles it with the OllyDbg engine, bounded by a dynamic per-proc window.

02

Rebuild control flow

A pre-pass suite reconstructs If / ElseIf / Else, For and Do While loops, Select Case from jump tables, and On Error / SEH — using labeled GoTo only where flow can't be structured.

03

Recover names & types

Stack slots become typed locals and parameters; stripped Subs are promoted to typed Functions; UDTs are rebuilt from their record descriptors.

04

Resolve calls

MSVBVM60 runtime helpers map to VB intrinsics and operators; vtable / UnkVCall sites resolve to control, OCX and user-class methods.

05

Emit VB

Writes clean VB — the Win32 Declare block, typed structs, file-I/O statements and named constants — as a .vbp you can reopen in the IDE.

What the engine recovers

every item below is backed by a real pass in the native engine
✓
Runtime-helper intelligence

Recognizes MSVBVM60 __vba* / rtc* helper calls and rewrites them as the VB functions, statements and operators a developer would have typed.

__vbaI4 → CLng · rtcMidCharBstr → Mid$
✓
Structured control flow

Rebuilds If / ElseIf / Else, resolving a shared compare across many conditional jumps and flag-reusing ElseIf chains — with honest labeled GoTo fallback.

If … ElseIf … Else
✓
Loop reconstruction

Detects For, Do While and variable-Step loops (from the sar/xor/cmp direction check) and names the counter slot and its increment.

NativeDetectForLoops · …WhileLoops
✓
Select Case from jump tables

Decodes computed jmp [reg*4+table] dispatch, including 1-based bases and nested two-level byte-map tables.

jmp [reg*4 + table] → Select Case
✓
COM / vtable call recovery

Resolves control and user-class method calls, control arrays, OCX late-bound DISPID dispatch, As New fields and New <class> through the object-info chain.

.UnkVCall → .Method / App / Load
✓
String & concatenation recovery

__vbaStrCat accumulators render as s = s & x, empty BSTR pointers become "", and __vbaStrCmp becomes real relational tests.

s = s & x
✓
Local variable type inference

Infers Dim … As types from how each stack slot is used — String, Long, control class, user class — instead of a blanket Variant.

49% of a 507-local benchmark concretely typed
✓
Parameter typing & Sub → Function

Types parameters from dereference width and cross-proc caller evidence, and promotes stripped module Subs to typed Functions from their accumulator epilogue.

Sub → Function As Long
✓
UDT reconstruction

Rebuilds Public Type definitions from __vbaRec* record descriptors and field offsets — user types that other VB decompilers don't recover.

Public Type UDT_… { field_0, field_4, … }
✓
Floating-point modeling

Tracks the FPU stack, distinguishes Double (m64) from Single (m32), folds FMULP/FADDP/… and recovers the ^ power operator.

__vbaPowerR8 → ^
✓
Array & UDT element access

Recovers SAFEARRAY reads/stores, nested 2-D arrays built via a lea/SIB stride, UDT-parameter fields and ReDim Preserve.

arg_8.field_<off> · a(i)(j)
✓
Guard suppression

Strips the compiler's SAFEARRAY bounds-check and FAILED(hr) HRESULT-guard cascades, removing bogus conditions and roughly halving the output.

bounds / HRESULT guards removed
Honest by design. Ours is deliberately a semi-decompiler: identifiers the compiler discards — module global names, standard-module procedure names, UDT field names and local names — genuinely aren't in the binary, so they surface as global_x, proc_x, field_x and var_x rather than a guess. Our optional AI naming pass (shown on the Parsec example) suggests descriptive names instead, and every one keeps its original placeholder in a 'was … comment so you can tell a suggestion from a recovered name. A few forms are still in progress (bottom-tested Do…Loop While, some 2-D array compares, RaiseEvent, class-method return types) and are shown as labeled GoTo or <cond> instead of invented output.
// beyond native VB6

Every other format, its own proof page

Native VB6 above is the main event — the hardest case in the business. But the engine reads the whole family, and each format has its own page of real recoveries: some judged against original source, some recovered from nothing but the EXE. More examples land on these pages over time.

VB1 · 16-bit P-Code

IconWorks (1991)

Real procedure and variable names — recovered from the symbol table VB1 left in the EXE.

✓ judged against original source
VB2 · 16-bit P-Code

MISSILE.EXE

A shareware game recovered straight from the EXE — no original source exists. What a real job looks like.

recovered from the EXE alone
VB3 · 16-bit P-Code

VisData (SDK sample)

Forms in VB3's own text format, real event names, structured code — line for line against SDK source.

✓ judged against original source
VB4 · 16-bit P-Code

VisData (VB4 edition)

The NE format most tools won't touch — real Control_Event handler names read from the file itself.

✓ judged against original source
VB5 · native x86

Frogger clone

Native machine code lifted back to VB — recovered straight from the EXE, no source existed.

recovered from the EXE alone
VB6 · P-Code

Miner VGA remake

VB's byte-code decompiled procedure by procedure — full project, judged against source.

✓ judged against original source
QuickBASIC 4.5 · DOS

Regatta (sailing game)

A DOS MZ executable reconstructed into structured BASIC — original source kept to compare.

✓ judged against original source
twinBASIC · native x86

Item Viewer

Forms, menus, real procedure and parameter names — from a native EXE with no VB header at all.

✓ judged against original source
.NET · CLR / IL

MapEditor (VB.NET)

One assembly, two reconstructions — C# and VB.NET — plus a ready-to-open Visual Studio solution.

✓ judged against original source

Want this run on your program?

Everything on this page was recovered by our engine. Tell us about the binary you're trying to bring back — the evaluation and quote are free.