Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Konran

Konran is a Clang plugin that automatically wraps every string literal in your C++ code with the OBF() macro at compile time. No source files are modified. No manual wrapping is required.

When paired with obfusheader.h, strings are XOR-encrypted during compilation and decrypted at runtime. Plaintext strings never appear in the binary.

source:  key["mode"] = "encrypt";
           |
           v  (Konran rewrites the compiler buffer)
           |
memory:  key[OBF("mode")] = OBF("encrypt");
           |
           v  (obfusheader.h encrypts at compile time)
           |
binary:  XOR-garbage bytes instead of plaintext
           |
           v  (runtime: obfuscator::decrypt() XORs back)
           |
runtime: original strings restored

Requirements

  • Clang / LLVM (matching the version used by your NDK or system compiler)
  • CMake 3.20+
  • C++20

Build

Konran supports:

  • MODULE builds (Clang plugin)
  • SHARED builds
  • STATIC builds

Configure

cmake -B build \
  -DBUILD_MODULE=ON \
  -DBUILD_SHARED=ON \
  -DBUILD_STATIC=ON

Disable targets you do not want:

cmake -B build \
  -DBUILD_MODULE=ON \
  -DBUILD_SHARED=OFF \
  -DBUILD_STATIC=OFF

Linux / macOS

cmake --build build -j$(nproc)

Windows

Use:

  • Visual Studio toolchain
  • MSVC
  • Ninja or Visual Studio generator

Do not use MinGW with official LLVM binaries.

cmake -B build -G Ninja
cmake --build build

Some LLVM Windows releases export broken DIA SDK paths in generated CMake files. If linking fails with:

diaguids.lib

patch the generated LLVM CMake export from:

C:/Program Files/Microsoft Visual Studio/2022/Enterprise/...

to either:

diaguids.lib

or your installed Visual Studio edition path.

Output

Artifacts are placed automatically into:

artifacts/<os>/<arch>/

Examples:

artifacts/windows/AMD64/Konran.dll
artifacts/windows/AMD64/Konran.lib
artifacts/windows/AMD64/KonranStatic.lib

artifacts/linux/x86_64/Konran.so

artifacts/macos/arm64/Konran.dylib

Usage

Linux

clang++ -c file.cpp -o file.o \
  -Xclang -load \
  -Xclang ./artifacts/linux/x86_64/Konran.so \
  -Xclang -plugin \
  -Xclang konran \
  -Xclang -plugin-arg-konran \
  -Xclang ./include/obfusheader.h \
  source.cpp

macOS

clang++ -c file.cpp -o file.o \
  -Xclang -load \
  -Xclang ./artifacts/macos/arm64/Konran.dylib \
  -Xclang -plugin \
  -Xclang konran \
  -Xclang -plugin-arg-konran \
  -Xclang ./include/obfusheader.h \
  source.cpp

Windows

clang++ -c file.cpp -o file.obj ^
  -Xclang -load ^
  -Xclang artifacts/windows/AMD64/Konran.dll ^
  -Xclang -plugin ^
  -Xclang konran ^
  -Xclang -plugin-arg-konran ^
  -Xclang include/obfusheader.h ^
  source.cpp

Each -Xclang prefix passes the immediately following argument to the Clang frontend. Write each frontend argument as a separate pair.

CMake (NDK / Android)

target_compile_options(your_target PRIVATE
  -Xclang -load
  -Xclang ${CMAKE_SOURCE_DIR}/artifacts/android/arm64-v8a/Konran.so
  -Xclang -plugin
  -Xclang konran
  -Xclang -plugin-arg-konran
  -Xclang ${CMAKE_SOURCE_DIR}/include/obfusheader.h
  -fno-merge-constants
  -fno-merge-all-constants
)

Skipping specific strings

Use // konran:off and // konran:on comment markers:

// konran:off
void debug_log(const char *msg) {
    printf("DEBUG: %s\n", msg);
}
// konran:on

const char *secret = "this gets encrypted";

Or on a single line:

const char *visible = "debug string"; // konran:off

Strings on whitelisted lines are left untouched. Everything else is wrapped in OBF() automatically.

What gets wrapped

String type Konran behavior
"hello" Wrapped in OBF()
"line1" "line2" Wrapped as single OBF("line1" "line2")
OBF("already") Left untouched (detects existing OBF() calls)
R"(raw)" Left untouched
'x' Left untouched
#include "file" Left untouched
"debug" // konran:off Left untouched

Version compatibility

Konran must be built against the same LLVM major version as the compiler that loads it. A plugin built for LLVM 18 will not load in Clang 19.

NDK version LLVM version
r25 16
r26 17
r27 18
r28 20

How it works

  1. Konran hooks into Clang's compilation pipeline via PluginASTAction.
  2. Before the parser reads the source file, Konran reads it, transforms every string literal "..." into OBF("..."), and provides the transformed source to the compiler via buffer remapping.
  3. The obfusheader.h is force-included to make OBF() available.
  4. obfusheader.h's obfuscator template XORs each byte at compile time using a key derived from TIME and COUNTER.
  5. At runtime, decrypt() re-XORs the bytes to restore the original string.
  6. The compiler proceeds normally with the transformed source.
  7. EmitObjAction handles codegen, producing the final object file with no plaintext strings.

Files

CMakeLists.txt
src/Konran.cpp
include/obfusheader.h

License

Konran is released under the BSD 3-Clause license. obfusheader.h is licensed separately by its authors.

Credits

obfusheader.h by https://github.com/ac3ss0r/obfusheader.h

About

General Purpose String Obfuscation Plugin For Clang and LLVM

Topics

Resources

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages