Features

A complete protection pipeline

Every Dhaedalida build combines multiple, independently generated layers of defense. Here is what runs under the hood.

Code Virtualization

Your logic becomes a virtual machine that only exists in your build

Dhaedalida converts each selected function into a self-contained virtual machine embedded in a new section of the executable. The original instructions no longer exist in the file to be disassembled. An analyst finds a custom VM executing the logic indirectly, not readable code.

  • Function-level protection: shield license checks, crypto and core IP while the rest of the app stays fast
  • Executables and DLLs: a virtualized DLL derives its own base at load time, so exports, relocations and DllMain keep working
  • Entry point included: pass your entry point as a protection target and it runs under VM protection from the very first instruction
  • No two builds alike: every run produces byte-different output with no shared static signature
  • Custom protection section name so the protected code blends into the app
  • Zero behavioral change: the protected function computes the same results as before
vm_dispatch
; generated VM - layout differs every build
vm_enter  ctx, 0x4A19
  handler_0x3F   ; push imm
  handler_0x08   ; xor rot
  handler_0xC1   ; branch pred
  handler_0x77   ; native bridge
vm_leave  ctx
String Encryption

No plaintext secrets left in your binary

Sensitive text is often the easiest clue an attacker uses to locate protection. With --encrypt-strings, the string literals used by protected functions are stored encrypted at rest and decrypted only for a moment, inside the virtual machine, at the instant they are used.

  • A strings-style scan of the shipped file reveals no plaintext messages or secrets
  • Each string gets its own key: no single point to unravel
  • Supports both ANSI and wide (UTF-16) text
  • Strings shared with unprotected code are left intact, so nothing breaks
strings yourapp.protected.exe
$ strings yourapp.protected.exe | grep -i license
(no matches)

; at runtime, inside the VM only:
vm_decrypt  str_0x2c, key_0x2c   ; one use
vm_wipe     str_0x2c             ; then gone
Obfuscation

Layered hardening, out of the box

Every virtualized function is automatically strengthened with multiple layers of obfuscation that resist both static and dynamic analysis. These protections are on by default, with adjustable complexity.

  • Encrypted constants: no meaningful values sit in the protected code as plaintext
  • Anti-disassembly hardening that defeats linear-sweep disassemblers
  • Randomized internal structure, shuffled per build, so it isn't a stable fingerprint
  • Decoy operations and opaque predicates that automated analysis cannot simplify away
  • Non-linear control flow: logic scattered and chained so its structure is hard to reconstruct
  • Anti-single-step protection that resists being walked one instruction at a time
control_flow
; non-linear dispatch
state = 0x11
loop:
  switch (state)
    0x11 -> ... ; state = 0x9C
    0x9C -> ... ; state = 0x02
    0x02 -> ... ; state = 0xFF
  goto loop
Application Packer

Wrap the whole program in a self-unpacking, encrypted shell

Beyond per-function virtualization, --packer compresses and encrypts the entire application behind a self-unpacking loader. On disk the shipped file contains no readable code or data; it restores itself in memory at launch and then runs normally.

  • Protects the whole program, not just the virtualized functions
  • Smaller shipped file thanks to compression
  • Defeats casual static inspection: an editor or disassembler shows only the protected shell
  • Use it together with virtualization for defense in depth, or on its own (pack-only)
on-disk layout
; yourapp.protected.exe
[ self-unpacking loader ]
[ compressed + encrypted image ]   ; no readable code or data

; at launch
loader -> decompress + decrypt in memory -> run
Defense in Depth

The protection protects itself

Dhaedalida protects its own unpacking loader with the same virtualization engine it applies to your code, so there is no readable version of the protection mechanism for an attacker to study.

  • The loader is virtualized with the same per-build VM as your functions
self_protect
; the loader itself is virtualized
vm_enter  loader_ctx
  unpack_image     ; in memory only
  verify_integrity
vm_leave  loader_ctx
; no readable loader on disk to study
Developer Workflow

Fits the way you already build and ship

