MBA — mba¶
Mixed Boolean/Arithmetic obfuscation for integer expressions.
mba rewrites integer add/sub/and/or/xor and similar instructions as semantically
equivalent MBA expressions built from linear zero-sum terms and optional nonlinear components. The
value is unchanged; the algebraic form that computes it is deeply tangled.
Presets (start here)¶
preset bundles the knobs into one tier; any explicit key overrides it.
| Preset | What it sets | Cost | Resists |
|---|---|---|---|
light |
basic rewriting, no inflation | lowest | weak |
medium |
noise-slot inflation (nonlinear + layered) — historical default | medium | SMT (fragile under -O2) |
high |
memory-free SLE zeros replacing the noise slot — recommended | ~medium | SMT + linear-MBA, survives -O2 |
max |
noise-slot inflation + SLE + input-derived zeros stacked | highest | SMT + linear-MBA, survives -O2 |
__attribute__((annotate("obf: mba(preset=high)"))) // recommended
__attribute__((annotate("obf: mba(preset=max, prob=60)"))) // max, override prob
Options¶
| Key | Default | Range | Meaning |
|---|---|---|---|
preset |
— | light|medium|high|max | Knob bundle applied before explicit keys. |
prob |
40 | 0–100 | Probability (%) to transform a candidate site. |
maxDepth |
3 | 1–10 | Maximum recursive depth for MBA expansion. |
maxSites |
120 | 1–5000 | Cap on transformed sites per function. |
linearTermsMin |
6 | 1–64 | Minimum linear "zero-sum" terms to inject. |
linearTermsMax |
10 | 1–96 | Maximum linear terms (must be ≥ linearTermsMin). |
enableNonLinear |
1 | 0/1 | Enable nonlinear zero-addends (mul/urem based). |
nonLinearWeight / nonLinearProb |
20 | 0–100 | Weight/probability for nonlinear components per site. |
enableLayered |
1 | 0/1 | Enable layered MBA windowing. |
layeredWindow |
48 | 0–256 | Sliding window size for layered MBA. |
layeredBudget |
1 | 0–32 | Max layered expansions per transformed site. |
inputZero |
0 | 0/1 | Inject memory-free, input-derived nonlinear runtime zeros. |
inputZeroReplace |
0 | 0/1 | With inputZero, drop the noise-slot inflation and use input-derived zeros only. |
inputZeroCount |
1 | 1–8 | Input-derived zero forms emitted per site. |
inputZeroWeight |
40 | 0–100 | Probability (%) to inject input-derived zeros per site. |
sle |
0 | 0/1 | Inject SLE-pool nonlinear runtime zeros (per-form structural diversity). |
sleReplace |
0 | 0/1 | With sle, drop the noise-slot inflation and use SLE zeros only. |
sleCount |
1 | 1–8 | SLE pool forms emitted per site. |
sleWeight |
40 | 0–100 | Probability (%) to inject SLE zeros per site. |
Example¶
__attribute__((annotate("obf: mba(prob=70,maxDepth=3,maxSites=80)")))
int mix(int a, int b) { return a ^ (b + 3); }
Memory-free hardening (recommended)¶
By default, MBA inflation leans on a per-function volatile noise slot. That slot's zero folds
away under an analyst's own -O2 (intra-block store-forwarding), and the plain linear terms fall to
SMT and linear-MBA simplifiers. Two opt-in modes replace it with memory-free, nonlinear runtime
zeros that survive -O2 and resist both a general SMT solver and a dedicated linear-MBA simplifier:
inputZero— a small fixed set of input-derived, nonlinear-lifted zeros.sle— a large, swappable pool of synthesized forms, adding per-form structural diversity.
Recommended (strongest per cost):
Raise sleCount / sleWeight, or combine inputZero and sle, for more layering at higher
runtime cost.
Regenerating the SLE pool without rebuilding
The pool loads at runtime from the file named by $XOLLVM_SLE_POOL, falling back to a
compiled-in default. Regenerate and point at it — no LLVM or obfuscator rebuild required:
python utils/mba_sle_gen.py --n 256 --out my_pool.txt # mints + vets a fresh pool
export XOLLVM_SLE_POOL=$PWD/my_pool.txt # next opt/clang run uses it
utils/mba_sle_verify.py re-checks that a pool file is all exact runtime zeros.
Z3-strong ≠ linear-MBA-strong
Resisting a general SMT solver and resisting a dedicated linear-MBA simplifier are different
properties. The high/max presets and the SLE pool are tuned against both — test with both
if you change the knobs. See Resilience benchmarks.