Star 历史趋势
数据来源: GitHub API · 生成自 Stargazers.cn
README.md
xollvm logo

xollvm

🛡️ Annotation-driven LLVM 22 & 23 obfuscator · new pass manager · zero LLVM source edits

LLVM License Platforms Passes Integration Docs

📖 Read the full documentation → xollvm.github.io

🚀 Getting Started · 🧩 Passes · ⚙️ Virtualization · 🧠 Development · ✅ Testing

Docs source lives in docs/ and is published to the site via MkDocs.


An annotation-driven LLVM obfuscation framework for the new pass manager (NPM). Configuration comes from source-level annotations (llvm.global.annotations) and is resolved once per module into a cached, deterministic configuration map.

xollvm plugs into stock LLVM with no LLVM source edits — it is compiled in as an LLVM static extension (LLVM_EXTERNAL_PROJECTS), so the same code ships three ways:

  • a clang/opt toolchain with the obfuscator built in (Linux and Windows),
  • a loadable pass plugin Obfuscator.so for -fpass-plugin (Linux/macOS).

Disclaimer / Legal: Intended for legitimate software-protection use cases (IP protection, anti-tamper research, academic evaluation, CTFs with permission). Do not use it for malware, unauthorized access, or to violate laws / terms of service. You are responsible for compliance with all applicable laws.

[!IMPORTANT] Obfuscation is not a security boundary. Treat it as one layer in a broader defensive strategy (hardening, anti-tamper, secure update, key management, …).


What you get

  • Module entry pass: -passes=obfuscation — module-only work (fmerge, strenc) then an ordered per-function pipeline.
  • Annotation-driven config with canonical pass IDs + aliases.
  • Deterministic seeding (module → function → pass) with an optional seed manifest.
  • Safety rails: instruction/block/loop-depth gating + IR-growth budgeting.
  • Diagnostics: -passes=obf-dump-config, -passes=obf-metrics.
  • Reports: JSON obfuscation map + per-pass CFG snapshots; HTML viewer (Python).
  • Runtime test suite (Python) under utils/.

Passes (high level)

Function pipeline (order enforced by the driver via topological sort):

PassIDCategoryDescription
Constant encryptionconstencExpressionEncrypts scalar int/FP constant operands into runtime-opaque materializations.
Mixed Boolean/ArithmeticmbaExpressionRewrites integer expressions as MBA equivalents.
Instruction substitutionsubstitutionExpressionReplaces instructions with equivalent idioms.
Virtual callvcallCall hardeningVirtualises direct calls via synthetic vtables.
Basic block splitsplitCFGSplits basic blocks to increase graph complexity.
Semantic diffusionsdiffExpression / CFGVolatile-slot masking that resists local simplification.
Bogus control flowbcfCFGAdds opaque predicates and fake edges.
CFG flatteningflatteningCFGReplaces structured control flow with a dispatcher.
Anti-optimization shieldshieldPost-hardeningVolatile barriers and opaque identities.
Anti-decompileradecPost-hardeningIndirectbr trampolines, asm junk, pointer aliasing.
Code virtualisationvmVirtualisationCompiles the function body into a private bytecode stream.

Module-only:

PassIDDescription
Function mergingfmergeCollapses annotated functions sharing a group= label into one selector-dispatched super-function; runs first, so the merged bodies feed the function pipeline.
String encryptionstrencEncrypts string literals; enabled when any annotated function includes strenc(...).

[!NOTE] vm conflicts with flattening (both restructure the CFG). Use one or the other per function.

[!NOTE] fmerge is opt-in per function and runs before everything else — the resulting super-functions are then obfuscated by the function pipeline. See FMERGE.md.


How it works

Annotations drive everything. A module analysis parses llvm.global.annotations once into a cached Function → Config map; the module entry pass then runs module-only fmerge and strenc and a deterministic, budget-gated per-function pipeline.

xollvm end-to-end pipeline: source annotations to obfuscated IR


Quick start

Option 1 — Download a prebuilt release

Grab from Releases:

FileWhatOS
xollvm-linux-Release.tar.zstclang/opt with the obfuscator built inLinux x86_64
xollvm-windows-Release.7zclang/opt with the obfuscator built inWindows x64
Obfuscator-linux-x64.soloadable -fpass-pluginLinux x86_64

Backends included: X86;AArch64;ARM;RISCV.

Option 2 — Build the toolchain from stock LLVM (static extension)

No fork, no patch — point LLVM's build at this repo. xollvm builds against both LLVM 22 and LLVM 23 (release/22.x or release/23.x) from the same sources — the version is detected at compile time, no flags to flip:

git clone --depth 1 --branch release/22.x https://github.com/llvm/llvm-project  # or release/23.x
git clone https://github.com/und3ath/xollvm

cmake -S llvm-project/llvm -B build -G Ninja \
  -DCMAKE_BUILD_TYPE=Release \
  -DLLVM_ENABLE_PROJECTS="llvm;clang" \
  -DLLVM_ENABLE_RTTI=ON -DLLVM_ENABLE_EH=ON \
  -DLLVM_TARGETS_TO_BUILD="X86;AArch64;ARM;RISCV" \
  -DLLVM_EXTERNAL_PROJECTS=Obfuscator \
  -DLLVM_EXTERNAL_OBFUSCATOR_SOURCE_DIR="$PWD/xollvm" \
  -DLLVM_OBFUSCATOR_LINK_INTO_TOOLS=ON

cmake --build build --target install

[!NOTE] Under LINK_INTO_TOOLS the AES stub is compiled by an external clang (the in-tree clang can't be used — it would form a build cycle). Make sure a clang is on PATH.

Option 3 — Build the loadable plugin (.so)

# needs an installed LLVM 22 or 23 (e.g. apt llvm-22-dev / llvm-23-dev)
cmake -S xollvm -B build -G Ninja -DLLVM_DIR=/usr/lib/llvm-22/lib/cmake/llvm  # or .../llvm-23/...
ninja -C build Obfuscator          # -> build/Obfuscator.so

Annotate functions

// Light: expression-level only
__attribute__((annotate("obf: mba(prob=70,maxDepth=3), substitution(loop=2)")))
int light(int x) { return x * 3 + 7; }

// Heavy: structural + post-hardening
__attribute__((annotate("obf: mba(prob=70), bcf(prob=30), flattening(minBlocks=3), shield, adec")))
int heavy(int x, int y) { return x ^ y; }

// Maximum: VM virtualisation (replaces the entire function body)
__attribute__((annotate("obf: vm(hardened=1,useAES=1,regEncrypt=1)")))
int secret(int key, int data) { return key ^ (data + 0xDEAD); }

// Function merging: fold same-group functions into one super-function
__attribute__((annotate("obf: fmerge(group=core,thunk=1,launder=1)")))
int parse_hdr(const char *p, int n) { /* ... */ return n; }
__attribute__((annotate("obf: fmerge(group=core,thunk=1,launder=1)")))
long crc_step(long acc, int b)      { /* ... */ return acc; }

C++: [[clang::annotate("obf: mba(prob=60), bcf(prob=25)")]]. See obf_annotations.h for the full cheat-sheet.


Run it

Prebuilt / static-extension toolchain (obfuscator is built in):

clang -S -emit-llvm -O0 test.c -o test.ll
opt   -passes=obfuscation test.ll -S -o test.obf.ll -obf-seed=1 -obf-deterministic
clang test.obf.ll -O2 -o test.obf

Loadable plugin (.so):

opt -load-pass-plugin=./Obfuscator-linux-x64.so -passes=obfuscation test.ll -S -o test.obf.ll
# or with clang: clang -fpass-plugin=./Obfuscator-linux-x64.so ...

Diagnostics: -passes=obf-dump-config (resolved config), -passes=obf-metrics (JSONL).


Reproducibility

Seeds cascade base → module → function → pass:

Hierarchical deterministic seed derivation

  • -obf-seed=<N> pins the base seed.
  • -obf-deterministic derives the module seed from a stable hash of the module id (when seed is 0).
  • -obf-seed-manifest=seeds.json dumps the full manifest.

Documentation

DocumentPurpose
BUILD.mdFull compilation guide — static-extension toolchain (Linux/Windows), .so plugin, prerequisites, troubleshooting.
USER.mdAnnotation grammar, pass reference, global options, reports, troubleshooting.
DEV.mdArchitecture: registration, annotation cache, pipeline ordering, reporting, adding passes.
VM.mdCode-virtualisation reference — ISA, bytecode format, hardening layers.
FMERGE.mdFunction-merging reference — grouping, memory ABI, dispatch (switch/indirectbr), thunks, selector laundering.
TESTS.mdRuntime test harness, categories, debug workflows.

License

Apache-2.0 WITH LLVM-exception (same as LLVM). See LICENSE.

关于 About

Modern LLVM Obfuscator

语言 Languages

C++65.0%
Python30.1%
Go Template3.4%
C1.0%
CMake0.5%

提交活跃度 Commit Activity

代码提交热力图
过去 52 周的开发活跃度
159
Total Commits
峰值: 39次/周
Less
More

核心贡献者 Contributors