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+flatteningis powerful but costs compile time and size — cap it with the IR budget knobs. vmis the heaviest option — it replaces the whole function. Use it only for the most sensitive code, and prefermba+flatteningwhere moderate obfuscation suffices.- Don't combine
vmandflatteningon 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
-O2or a solver. Run the resilience bench before claiming a hardening win.