Skip to content

Choosing passes

Don't cargo-cult a bundle. Pick passes against a threat model — who is attacking, with what tools — then verify the choice with the resilience bench.

Start small, scale up

Verify correctness at every step. Begin with one or two passes, confirm the program still behaves, then add more. Fix -obf-seed during development so any issue is reproducible.

Map attacker → defence

Attacker capability Weak against it Reach for
Human reading a decompiler (Hex-Rays, Ghidra) plain code mba, bcf, flattening, adec, vcall
Linear disassembly / function recovery normal prologue/flow adec (indirectbr, asm junk, stack pollution)
The optimizer undoing obfuscation (-O2) naive MBA/predicates shield, sdiff, mba(preset=high) (memory-free zeros)
SMT / symbolic execution proving predicates simple opaque predicates mba(preset=high/max), layered bcf, vm
Linear-MBA simplifiers linear MBA mba SLE / input-zero modes (sle, inputZero)
grep for strings / constants plaintext literals strenc, constenc
Reading the callee off a call direct calls vcall
Automated devirtualization (lifter + -O3) lightly-hardened vm vm(preset=max) — see resistance
Signature/pattern matching across builds fixed IR names/constants -adec-prefix random, -adec-randomize-consts, randISA, per-build seed

Tier the effort

Not every function deserves the same treatment. Virtualisation costs 5–20× runtime — spend it where it matters.

flowchart TD
    A{How sensitive?} -->|hot path, low value| L["light: mba + substitution + split"]
    A -->|moderate| M["medium: + vcall + bcf"]
    A -->|structural secret| H["heavy: + flattening + shield + adec"]
    A -->|crown jewels| V["vm(preset=max), pre-obfuscated"]

Concrete bundles for each tier are on the Presets page.

Pitfalls

  • CFG transforms explode IR. bcf + flattening is powerful but costs compile time and size — cap it with the IR budget knobs.
  • vm is the heaviest option — it replaces the whole function. Use it only for the most sensitive code, and prefer mba + flattening where moderate obfuscation suffices.
  • Don't combine vm and flattening on one function — they conflict.
  • Budgets throttle silently. Many "skipped due to budget" report entries mean you hit the ceiling — lower probabilities or raise the budget.
  • Test resistance, not just correctness. A bundle that passes the runtime suite can still fold under -O2 or a solver. Run the resilience bench before claiming a hardening win.