Nebula.NET
Resisting automated deobfuscation
How Nebula.NET stands up to de4dot and other automated deobfuscators — control-flow that can’t be constant-folded, string encryption that can’t be auto-stripped, proxy-hidden call graphs, and code virtualization.
The first thing a knowledgeable attacker does with a protected assembly is run an automated deobfuscator — most commonly de4dot — to strip the protection in one click before reading anything by hand. An obfuscator that only survives manual inspection but folds to de4dot file.dll isn’t really protecting you.
Nebula is built to defeat the automated pass. Each layer targets a specific technique these tools rely on.
Control flow that can’t be constant-folded
Automated control-flow deobfuscators undo a flattened method by constant-propagating the dispatcher’s state variable — statically computing which block runs next and rebuilding the original structure. Nebula’s flattening masks the dispatch state with a non-foldable, runtime-computed key (switch (state ^ key), where key is produced by a loop the tool can’t evaluate). The stored state values aren’t the case labels, so there’s nothing constant to fold — the state graph can’t be reconstructed. The aggressive (Enterprise) tier adds non-prunable decoy states that can’t be proven dead and stripped.
String encryption that can’t be auto-stripped
The classic de4dot win is automatic string decryption: it recognises the canonical string Decrypt(string) routine, invokes it, and replaces every call with the plaintext. Nebula’s decryptor takes a per-call-site key (Decrypt(cipher, salt)), with a different salt at every site — so it isn’t the signature de4dot auto-detects, and no single call reproduces a string without its site’s salt. The automatic pass comes back empty.
A hidden call graph
Reference (proxy-call) obfuscation routes calls through injected, unbranded proxy methods, so a decompiler and automated call-graph analysis can’t see which external or BCL method a site actually invokes. de4dot’s generic proxy-call fixer only reverses the specific schemes of obfuscators it recognises; Nebula’s isn’t one of them.
No IL at all
For your most sensitive methods, code virtualization (Enterprise) removes the IL entirely — the logic becomes custom VM bytecode. There is nothing for a deobfuscator to clean up, because there’s no recognisable IL to begin with; reversing it means reverse-engineering the VM.
The result, by edition
| Layer | Free | Pro | Enterprise |
|---|---|---|---|
| Non-foldable control-flow dispatch | capped (2 methods) | ✅ | ✅ |
| Per-call-site string encryption | capped (2 strings) | ✅ unlimited | ✅ unlimited |
| Proxy-call (call-graph) obfuscation | — | ✅ | ✅ |
| Aggressive tier (decoy states) | — | — | ✅ |
| Code virtualization | — | — | ✅ |
Pro output already resists de4dot’s automatic control-flow deobfuscation and string decryption and hides the call graph. Enterprise adds the aggressive tier and virtualization, so the methods that matter most have no recoverable IL.
Verify it yourself
This isn’t a marketing claim you have to take on faith:
- Obfuscate a build with Nebula.
- Run it through de4dot (or any deobfuscator).
- Open the result in Glass.NET (our free decompiler) or ILSpy.
You’ll see the control-flow still flattened, strings still encrypted, and virtualized methods still just a VM call. No client-side protection is ever unbreakable given unlimited effort — but the goal is to make automated stripping fail and manual reversing expensive, and that’s exactly what these layers do.