VBE File Documentation
Summary
A VBScript Encoded Script File is a VBScript that has been scrambled with Microsoft’s Script Encoder (screnc.exe) so its source is unreadable. A .vbe still runs like a plain .vbs: double-clicking it executes the script through the Windows Script Host, which decodes it at runtime. Its MIME type is text/vbscript. The encoding is reversible obfuscation, not encryption, and is often abused by malware.
Technical details
| Feature | Value |
|---|---|
| Full name | VBScript Encoded Script File |
| File extension | .vbe |
| MIME type | text/vbscript, application/x-vbe |
| Format type | Encoded (obfuscated) text script |
| Developer | Microsoft |
| Introduced | Late 1990s, alongside VBScript and the Windows Script Host |
| Encoder tool | Microsoft Script Encoder (screnc.exe) |
| Executed by | Windows Script Host (wscript.exe / cscript.exe) |
| Underlying language | VBScript (the encoded counterpart of .vbs) |
| Encoding | Reversible obfuscation (polyalphabetic substitution), not encryption |
| Encoded block marker | #@~^ start, ^#~@ end |
| Magic number | None at a fixed offset; recognised by the #@~^ marker |
| Byte order | Not applicable (character-based text) |
| Open standard | No |
| Character encoding | ASCII / ANSI text |
| JScript equivalent | .jse (JScript Encoded) |
| Related extensions | .vbs, .jse, .js, .wsf, .hta |
| Security risk | High — common malware obfuscation vector |
| Deprecation | VBScript is an optional Feature on Demand in Windows 11 24H2; removal planned in a later release |
| Recommended replacement | PowerShell (.ps1) |
| Specification | learn.microsoft.com (Script Encoder, archived scripting articles) |
What is a VBE file?
A .vbe file is a VBScript Encoded Script File: an ordinary VBScript that has been passed through Microsoft’s Script Encoder to scramble its source. It is the encoded counterpart of a plain .vbs file. The encoder appeared in the late 1990s alongside VBScript and the Windows Script Host (WSH), and Microsoft shipped it as a small command-line tool, screnc.exe. The idea was to let web developers and administrators distribute VBScript (in classic ASP pages, Internet Explorer pages, or standalone .vbe/.jse files) without exposing the readable code.
The important thing to understand is what the encoding is not. It is not compilation and it is not encryption. A .vbe holds the same logic as the original script, transformed by a fixed, reversible substitution. The Windows Script Host decodes it transparently at run time, which means a .vbe behaves exactly like a .vbs: double-clicking it runs the script rather than showing it. The rest of this page describes how the encoder wraps and transforms the code, how WSH executes it, and why the “encoding” gives a false sense of protection.
The Script Encoder and screnc.exe
The Microsoft Script Encoder is a single-purpose utility. You give it a source file and it emits an encoded copy, changing the extension to signal the result: a VBScript .vbs becomes .vbe, and a JScript .js becomes .jse (see JavaScript/JScript). It can also encode script embedded inside HTML, ASP (.asp), scriptlet (.sct), and HTA files, in which case only the script blocks are touched and the surrounding markup is left alone.
A typical invocation looks like this:
screnc.exe source.vbs output.vbe
Both new extensions, .vbe and .jse, are registered with the appropriate scripting engines, so Windows knows which decoder to hand the file to. The encoder does not embed a password or a key: any machine with the matching scripting engine can decode and run the file. That is by design, because the whole point was runtime transparency, but it is also the reason the scheme protects nothing. VBScript itself is now end-of-life. Microsoft has deprecated it; in Windows 11 version 24H2 and Windows Server 2025 it became an optional “Feature on Demand” (still enabled by default for now), and it is scheduled for removal from Windows in a later release. Internet Explorer, which hosted VBScript in the browser, was retired in June 2022.
The #@~^ marker and encoded-block layout
Because encoded script can sit inside a larger HTML or ASP file, a .vbe is not identified by a byte at offset 0. There is no fixed magic number. Instead the decoder scans for a distinctive delimiter: every encoded block starts with the four characters #@~^. That marker can appear anywhere in the file, and unencoded text may come before or after it, which is how the encoder handles script mixed into markup.
The block has a strict header-and-footer shape around the scrambled payload:
#@~^nnnnnn== ...encoded payload... cccccc==^#~@
The prefix #@~^ is followed by six characters (nnnnnn) that encode the length of the block in a base64-style alphabet, then a literal ==. The encoded VBScript follows. The block closes with six more characters (cccccc) that hold a checksum, another ==, and finally the reversed marker ^#~@. So the outer frame reads #@~^ at the head and ^#~@ at the tail, with length and checksum fields nested just inside each end. A decoder validates the length, reverses the substitution over the payload, and can use the trailing checksum to confirm it recovered the block intact.
The substitution and lookup-table decoding
The transform between #@~^...== and ==^#~@ is a polyalphabetic substitution. Rather than one fixed cipher alphabet, the scheme uses three substitution alphabets and rotates between them position by position: the same plaintext character encodes to different bytes depending on where it sits in the stream. Decoding is a table lookup. A fixed decode table maps each encoded byte back to a candidate plaintext value, and a short “table choice” sequence selects which of the three alphabets applies at each position. A handful of characters are also escaped through combining sequences so that bytes which would otherwise clash with the framing (such as newlines, tabs, and the marker characters) survive encoding.
Two consequences follow from this design. First, the mapping is completely deterministic and carries no secret, so recovering the original source needs no key, only the published tables. Second, because the tables are public and fixed, the reverse transform has been implemented many times. The widely circulated scrdec tool (and its C source, scrdec14.c) decodes both .vbe and .jse files, as do modern vbe-decoder scripts and numerous on-the-fly web decoders. Any of them turns a .vbe back into readable VBScript in a fraction of a second. This is why the correct way to inspect a suspicious .vbe is to decode it and read the recovered .vbs in a text editor, never to run it.
Windows Script Host execution
A .vbe runs through the same host as a plain script: the Windows Script Host. WSH ships in every modern Windows version and exposes two front ends. wscript.exe is the windowed host used when you double-click a script; it shows message boxes and dialogs. cscript.exe is the console host, used from a command prompt when output should go to the terminal:
wscript.exe logon.vbe ' double-click / GUI host
cscript.exe logon.vbe ' console host, e.g. for logging output
When WSH loads the file, the VBScript engine detects the #@~^ marker, decodes the block in memory, and executes the recovered source. From the script’s point of view nothing changed: it has the full VBScript object model available, including WScript.Shell for launching programs and editing the registry, Scripting.FileSystemObject for reading and writing files, and COM automation for Office, WMI, and networking. Encoding does not sandbox or restrict any of this; the decoded script runs with the full privileges of the user who launched it. The same code can also be delivered inside a Windows Script File (.wsf), which lets a single job combine encoded and plain script and mix VBScript with JScript.
Why encoding is not security: attack mechanics
The .vbe format is a textbook example of security-by-obscurity, and it is heavily abused by malware. Understanding the mechanics matters because the danger is concrete, not theoretical.
The execution path is the first problem. On a default Windows install, .vbe is an executable script type: double-clicking it runs it immediately under wscript.exe, with no compile step and no prompt for what the code will do. A user who receives invoice.vbe and opens it expecting a document has already executed arbitrary code. Attackers reinforce this with double extensions such as invoice.pdf.vbe, relying on hidden file extensions so the victim sees only “invoice.pdf”.
The encoding is the second problem, and it cuts against the defender. It gives the author false confidence that the logic is hidden, while providing no real barrier: as shown above, the substitution is keyless and reverses with public tools. What it does buy an attacker is evasion. A scanner that only reads the file as text sees scrambled bytes, and an analyst who opens it in Notepad sees gibberish rather than an obvious call to download a payload. So malware families ship VBScript droppers and downloaders as .vbe to slip past signature-lite antivirus and to hide intent from casual inspection.
The capability is the third problem. Once running, an encoded script can do anything the user can. Common patterns chain the objects above: create MSXML2.XMLHTTP or an ADODB stream to download a second-stage binary, write it to %TEMP% with FileSystemObject, execute it with WScript.Shell.Run, and add a Run registry key or a scheduled task for persistence. None of that requires elevation; it all runs in the user’s own context. For these reasons .vbe sits on the list of dangerous script extensions that many mail systems and endpoint policies block outright, next to .vbs, .js, .jse, .wsf, and .hta. The safe rule is simple: never run a .vbe you did not create or fully trust, and to examine one, decode it and read the source.
Reading and migrating a VBE file
To read a .vbe safely, decode it first with a Script Decoder, then open the recovered .vbs in a text editor such as Notepad++ or Visual Studio Code with VBScript syntax highlighting. The decode step is the same operation WSH performs internally, so nothing is lost. On macOS and Linux there is no Windows Script Host, so those systems can only decode and read a .vbe, never run it.
Because VBScript is being retired, the recommended path for any encoded script you still depend on is to decode it to VBScript and then rewrite the logic in PowerShell (a .ps1 file). There is no one-click converter, but PowerShell covers every VBScript capability — file handling, WMI, COM automation — and is the supported technology going forward. Wrapping a .vbe into a standalone .exe with a script-to-EXE packager is possible but only bundles a runtime stub around the same script; such wrappers are heavily abused by malware and are frequently flagged by antivirus.
Frequently asked questions
What is the difference between a .vbs and a .vbe file?
A .vbs is readable VBScript source; a .vbe is the same script after Microsoft’s Script Encoder obfuscated it. Both run identically under the Windows Script Host, which decodes the .vbe at run time. The encoding is reversible substitution, not encryption, so a .vbe offers no real protection over a .vbs.
How do I decode a .vbe file?
Feed it to a public Script Decoder (such as a scrdec-based or vbe-decoder tool) to recover the original VBScript, then read it in a text editor. The Script Encoder uses fixed, published lookup tables and no key, so decoding is deterministic and takes a fraction of a second. This is the safe way to inspect a suspicious file, because it never executes the code.
How can I recognise a .vbe file without running it?
Open it as text and look for the encoded-block marker: it starts with #@~^ and ends with ^#~@, with the scrambled payload in between. There is no magic number at offset 0 because the encoded block can appear anywhere in the file, which is why the marker, not a byte signature, identifies it.
References
- Microsoft — Script Encoder (screnc.exe) scripting reference (archived)
- Microsoft — Windows Script Host overview
- Microsoft — VBScript deprecation: timelines and next steps
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.