Skip to content

Quick Start

LLVM 22 required for -mllvm flags. On LLVM 17–21, clang parses -mllvm options before -fpass-plugin has loaded the plugin, so every -kagura-* flag is rejected with "Unknown command line argument". Use the shipped kagura-opt, or opt --load-pass-plugin=<plugin> -kagura-… -passes=…, both of which work on all supported versions. See Known issues.

Get a Kagura-protected binary in under five minutes.

1. Get the plugin

Pre-built plugin binaries are published per release on the GitHub Releases page.

kagura-<version>-macos-arm64-llvm21.tar.gz
kagura-<version>-macos-arm64-llvm22.tar.gz
kagura-<version>-linux-x86_64-llvm19.tar.gz
kagura-<version>-linux-x86_64-llvm21.tar.gz
kagura-<version>-linux-x86_64-llvm22.tar.gz

Each archive contains:

  • plugin/KaguraObfuscator.{dylib,so}
  • runtime/libkagura_runtime.a
  • include/kagura/game_protect.h, include/kagura/VM.h, include/kagura/VMOpcodes.def

Only those three headers are installed (cmake/KaguraInstall.cmake). The pass-plugin headers — Options.h, Passes.h, Passes/, Utils.h — are deliberately not shipped: they include LLVM headers a consumer of the binary release does not have.

2. Obfuscate a single file

clang -fpass-plugin=path/to/KaguraObfuscator.dylib \
      -mllvm -kagura-str \
      -mllvm -kagura-fla \
      -mllvm -kagura-bcf \
      -mllvm -kagura-bcf-prob=50 \
      -O1 your_file.c -o your_file

For real projects, use a single JSON file to control every pass.

kagura.json
{
  "profile": "BALANCED",
  "passes": {
    "str":   true,
    "fla":   true,
    "bcf":   true,
    "honey": true,
    "mvo":   false
  },
  "tuning": {
    "bcf_prob": 40,
    "seed":     12345
  }
}
clang -fpass-plugin=path/to/KaguraObfuscator.dylib \
      -mllvm -kagura-config=kagura.json \
      -O1 your_file.c -o your_file

See Configuration for the full DSL.

4. IR-level use with opt

clang -O1 -emit-llvm -c your_file.c -o your_file.bc

opt --load-pass-plugin=path/to/KaguraObfuscator.dylib \
    -passes="kagura-str,function(kagura-fla,kagura-bcf,kagura-sub)" \
    your_file.bc -o your_file.opt.bc

clang your_file.opt.bc -o your_file

5. Per-function control

// Force-enable a pass for this function
__attribute__((annotate("kagura_fla")))
void critical_function(void) { /* ... */ }

// Force-disable a pass for this function
__attribute__((annotate("kagura_nofla")))
void performance_sensitive(void) { /* ... */ }

// Virtualize with the VM pass
__attribute__((annotate("kagura_vm")))
int verify_license(const char *key) { /* ... */ }

Some passes call symbols they do not define — str-aes, vm, anti-debug, tamper, pac, ci, bbcheck, telemetry, objc and jni — and those targets must link libkagura_runtime.a:

clang your_file.c path/to/libkagura_runtime.a -o your_file

See the Runtime Library page for the symbol matrix.

Next steps