Protect interactively in the Dhaedalida desktop app while you tune settings, then automate the exact same profile in your build pipeline with the command-line engine. Mark functions once in source with the marker SDK, detected with or without a PDB.

  • Desktop app: open your EXE or DLL → review the function list → tick protections → Protect
  • Marker SDK: bracket functions with VMStart() / VMEnd(); bindings for C, C++, Rust, Go, Delphi and more, harmless no-ops in a normal build
  • Marked functions detected with or without debug symbols (a PDB), even in a stripped release build
  • Opt-in --strip scrubs debug info from the shipped file (PE debug directory, embedded PDB path, symbol tables and debug sections) so no build paths or symbols leak
  • The CLI takes protection targets from a list file: hundreds of functions in one CI run
ci-pipeline.yml
# protect step in CI
- run: dhaedalida-cli bin/app.exe \
     --out dist/app.protected.exe \
     --addr-file protect.list \
     --encrypt-strings --strip \
     --packer --anti-debug --anti-tamper --protect-imports
Packer protection suite

Composable tamper-resistance layers

Each layer defends a specific avenue of attack. Compose exactly the profile you want: enable the packer with --packer and add layers as flags. The packer suite ships in the Pro edition.

ProtectionFlagWhat it doesDefault
Import protection--protect-importsHides the app's Windows API referencesSelectable
Debugger resistance--anti-debugDeclines to run under a debuggerSelectable
Analysis-VM resistance--anti-vmStops running inside a VM (VMware, Hyper-V, VirtualBox...)Selectable
Monitoring resistance--anti-monitorDeclines to run under system-monitoring toolsSelectable
Integrity / anti-tamper--anti-tamperRefuses to run if the file has been patchedSelectable
Containment-tool resistance--anti-sandboxDetects analysis sandboxes and declines to runSelectable
Anti-dump--anti-dumpBlocks reconstruction of a usable copy from process memoryOff (advanced, opt-in)
Direct system calls--syscallsHardens the loader's own integrity against user-space toolsSelectable
FAQ

Product questions

Which platforms does Dhaedalida support?
Dhaedalida protects Windows 32-bit and 64-bit executables and DLLs (PE32 and PE32+ .exe and .dll). A virtualized or packed DLL derives its own base at load time, so exports, relocations and DllMain keep working. The marker SDK ships bindings for C (MSVC and GCC/Clang), C++, Rust, Go, Delphi/Object Pascal, D, Zig, Nim and assembly. Any native x86/x64 language works; .NET and other managed code are out of scope.
Does protection change how my application behaves?
No. The protected build is behaviorally identical to the original: the selected functions simply run inside the virtual machine and compute the same results.
Do I have to change my source code?
Only optionally. Add the marker SDK (bindings ship for C, C++, Rust, Go, Delphi/Pascal, D, Zig, Nim and assembly) and bracket sensitive functions with VMStart() / VMEnd(). Marked functions are detected with or without a PDB, and the markers are harmless no-ops in a normal build. Additionally, it's possible to protect a specific function using only its address with the CLI.
Can I protect an app without virtualizing any function?
Yes. The packer can protect a whole application on its own (pack-only), or be combined with virtualization for defense in depth.
Is the protected output reproducible?
By default every run is byte-different, so builds share no static signature.
How should Dhaedalida be used?
Dhaedalida is a legitimate software-protection product for software authors and vendors to protect their own applications, safeguarding intellectual property, enforcing licensing and preventing tampering.
My application is getting flagged by lots of antivirus products
Software protectors rely on techniques that malware crypters also use (encrypted sections, dynamic API resolution and code obfuscation, among others), so some antivirus engines may wrongly flag a protected application as malicious. We recommend code-signing every application with a certificate after protecting it, which tends to reduce false positives. Most antivirus vendors also offer a channel to report false positives so their detection improves.
Can I digitally sign my protected files?
Yes, code signing is fully supported. The only requirement is the order: sign your files after protecting them, not before. A digital signature embeds a cryptographic hash of the file, and protection necessarily rewrites the file (adding new sections among other changes), so a signature applied before protection would no longer match and become invalid. Protect first, sign last: that way your signature covers exactly the bytes your users receive.

See it on your own binary

The free demo puts real functions under VM protection: protect a build and inspect the output yourself. The full pipeline ships in the Basic and Pro editions.

Download Free Demo