Visual Basic 4 / VB40032.DLL and VB40016 · always P-Code · 1995

VB4 decompiler: 32-bit and 16-bit, always P-Code, both handled.

Visual Basic 4 shipped without a native-code compiler, so every VB4 program — whether it was built for Windows 95 as a 32-bit PE or for Windows 3.1 as a 16-bit NE — is P-Code. That is good news for recovery: the token stream is decoded completely, and our VB4 decompiler measures itself against shipped source, statement by statement, on both kinds of build.

See a real 16-bit VB4 recovery, VisData, next to its original source →

// under the hood

Two containers, one language

A 32-bit VB4 EXE is a normal PE that imports VB40032.DLL; its entry thunk jumps into the runtime and a project header lists the forms, the external components and the project's names. A 16-bit VB4 EXE is an NE image importing VB40016, where every pointer is a far segment:offset pair patched by the loader — none of the 32-bit address logic applies, so the 16-bit build has its own engine, with every structure offset hand-verified against Microsoft's own sample programs.

Inside, the two share more than they differ. Form layouts sit in a designer stream that is byte-identical between the 16-bit and 32-bit builds. Public procedure names, parameter names and types live in an embedded type library. Event wiring lives in runtime control records that map each control's events to handler code. And each procedure carries a descriptor with its exact code length, so procedure bodies are bounded precisely, never guessed.

// what comes back

What the VB4 decompiler brings back

  • ✓

    Project, forms and modules

    A .vbp, one .frm per form with the full designer block and a .frx for its resources, and the standard modules with their code.

  • ✓

    Real event-handler names, read from the file

    The 16-bit event dispatch tables give Control_Event names directly — 48 of 48 exact on Microsoft's CONTROLS sample, and 372 handlers named on the 37-form VisData.

  • ✓

    Types, globals and module settings

    Type blocks with every member size exact, module-level global declarations, and each module's Option Compare setting inferred from the string-compare opcodes it uses.

  • ✓

    Structured code

    Select Case, If / ElseIf / Else, For / Next with Step, Do / Loop, GoSub, On Error, arrays with bounds and element types, ReDim and Erase, and Declare imports with signatures.

// measured

Measured against original source

BenchmarkMetricResult
3DMAZE (32-bit, with source)Procedures matched34 of 34
Statements semantically wrong / missing3 / 0
For / Next pairs, Type blocks, fixed-array bounds86/86 · 5/5 · 26/26
Generated projectcompiles to a running EXE
SETUP (32-bit, with source)Procedures and modules attributed178 of 178 · 10 of 10
Four 32-bit binariesP-Code bytes decoded100.0%, 0 truncated
VisData (16-bit, 37 forms)Forms and controls exact37 of 37 · 629 of 629
Event handlers named / exact372 named · 87% exact

See the VisData recovery →

// the fine print

What VB4 strips

Stored: the structure. Stripped: most of the names

Variable names and ordinary procedure names are gone (var_154, Proc_40C9AC), as are Type and member names (the layout is exact, the names read Type_30 / .field_8), constant names (values are folded in at each use), standard-module names (Module1) and Public/Private visibility. Some compiler temporaries the P-Code really materialises — Set t = X pairs — come back as written and can be tidied. The 16-bit engine is younger than the 32-bit one: a few Form_* event arities are inferred rather than read, and 16-bit .frx extraction is still being added.

// how to decompile your program

Three ways to get from the EXE to source

STEP 01

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.

STEP 03

…or let us do it

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.

// questions

VB4 decompiler questions

My VB4 program is 16-bit. Can it still be decompiled?

Yes. The 16-bit NE build has its own engine, verified offset by offset against Microsoft's samples: forms, controls, modules and real event-handler names are read straight from the file.

Why is VB4 always P-Code?

VB4 had no native-code compiler; that arrived with VB5. Every VB4 EXE is a P-Code token stream, which the decompiler decodes completely rather than reconstructing from machine code.

Can I open the result in VB6?

Yes. The output is a .vbp project. VB5 and VB6 open VB4 projects and upgrade them, which is often the point of the exercise.

// other formats

Every generation of Basic has its own page

Ready to decompile your VB4 program?

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.

free evaluation fixed quotes NDA available software from $299