Visual Basic 5 and 6 executables have not left the triage queue. They are small, easy to produce with a builder, and a plain strings extractor gives a misleading picture of them: addresses, passwords and @Placeholder markers mixed together, with no indication of what the program actually uses.
Malva.RE now supports these executables. The report presents the project reconstructed by VBReFormer Gen 2 (7.x), readable procedure by procedure, and, for the DarkCloud family, an exfiltration configuration established from the code. The DarkCloud 4.9 case serves as the example; its complete technical analysis is published separately.
What the report shows
A project, not a list of strings. For a VB5/VB6 executable, the sample tree contains a [VB6 project] entry: the project file, the form or forms with their properties and event handlers, the modules, the resources and the export notes. Those notes flag what the reconstruction did not recover, rather than replacing it with a plausible value. Every module opens in the code reader; you can start from a form event and follow the calls down to the routines that prepare and send the data.
For DarkCloud, a configuration read in the code. When the Hunt_DarkCloud_Stealer_Variants rule, published by Evelyne Diaz Araque at Stairwell (rule and context), identifies a VB5/VB6 executable, the report presents the exfiltration transports the program contains and tells those this build enables apart from those it leaves disabled. For the active branch, the parameters are given with their role: recipient, server, account, password, port, SSL setting, authentication mode. For the disabled branches, builder markers stay markers, not network indicators. The staging directory is kept in symbolic form, with its environment variables.
What matters to the analyst is traceability: every value points back to the procedure and the argument that use it and, when the reconstructed code is not enough, to the disassembly that corroborates it. A value displayed without its context is a claim; a value tied to an instruction is verifiable.
Why a dedicated decompiler
Classic VB5/VB6, VBA and VB.NET share part of their syntax, not their execution format.
| Technology | What there is to analyze | In Malva.RE |
|---|---|---|
| VBA | Project embedded in an Office document, macro streams, Office-specific compiled representation | vbaDna: VBA decompilation and VBA Stomping detection |
| VB.NET | .NET assembly, CLR metadata, IL code | Outside the scope of this article |
| Native VB5/VB6 | x86 PE, VB metadata, machine instructions, MSVBVM60 runtime conventions | VBReFormer Gen 2 (7.x) — the case in this article |
| P-code VB5/VB6 | VB metadata and instructions for the VB virtual machine | VBReFormer Gen 2 (7.x) — outside the case in this article |
In a native VB6 program, the meaning of the x86 instructions depends to a large extent on the runtime’s conventions: BSTR strings carrying their length, VARIANT values carrying their type, late-bound COM calls whose primitive does not say which object or property is targeted. Matching instructions against the project structures and the runtime conventions is what turns a disassembly into readable procedures. The output remains a reconstruction: procedure names such as proc_46CD10 are for navigation, they are not the original names. The technical analysis details these difficulties and what VBReFormer Gen 2 (7.x) brings to overcome them.
The analyst journey
- Identify. The file is recognized as a VB5/VB6 executable; if it matches the DarkCloud rule, the configuration reading is added to the decompilation.
- Open the sources. Under
[VB6 project], forms and modules are read in the report; resources stay resources, the export notes remain readable separately. - Follow the program. From the form’s load event to the initialization, then to the collection routines and the sending dispatcher.
- Read the configuration. The transports, their state in this build, the values of the active branch and the unreplaced markers of the others.
- Verify. Every conclusion points back to a procedure, an argument or an instruction; an undetermined value stays undetermined.
DarkCloud 4.9, in brief
The sample studied, SHA-256 367383cfaa2ffc1404ba4ac1364a96992d78e036a0a67c994fbd6686f636474e, is a 460 KiB x86 PE compiled as native VB6, which identifies itself through the internal string Agent: DARKCLOUD V4.9. The Stairwell rule finds 14 $s* indicators out of 14 in it, against a threshold of 6 on that branch. It was never executed: decompilation, YARA checking and configuration reading operated on its bytes only.
VBReFormer Gen 2 (7.x) produced an export of 11 files, eight of which are code views: five application modules, one form and two generated helpers.
The configuration is read in an exfiltration dispatcher with four branches whose conditions are constant: 0 = -1 for FTP, HTTP and Telegram, -1 = -1 for SMTP. In this build, only the SMTP transport is enabled: server mail[.]mokasco[.]com quoted in defanged form, port 587, SSL setting false, authentication smtpauthenticate=1, i.e. cdoBasic. The three other branches exist in the code but only receive markers, @GateUrl, @StrBotToken, @ChatID: they are not network IOCs. The staging directory is %AppData%\Microsoft\Windows\Templates\%COMPUTERNAME%-%USERNAME%, kept with its variables.
That dispatcher is publicly browsable: Module7.proc_46CD10 in the VBReFormer demonstration. The Form1 form lets you start from the entry point. SMTP authentication illustrates the approach: the reconstructed code flags an unrecovered __vbaLateCallSt call, and it is the reading of the VARIANT in the malware’s x86 instructions that establishes the value 1.
The Malva.RE report for the sample shows the reconstructed project and the configuration as they appear to the analyst.

The dispatcher in the VBReFormer Online demonstration, lines 15 to 30: the constant condition 0 = -1 neutralizes the FTP branch, -1 = -1 enables the SMTP branch. Retouched capture: credential-bearing variables renamed, values replaced with <masqué>, host defanged.
The SMTP accounts, recipient and password, present in clear text in the file, are masked in this publication. The host name is a value from the file: it says nothing about the server’s current status and does not attribute the malware to the organization whose name it carries. The false SSL setting describes a configuration, not an observation of traffic.
What this support does not promise
Decompilation is a reconstruction, with its diagnostics. Original local names and comments are not in the executable; some expressions or calls can remain partial and are flagged as such. This case documents a native VB6 program: P-code belongs to the same tool, but not to this study.
The malware code is never executed. No connection to the extracted server, no trial of the credentials, no message sending were performed; the conclusions describe the code and its static configuration.
This case is neither a benchmark nor a comparison with other tools or other generations of VBReFormer. A clear-text configuration in this build does not mean every DarkCloud version stores its parameters that way, and a YARA match remains a starting point that the code has to corroborate.
Compressed executables first go through Malva.RE’s unpacking stages, such as static UPX unpacking.
Going further
- DarkCloud 4.9 Decompiled with VBReFormer Gen 2 (7.x), the complete study with VB6 and x86 excerpts.
- The formats supported by Malva.RE, where VB5/VB6 executables join PE files, Office documents, scripts and installers.
- Configuration extraction for the other supported families.
- VBReFormer, the VB5/VB6 decompiler.
Try Malva.RE on a real malware sample
Understand malware structure and behavior without execution
- Static analysis in under 10 seconds
- VBA, PowerShell and AutoIt deobfuscation (paid plans)
- Reports designed for SOC and malware analysts
Free plan: submissions and reports are public. Private from the Essential plan.
