Releases: und3ath/xollvm
Release list
v0.10.0
xollvm — v0.10.0
Built against stock LLVM release/22.x.
Highlights
This release lands MBA extension v3 — memory-free, solver-resistant Mixed Boolean-Arithmetic strengthening for the mba pass, plus preset bundles and a SiMBA resilience harness.
What's new
MBA pass (mba)
- Memory-free input-derived runtime-zero inflation — zeros are lifted from function inputs, no volatile memory scratch (defeats store-forwarding folds).
- SLE pool: nonlinear-lifted runtime zeros drawn from a 260-entry system-of-linear-equations pool (
MBASlePool.inc), resistant to InstCombine canonicalization. - Preset bundles:
light/medium/high/maxfor one-knob strength selection.
Docs
docs/USER.mddocuments the memory-free input-zero and SLE options.- README now points to the
xollvm.github.iodocs site.
Tooling / tests
- SiMBA attack + MBA resilience bench cases in
utils/deobf_bench/(attacks/simba.py, newmba_opsprogram templates). - MBA correctness, fold-check, and SLE generate/verify utilities (
utils/mba_fold_check.py,utils/mba_sle_gen.py,utils/mba_sle_verify.py).
Chore
- Dropped prototype demo/perf scratch;
.gitignoreglobs guard future scratch.
Merged PRs
- #17 —
feat/mba_ext_v3: MBA extension v3 (memory-free zeros, SLE pool, presets, SiMBA harness) - #18 —
chore/drop-demo-scratch: drop prototype scratch, ignore future scratch - #19 —
docs/readme-site-link: point README to docs site
Artifacts
| File | What | OS |
|---|---|---|
xollvm-linux-Release.tar.zst |
clang/opt with obfuscator built in | Linux x86_64 |
xollvm-windows-Release.7z |
clang/opt with obfuscator built in | Windows x64 |
Obfuscator-linux-x64.so |
loadable -fpass-plugin |
Linux x86_64 |
Cross-compilation backends
-DLLVM_TARGETS_TO_BUILD="X86;AArch64;ARM;RISCV" — X86, AArch64, ARM, RISC-V.
Full Changelog: v0.9.2...v0.10.0
v0.9.2
xollvm — v0.9.2
Built against stock LLVM release/22.x.
Fixes
- strenc: materialize constexpr users of encrypted string globals on the PHI predecessor edge. PHI incoming-value uses were being materialized in the PHI's own block, pushing the PHI off the top and producing invalid IR (
PHI nodes not grouped at top of basic block); they are now inserted before the incoming predecessor's terminator, which always dominates the edge use. - strenc: skip encryption for strings whose address is
ptrtoint'd — identity would silently diverge once uses are rewritten to a per-call stack buffer. - strenc: fix stat counters always printing
0in Release builds (STATISTIC→ALWAYS_ENABLED_STATISTIC).
Docs
- DEV.md: reworked against current source — replaced the retired in-tree
PassRegistry.defmodel with the fork-freeregistration/PluginEntry.cpp+ObfPasses.incmechanism; corrected the pipeline ordering table (vcall runs after flattening, not before); replaced stale VM opcode-count and hardening-layers snapshots with pointers toVMPassConfig/VM.md.
Artifacts
| File | What | OS |
|---|---|---|
xollvm-linux-Release.tar.zst |
clang/opt with obfuscator built in | Linux x86_64 |
xollvm-windows-Release.7z |
clang/opt with obfuscator built in | Windows x64 |
Obfuscator-linux-x64.so |
loadable -fpass-plugin |
Linux x86_64 |
Cross-compilation backends
-DLLVM_TARGETS_TO_BUILD="X86;AArch64;ARM;RISCV" — X86, AArch64, ARM, RISC-V.
v0.9.1
xollvm — v0.9.1
Built against stock LLVM release/22.x.
Changelog
- fix:
vmpass crash (SIGSEGV) when obfuscating for a cross-compilation target whosewchar_sizediffers from the host build (e.g. Windows host → Android NDKaarch64-linux-android). The embedded AES-CTR stub (aes_stub.bc, mandatory forvm's bytecode cipher) is compiled once at build time for the host triple; its stalellvm.module.flagsmetadata now gets stripped before linking into the target module, alongside the existing DataLayout/TargetTriple normalization. (b42d0c4)
Artifacts
| File | What | OS |
|---|---|---|
xollvm-linux-Release.tar.zst |
clang/opt with obfuscator built in | Linux x86_64 |
xollvm-windows-Release.7z |
clang/opt with obfuscator built in | Windows x64 |
Obfuscator-linux-x64.so |
loadable -fpass-plugin |
Linux x86_64 |
Cross-compilation backends
-DLLVM_TARGETS_TO_BUILD="X86;AArch64;ARM;RISCV" — X86, AArch64, ARM, RISC-V.
v0.9.0
xollvm — v0.9.0
Built against stock LLVM release/22.x.
Artifacts
| File | What | OS |
|---|---|---|
xollvm-linux-Release.tar.zst |
clang/opt with obfuscator built in | Linux x86_64 |
xollvm-windows-Release.7z |
clang/opt with obfuscator built in | Windows x64 |
Obfuscator-linux-x64.so |
loadable -fpass-plugin |
Linux x86_64 |
Cross-compilation backends
-DLLVM_TARGETS_TO_BUILD="X86;AArch64;ARM;RISCV" — X86, AArch64, ARM, RISC-V.
Changelog
VM super-op fusion (#9)
- Fuse shl+add chains into
OP_SHLADD - Fuse icmp+select into
OP_CMPSEL - Fuse and+icmp-zero bit-tests into
OP_ANDCMPZ - Opcode count 53→56
- Remove
preset=light(#10)
MBA pool expansion (#11)
- Indexed
poolSize/applyByIndexaccess API - 4 new alt identities + correctness/fold-check suites
- Add mul family (mul/mulAlt/mulAlt2) to indexed pool
- Add shl family (const-RHS) to indexed pool
- Strengthen mulAlt2: Neg-mirror → 16-bit split-mul
- Pool now 23 identities across 7 opcodes
VM handler mutation (#13)
- Intra-function handler-variant dispatch
- Full MBA pool + structural mutations for variant diversification
- Static decoy handlers
- Live decoys via opaque-false-guarded branches
preset=maxopts inhandlerVariants=4+handlerDecoys=2; decoy gate now layer-based- Handler-variant cap lifted 4→64,
handlerDecoysknob added
Misc
- gitignore
deobf_bench_work/,run_regression.ps1,docs/design/
v0.9.0-rc1
xollvm — v0.9.0-rc1
Built against stock LLVM release/22.x.
Prerelease. Headline change: the obfuscator now runs inside a normal
clang/clang-clcompile via the default-off-enable-obfuscationflag —
nooptround-trip, so it drops straight into Visual Studio / MSBuild.
What's new (vs v0.8.0)
Added
- In-compiler obfuscation — default-off
-enable-obfuscationflag runs the
obfuscator during a normalclang/clang-cl-ccompile via a PipelineStart
extension point. Nooptround-trip; enables Visual Studio / MSBuild
integration. Off by default → pipeline byte-identical; annotation-gated →
un-annotated code untouched. (#7) - vcall: encrypted, runtime-filled vtable behind the
encTableknob. (#4) - constenc:
wrapMBAoption to wrap encrypted constants in MBA. (#5)
Fixed
- Correctness fixes in the
bcf,flattening, andsplitpasses. (#3) - Corrected
docs/USER.md: the oldclang -mllvm -passes=obfuscationrecipe was
invalid (clang has no-passes); replaced with the-enable-obfuscationflow.
Tooling
- Deobfuscation resilience benchmark (Z3/angr attacks across passes). (#6)
Docs
USER.mdclang/clang-cl + Visual Studio/MSBuild integration guide.- Refreshed VM diagrams and annotation knobs (
obf_annotations.h).
Using it in Visual Studio
- Extract
xollvm-windows-Release.7z, e.g. toC:\xollvm\(soC:\xollvm\bin\clang-cl.exeexists). - Install the LLVM Compiler Toolchain VS extension (once) →
LLVM (clang-cl)toolset. - Project → Properties → General → Platform Toolset = LLVM (clang-cl); LLVM → LLVM Toolchain Directory =
C:\xollvm. - C/C++ → Command Line → Additional Options:
/clang:-mllvm /clang:-enable-obfuscation /clang:-mllvm /clang:-obf-seed=1 /clang:-mllvm /clang:-obf-deterministic - Annotate functions:
__attribute__((annotate("obf: mba, bcf, flattening"))). - Build (Release
/O2fine — obfuscation survives the optimizer).
Artifacts
| File | What | OS |
|---|---|---|
xollvm-linux-Release.tar.zst |
clang/opt with obfuscator built in | Linux x86_64 |
xollvm-windows-Release.7z |
clang/opt with obfuscator built in | Windows x64 |
Obfuscator-linux-x64.so |
loadable -fpass-plugin |
Linux x86_64 |
Cross-compilation backends
-DLLVM_TARGETS_TO_BUILD="X86;AArch64;ARM;RISCV" — X86, AArch64, ARM, RISC-V.
v0.8.0
xollvm — v0.8.0
Built against stock LLVM release/22.x.
A large code-virtualisation (vm) hardening release: data-at-rest crypto, nested
virtualisation, decentralised dispatch, ISA diversification, key-schedule anti-debug, and the
engine pool — per-function, metamorphic interpreter engines. Every new feature is
behind its own knob, defaults OFF, and is byte-identical to v0.7.0 when off. The new
preset=max bundle opts the whole set in. Full vm runtime suite green (125/125).
Highlights
- Engine pool Spread virtualised functions across many structurally-distinct
interpreter engines instead of one shared engine — so lifting one function's engine gives no
shortcut for a function that runs a different one. - Metamorphic engines. Each engine's handler bodies are MBA-diversified per clone: distinct
code, not just distinct names. - Bytecode at rest stays ciphertext via lazy per-fetch AES decryption, with constants moved
inside the encrypted stream. - No single dispatch fingerprint — dispatch can be threaded into every handler and each
opcode byte keyed per instruction pointer. - Cross-build diversity — per-build operand-encoding randomisation means two builds of the
same source share no static handler signature.
What's new (vm pass)
Engine pool — per-function metamorphic virtualisation
enginePoolSize=N— build N structurally-distinct engines per module; each function is
assigned to one by a name+seed hash (__vm_engine,__vm_engine.p1, …).perFnEngine=1— give a function its own dedicated engine (annotation-selective: set it on the
critical functions only, or everywhere for a full per-function build).metamorphicEngines=1— rewrite each engine's integer handler arithmetic with a
per-clone-seeded MBA identity, so pool engines have structurally distinct bodies even at
handlerVariants=1, hardened=0.- Pooling extends to the nested layer (
__vm_engine.nest.pN) while the shared__vm_h_*helpers
are virtualised exactly once.
Data-at-rest crypto
lazyDecrypt=1— decrypt bytecode per fetch from a recomputed AES-CTR keystream block instead
of decrypting the whole buffer at load; the runtime bytecode never exists as contiguous
plaintext (requiresencBytecode).constInStream=1— carry int/i64/fp constants inside the encrypted bytecode
(OP_LOADI/OP_LOADI64/OP_LOADI_Fprologue) instead of plaintext wrapper stores (requires
encBytecode).
Nested virtualisation
nestedVM=1— the compute step of BINOP/BINOP64/ICMP/ICMP64/FCMP/CAST/BINOP_F opcodes is
outlined into__vm_h_*helpers that are themselves virtualised against a second engine
(__vm_engine.nest), giving depth-2 interpretation with no possible recursion.nestedVMOpcodes=Ncaps how many opcodes nest.
Dispatch
threadedDispatch=1— inline fetch/decode/indirectbrinto every handler; removes the single
centralvm.dispatch/vm.fetchfingerprint.keyedDispatch=1— XOR each opcode byte with a per-IP compile-time key; the same physical byte
decodes to different opcodes at different IPs.
ISA
superOps=1— fusemul+addchains into a singleOP_MULADDopcode (new opcode 0x34).randISA=1— per-build, module-uniform permutation of five operand-field encodings (BinSubop,
ICmp predicates, CastKind, FBinSubop, FCmp predicates), so cross-sample signatures don't match.- New opcode
OP_LOADI64(0x33);OP_COUNTgrows to0x35(53 opcodes).
Anti-debug
bindAntiDebug=1— foldIsDebuggerPresent/CheckRemoteDebuggerPresent/
NtQueryInformationProcessdetection into the AES round-key mask, so under a debugger the
bytecode decrypts to garbage and crashes before the first opcode (requireshardened+antiDebug).- Handler-level RDTSC timing traps are now debounced over consecutive slow executions and the
defaultadHandlerThresholdraised to 5000, eliminating scheduling-noise false positives.
Configuration
preset=<light|medium|high|max>— canned knob bundles applied before explicit knobs.
max= full stack + nested VM + super-operators + rolling register key + bind-anti-debug +
ISA randomisation + per-function metamorphic engines.
Internal / breaking
- The legacy LCG bytecode-encryption path and the
useAESknob were removed — AES-128-CTR is
now the only bytecode cipher (useAES=…in an annotation is silently ignored). VMPass_Impl.cppsplit by concern intoVMPass_{Handlers,Wrapper,Dispatch,Nested,Crypto,AntiDebug,Harden}.cpp.docs/VM.mdfully updated for all of the above.
Artifacts
| File | What | OS |
|---|---|---|
xollvm-linux-Release.tar.zst |
clang/opt with obfuscator built in | Linux x86_64 |
xollvm-windows-Release.7z |
clang/opt with obfuscator built in | Windows x64 |
Obfuscator-linux-x64.so |
loadable -fpass-plugin |
Linux x86_64 |
Cross-compilation backends
-DLLVM_TARGETS_TO_BUILD="X86;AArch64;ARM;RISCV" — X86, AArch64, ARM, RISC-V.
Full diff: v0.7.0...v0.8.0
v0.7.0
xollvm — v0.7.0
Platforms
| Artifact | OS |
|---|---|
xollvm-linux-Release.tar.zst |
Linux x86_64 (ubuntu-24.04) |
xollvm-windows-Release.7z |
Windows x64 (MSVC 2022) |
Obfuscator-linux-x64.so |
Linux x86_64 — loadable -fpass-plugin |
Cross-compilation targets
Built with -DLLVM_TARGETS_TO_BUILD="X86;AArch64;ARM;RISCV" — the following backends are included:
- X86 — x86 / x86_64
- AArch64 — ARM 64-bit (Apple Silicon, Linux ARM64)
- ARM — ARM 32-bit
- RISCV — RISC-V 32/64-bit
Highlights
New module-only obfuscation pass, fmerge, collapses several annotated functions into a
single super-function whose hidden selector parameter picks which original body runs. This
is not LLVM's MergeFunctions (identical-function folding for size) — fmerge deliberately
merges dissimilar functions to destroy call-graph boundaries, running before the function
pipeline so flattening / bcf / mba / vm all operate on the merged result. Opt-in,
annotation-driven, consistent with every other xollvm pass.
Added
fmergefunction-merging pass — per-function opt-in via
__attribute__((annotate("obf: fmerge(group=...)"))); functions sharing agroup=label
merge into one super-function, all direct call sites rewritten to the merged callee with
the appropriate selector.- Selector laundering (
launderSel=1) — call-site selectors are read from a mutable
per-group global (@__obf_fmsel_<label>) via a volatile load instead of an inline constant,
so constant-propagation / symbolic devirtualization can't recover which behavior a call
runs. Cross-group merged→merged calls already rewrite correctly.
Changed
docs/obf_annotations.hcheat-sheet extended withconstencandfmergeannotation
examples; corrected the sample path referenced fromREADME.md.
Tests
- New
fmergecase/gate pairs (utils/cases/fmerge.py,utils/gates/fmerge.py) plus
three template programs (basic,combo,thunk) exercising group merging and selector
rewriting.
Full diff: e3ced21…7457f2d (main) — 19 files, +1899 / −11.
v0.6.0
xollvm — v0.6.0
Built against stock LLVM release/22.x.
Artifacts
| File | What | OS |
|---|---|---|
xollvm-linux-Release.tar.zst |
clang/opt with obfuscator built in | Linux x86_64 |
xollvm-windows-Release.7z |
clang/opt with obfuscator built in | Windows x64 |
Obfuscator-linux-x64.so |
loadable -fpass-plugin |
Linux x86_64 |
Cross-compilation backends
-DLLVM_TARGETS_TO_BUILD="X86;AArch64;ARM;RISCV" — X86, AArch64, ARM, RISC-V.