llvm-obfus is an out-of-tree LLVM pass plugin for function-selective obfuscation and virtualization.
Configure it with YAML or source annotations. The main entry point is obf-safe-pipeline.
Build · Usage · Configuration · Documentation · Security
- VM bytecode with encoded dispatch, registered caller tokens, and instruction/successor integrity checks.
- MBA, instruction substitution, CFG flattening, outlining, and seeded indirect dispatch.
- String and constant encoding, with optional authenticated runtime decoding.
- Code-as-data self-checksum with post-link binding.
- Release marker cleanup and configurable symbol-isolation checks.
Levels control pass eligibility. Input shape and configuration determine which transforms apply.
| Level | Purpose |
|---|---|
none |
Requests no transforms, subject to enforced security floors |
light |
Permits string encoding, constant encoding, and block splitting |
strong |
Permits native arithmetic and control-flow transforms |
vm |
Permits VM execution and selected supporting transforms |
strong_vm |
Adds VM implementation hardening and enforces admission for VM-eligible functions |
Profiles (fast, standard, guarded, fortress, lab) set budgets and defaults.
See the configuration reference for the full pass matrix and selection rules.
Linux and Windows x86-64. LLVM 21 minimum, with matching tools and plugin hosts.
| Input | Workflow |
|---|---|
| C / C++ | obf-clang / obf-clang++, or direct Clang plugin loading |
| LLVM bitcode | obf-bc, followed by compilation and runtime linkage |
| Rust / Cargo | obf-rustc with a compatible nightly or development toolchain |
| Zig | LLVM bitcode workflow with a compatible toolchain |
| TinyGo | obf-tinygo on Linux |
Windows plugins require compatible hosts that export LLVM symbols.
Clang uses obf_clang_plugin.dll. opt uses obf_plugin.dll.
Requires CMake 3.24+, a C++23 compiler, LLVM development files and tools, Python 3.10+, lit, and Ninja.
cmake -S . -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_DIR="$(llvm-config --cmakedir)"
cmake --build build --parallel 3See Build and toolchains for Windows setup and toolchain requirements.
From the repository root after building:
- Create
example.c:
#include <stdio.h>
int protected_value(int input) {
return (input * 7) ^ 0x5a;
}
int main(void) {
printf("%d\n", protected_value(7));
return 0;
}- Create
protect.yaml:
profile: standard
seed: 20260817
default_level: none
overrides:
- name: protected_value
level: strong_vm
self_checksum:
enabled: false- Compile and run the program:
build/obf-clang --obf-config=protect.yaml \
-O1 -fno-inline example.c -o example
./exampleExpected output:
107
The wrapper loads the plugin and links libobf_runtime.a.
Self-checksum is disabled in this example, so no binding step is needed.
Policy floors and caller promotions can select functions beyond the explicit target.
Use obf-clang++ for C++. Select functions by LLVM symbol name or source annotation.
VM expansion can increase build time, memory use, binary size, and runtime cost.
Keys are embedded in the binary. Debugging, tracing, and memory inspection can expose live plaintext.
- VM header and successor checks run before handler effects. They are not cryptographic authentication.
- Authenticated runtime decoders check descriptors, ciphertext tags, and completed payloads. A valid-looking abandoned decode owner can leave waiters pending indefinitely.
- Self-checksum covers selected code samples, not the whole binary. Required records must be bound after the final link.
- Ordinary
vmcan leave unsupported functions native. Thestrong_vmadmission gate applies only while VM eligibility remains enabled.
Exception edges or inline assembly can disable VM eligibility, even for an exact strong_vm override.
See feature restrictions and SECURITY.md for the full limits and private reporting contact.
| Task | Guide |
|---|---|
| Build and select compatible tools | Build and toolchains |
| Use annotations, bitcode, or managed ELF LTO | Usage |
| Set selectors, profiles, and transform options | Configuration |
| Integrate Rust, Zig, or TinyGo | Other frontends |
| Understand transforms and pipeline order | Protection reference |
| Bind self-checksum records | Self-checksum binding |
| Run tests, benchmarks, and audits | Development |
| View existing decompiler and control-flow images | Visual examples |
See the documentation index for runtime and contribution references.
GNU General Public License v3.0. Developed by @90th.