Stopping VB6's Cleanup by Patching vba6.dll

1. What You're Patching

In vba6.dll (VB6 SP6 English), two code paths check whether to delete generated .obj files. Those checks compile down to short-branch instructions:

File Offset (dec) RVA (hex) Original Opcode Meaning
866 517 0x0D38D5 0x76 (JBE) Jump if below or equal
866 577 0x0D3911 0x75 (JNE) Jump if not equal (ZF)

By changing both bytes to 0xEB (JMP short) you force an unconditional jump over the deletion logic-VB6 will leave the .obj files in place.


2. Verifying the Offsets

  1. Backup your vba6.dll from %SystemRoot%\System32 (e.g., vba6.dll.bak).
  2. Open it in a PE-aware hex editor and navigate to decimal offsets 866517 and 866577.
  3. Confirm you see bytes 76 at 866 517 and 75 at 866 577. If they differ, you may have a localized or patched variant.

3. Pure PowerShell Patch/Unpatch Scripts

Save these two scripts alongside your vba6.dll, then run them as Administrator.

VBA6Patch.ps1


param(
  [string]$DllPath = "vba6.dll",
  [int]$Off1    = 866517,
  [int]$Off2    = 866577
)

if (-not (Test-Path $DllPath)) {
  Write-Error "File not found: $DllPath"
  exit 1
}

$bytes = [System.IO.File]::ReadAllBytes($DllPath)

if ($bytes[$Off1] -ne 0x76) {
  Write-Warning ("Offset1 byte is 0x{0:X2} (expected 0x76)" -f $bytes[$Off1])
}
if ($bytes[$Off2] -ne 0x75) {
  Write-Warning ("Offset2 byte is 0x{0:X2} (expected 0x75)" -f $bytes[$Off2])
}

$bytes[$Off1] = 0xEB
$bytes[$Off2] = 0xEB

[System.IO.File]::WriteAllBytes($DllPath, $bytes)
Write-Host "Patch applied to $DllPath"
  

VBA6Unpatch.ps1


param(
  [string]$DllPath = "vba6.dll",
  [int]$Off1    = 866517,
  [int]$Off2    = 866577
)

if (-not (Test-Path $DllPath)) {
  Write-Error "File not found: $DllPath"
  exit 1
}

$bytes = [System.IO.File]::ReadAllBytes($DllPath)

if ($bytes[$Off1] -ne 0xEB) {
  Write-Warning ("Offset1 byte is 0x{0:X2} (expected 0xEB)" -f $bytes[$Off1])
}
if ($bytes[$Off2] -ne 0xEB) {
  Write-Warning ("Offset2 byte is 0x{0:X2} (expected 0xEB)" -f $bytes[$Off2])
}

$bytes[$Off1] = 0x76
$bytes[$Off2] = 0x75

[System.IO.File]::WriteAllBytes($DllPath, $bytes)
Write-Host "Patch removed from $DllPath"
  

4. How to Confirm It Worked

  1. Open the VB6 IDE and build any simple .vbp project.
  2. After the build completes, inspect your project's obj folder (or %TMP%). The .obj files should still be present.
  3. If they've vanished, ensure you ran the correct script against the right vba6.dll-on 64-bit Windows there may be one in SysWOW64.

5. Alternative Approaches


6. Summary

By applying this patch you prevent VB6 SP6 from cleaning up your .obj outputs-granting you full control over linker workflows and easing integration of VB6-compiled objects into larger C/C++ projects.