Skip to the content.

Go back to the home page

Background

After the introduction of constexpr in C++11, I had an idea to use it to automatically obfuscate string literals in C++ programs. Indeed it was only in C++14 with the acceptance of N3652 i.e relaxing constraints on constexpr functions, that it became much simpler to implement. It was actually a very small project compared to what I have done in the past, with only 200 lines of code. Since its initial release it has become quite popular due to its simplicitly, and I have been maintaining it and incrementally improving it ever since.

Whats the problem?

When plain text string literals are used in C++ programs, they will be compiled as-is into the resultant binary. This causes them to be incredibly easy to find. One can simply open up the binary file in a text editor to see all of the embedded string literals in plain view. A special utility called strings exists which can be used to search binary files for plain text strings.

What does Obfuscate do?

This header-only library seeks to make it difficult (but not impossible) for embedded string literals in binary files to be found by encrypting them with an XOR cipher at compile-time using a constant expression, forcing the compiler to work with the encrypted string instead of the plain text literal. Usage of AY_OBFUSCATE additionally removes the need for a const pointer to the string, which more often than not (for small strings) convinces the compiler to inline the encrypted string, building it up at runtime in a series of assembly operations, protecting the binary image against simple XOR decryption attacks. Encrypted strings will then be decrypted at runtime to be utilised within the program.

Technical features

By simply wrapping your string literal "My String" with AY_OBFUSCATE("My String") it will be encrypted at compile time with a random 64 bit key and stored in an ay::obfuscated_data object which you can manipulate at runtime. For convenience it is also implicitly convertable to a char*.

For example, the following program will not store the string “Hello World” in plain text anywhere in the compiled executable.

#include "obfuscate.h"

int main()
{
  std::cout << AY_OBFUSCATE("Hello World") << std::endl;
  return 0;
}

Examples of usage

Because the obfuscated data that is generated by AY_OBFUSCATE has global lifetime it is completely fine to also use it in both a local and a temporary context.

char* var = AY_OBFUSCATE("string");
const char* var = AY_OBFUSCATE("string");
static const char* var = AY_OBFUSCATE("string");
std::string var(AY_OBFUSCATE("string"));
function_that_takes_char_pointer(AY_OBFUSCATE("string"));