Self-hosted service
andrivet/ADVobfuscator avatar
andrivet/ADVobfuscator

ADVobfuscator hides strings in the compiler, not in a post build step

Obfuscation library based on C++20 and metaprogramming

1,782 stars264 forksC++BSD-3-Clause-Clear

At a glance

What is it?
ADVobfuscator is a header only C++20 library that obfuscates strings, byte blocks and call sequences at compile time using templates and constexpr, with no external tool and no compiler patch. The catch is blunt: it does nothing in a Debug build, and AES support is partial on Clang and Visual Studio.
Who is it for?
Adopt ADVobfuscator if you ship a native binary whose strings you do not want visible in a hex dump, and you build with GCC or a recent Clang in Release mode. Do not adopt it if you need AES everywhere, because the compatibility table marks AES as limited on Apple Clang, several Clang builds and both Visual Studio entries, and marks obfuscation off entirely for GCC 13.3.0 on macOS AArch64.
Can I use it commercially?
Yes. BSD-3-Clause-Clear is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 35 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Header only, constexpr, and no compiler modification

ADVobfuscator's claim is narrow and checkable: obfuscated data and code are produced at compile time, without an external tool and without modifying the compiler. In practice that means the whole library lives under `include/advobfuscator` as headers you drop into your include path. There is no link step, no code generator, no wrapper script around your build.

The eight headers each cover one mechanism. `string.h` handles obfuscated strings, `bytes.h` obfuscated blocks of bytes, `aes.h` obfuscation using AES-128 compile time encryption, and `aes_string.h` obfuscated strings using the same AES-128 scheme. `fsm.h` is a compile time finite state machine used to obfuscate function calls, which is the one mechanism here that hides control flow rather than data. `obj.h` is labelled simply Obfuscation, `random.h` generates random numbers at compile time, and `format.h` gives std::format formatting of strings.

`random.h` is the piece that makes the rest work. Obfuscation that is fixed at compile time has to be generated at compile time, so the key material and the transformed payload are both constexpr values the compiler evaluates while it type checks your template arguments. The README points to a PDF for the details: the documentation at https://andrivet.github.io/ADVobfuscator/ADVobfuscator.pdf covers how the library is built, how to install and use it.

Because everything is templates and constexpr, the cost lands in compile time and in error messages rather than in a runtime dependency. That is the trade you are making.

Debug builds silently produce no obfuscation at all

This is the single most important operational fact in the README and it is stated without hedging. Debug builds do not respect statements such as `inline` or `constexpr`, and optimizations are disabled by default, which compilers do so you can step through code. As a consequence the README says plainly that ADVobfuscator is not compatible with Debug builds, that you can compile in Debug, and that in this case the strings or data will not be obfuscated. Obfuscation works only for Release builds.

There is no warning, no `#error`, and no runtime flag described. A developer debugging locally sees their plaintext string in memory and concludes the library works. The same code path in a Release pipeline produces something else entirely. Any adoption decision has to include a check on the shipped configuration rather than on the developer's daily build.

Note also that this is a property of the toolchain, not a bug in the library. The obfuscated value is a constexpr computation, and a Debug configuration is defined by disabling the compiler behaviour that evaluates it. That is why the constraint cannot be lifted by adding a runtime option.

Building the examples on Linux, macOS and in Docker

The requirements are short: a C++20 compatible compiler, described in the README as a compiler that is not too old, and a C++20 Standard Library, which is generally the case if the compiler supports C++20, with the README warning about exceptions in embedded environments. CMake 3.14 is needed only if you want to build the examples with CMake, and it is explicitly optional.

On Linux and macOS with CMake, the examples build out of tree into a directory called BUILD:

bash
mkdir -p BUILD
cd BUILD
cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build .

The Release configuration in that third line is the whole point of the example script. Each example sits in its own subdirectory, so the demo binary is run as `./example/demo`. The library itself is not built by this: what is built is code that consumes the headers.

Two Dockerfiles are provided for reproducing a toolchain without touching the host. The Clang path:

bash
docker build -t advobfuscator-clang -f docker/clang.docker .
docker run --rm -it advobfuscator-clang:latest

And the GCC path, which changes only the image name and the dockerfile:

bash
docker build -t advobfuscator-gcc -f docker/gcc.docker .
docker run --rm -it advobfuscator-gcc:latest

The first command must run from the repository root, since both paths are relative to it. On Windows the route is Visual Studio, and the README's instruction is a single sentence: open `ADVobfuscator.sln`. That solution file sits at the top level of the repository next to `CMakeLists.txt` and the `Examples` directory.

What the compatibility table actually promises, and where it stops

The README publishes a table with two columns that matter more than the compiler column: Obfuscation and AES. Read it before choosing a toolchain.

Full AES support is listed for exactly three rows, all GCC: 15.1.0 on macOS 15 x86_64, 14.2.0 on macOS 15 AArch64, and 14.2.0 on Debian 13 x86_64. Every Clang row and every Visual Studio row says limited for AES. Apple Clang 17.0.0 on macOS 15 AArch64, Clang 21.1.8, 19.1.7, 18.1.8 and 17.0.6 on Debian, Visual Studio 2022 17.14.13 on Windows 11 AArch64, and Visual Studio 2026 18.0.339 on Windows 11 AArch64 all obfuscate, all with limited AES.

The one row where obfuscation itself is NO is GCC 13.3.0 on macOS 15 AArch64, which also has NO for AES. That is a silent trap for a developer on an older GCC on Apple Silicon: the headers compile, the example builds, and nothing is obfuscated.

The README hedges the table with one sentence, that other compilers are probably compatible if they are C++20 compliant. Probably is doing real work in that sentence, and it sits directly below a table with a hard NO in it.

Licence terms are BSD three clause with an explicit patent carve out

The project is published under BSD-3-Clause-Clear, copyright 2025 Sebastien Andrivet, and the LICENSE file is the full text rather than a summary. Three conditions apply: source redistributions must retain the copyright notice and conditions, binary redistributions must reproduce that notice in the documentation or other materials provided with the distribution, and neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote derived products without prior written permission.

The Clear variant is the part to notice. The text states that no express or implied licenses to any party's patent rights are granted by this licence. For a company shipping a closed binary that vendors the headers, that sentence is the reason to read the LICENSE file rather than rely on the label on a dependency list.

The warranty disclaimer is the standard one: the software is provided as is, and the contributors are not liable for damages including loss of use, data or profits. Nothing here restricts use in a commercial product beyond the notice and endorsement conditions.

Version 2.1.3 and the cost of staying current

Three releases are visible in the recent history: v2.1.3 on 2026-09-18, v2.1.2 on 2026-04-11, and v2.1.1 on 2025-12-11. The repository is not archived and the last push was on 2026-09-18, the same day as v2.1.3.

The upgrade path is a C++ library upgrade with all the awkwardness that implies. The headers are templates evaluated inside your own translation units, so a version bump changes what your compiler instantiates, which can surface as a new error deep inside a constexpr evaluation rather than at a clean call site. Since the repository ships a change log at the top level as `CHANGELOG.txt`, the migration input exists; the README does not describe a deprecation policy or a compatibility promise between minor versions.

What keeps the upgrade cheap is that there is nothing to relink. The library's whole surface is eight headers, the examples are a convenience, and the tests directory at the top level gives you something to run against your own toolchain before you trust a new version in a release pipeline.

Where a runtime packer would do the same job

The obvious alternative is to obfuscate after the fact. A packer or protector applied to a finished executable, or a post processing step that rewrites string literals in the binary, reaches a similar goal with none of the compiler dependency. The difference runs the other way from what you might expect: those tools add a runtime component and a signature, while ADVobfuscator adds nothing at runtime and requires that your compiler actually evaluate your templates.

The other alternative is to do nothing at compile time and hide strings at runtime yourself, storing them encrypted and decrypting on demand with a small wrapper type. That gives you control over when the plaintext exists in memory, which ADVobfuscator does not offer, since its payload is decoded at runtime by its own generated accessor.

What neither alternative gives you is the function call obfuscation in `fsm.h`, which restructures calls through a compile time state machine. That is the part with no drop in equivalent outside a compile time C++ library.

One honest limitation applies to all three: hiding a string from a hex dump does not hide it from someone who single steps the decode.

Editorial conclusion

Adopt ADVobfuscator if you ship a native binary whose strings you do not want visible in a hex dump, and you build with GCC or a recent Clang in Release mode. Do not adopt it if you need AES everywhere, because the compatibility table marks AES as limited on Apple Clang, several Clang builds and both Visual Studio entries, and marks obfuscation off entirely for GCC 13.3.0 on macOS AArch64. Verify first that your exact compiler and configuration produce obfuscated output, since a Debug build compiles cleanly and silently does nothing, and confirm which of aes.h and aes_string.h your platform actually executes rather than falling back to.

Frequently asked questions

Does ADVobfuscator work in a Debug build?

No. The README states it is not compatible with Debug builds, and that in Debug the strings or data will not be obfuscated. Obfuscation works only for Release builds, because Debug configurations do not evaluate `constexpr`.

Which compilers does ADVobfuscator support?

The compatibility table lists Apple Clang, several Clang versions on Debian, GCC and two Visual Studio versions, all on macOS, Debian or Windows 11. The README says other compilers are probably compatible if they are C++20 compliant.

Is AES-128 support complete on every platform?

No. The table marks AES as limited for every Clang row and both Visual Studio rows, and full only for GCC 15.1.0 on macOS, GCC 14.2.0 on macOS AArch64 and GCC 14.2.0 on Debian.

How do I build the ADVobfuscator examples?

On Linux and macOS create a BUILD directory, run CMake with -DCMAKE_BUILD_TYPE=Release and build it, then run the example binary from its subdirectory such as `./example/demo`. CMake 3.14 is required for that route only.

What licence is ADVobfuscator under?

BSD-3-Clause-Clear, copyright 2025 Sebastien Andrivet. The LICENSE text adds that no express or implied licenses to any party's patent rights are granted by the licence.

Official sources

  1. andrivet/ADVobfuscator on GitHub
  2. Issues
  3. License: BSD-3-Clause-Clear
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/andrivet-advobfuscator.svg)](https://hysenlabs.com/projects/andrivet-advobfuscator)

Was this useful?