Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/adamyaxley/Obfuscate
Guaranteed compile-time string literal obfuscation header-only library for C++14
https://github.com/adamyaxley/Obfuscate
cpp14 cpp17 embedded-string-literals header-only obfuscate obfuscate-strings obfuscation string string-literals string-obfuscation
Last synced: 9 days ago
JSON representation
Guaranteed compile-time string literal obfuscation header-only library for C++14
- Host: GitHub
- URL: https://github.com/adamyaxley/Obfuscate
- Owner: adamyaxley
- License: unlicense
- Created: 2017-11-15T13:08:16.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2024-07-10T10:51:51.000Z (4 months ago)
- Last Synced: 2024-10-16T11:05:31.016Z (24 days ago)
- Topics: cpp14, cpp17, embedded-string-literals, header-only, obfuscate, obfuscate-strings, obfuscation, string, string-literals, string-obfuscation
- Language: C++
- Homepage:
- Size: 64.5 KB
- Stars: 1,046
- Watchers: 21
- Forks: 171
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- AwesomeCppGameDev - Obfuscate - time string literal obfuscation header-only library for C++14 (C++)
README
**[Source available on GitHub](https://github.com/adamyaxley/Obfuscate)**
# Obfuscate
Guaranteed compile-time string literal obfuscation header-only library for C++14.## Quick start guide
1. Copy `obfuscate.h` into your project
2. Wrap strings with `AY_OBFUSCATE("My String")`Now your project will not expose those strings in plain text in the binary image.
_Note that these strings will still be accessible to determined hackers. Using obfuscation to hide private passwords or any other security sensitive strings is not recommended by the author._
## 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](https://en.wikipedia.org/wiki/Strings_(Unix)) exists which can be used to search binary files for plain text strings.## What does this library 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
* _Guaranteed compile-time obfuscation_ - the string is compiled with a constexpr expression.
* _Global lifetime (per-thread)_ - the obfuscated string is stored in a thread local variable in a unique lambda.
* _Implicitly convertible to a char*_ - easy to integrate into existing codebases.
* _Random 64-bit key_ - obfusated with a random key each time.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.
```c++
#include "obfuscate.h"int main()
{
std::cout << AY_OBFUSCATE("Hello World") << std::endl;
return 0;
}
```### Examples of usage
Because the obfuscated string that is generated by `AY_OBFUSCATE` has global lifetime per-thread, it is completely fine to also use it in both a local and a temporary context.
```c++
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"));
```### Thread safety
This library can be used in a multi-threaded environment only if `AY_OBFUSCATE` is used in a local context per thread. This is because the obfuscated string is internally stored with `thread_local` storage. The following usage is supported:```c++
void fun()
{
auto var = AY_OBFUSCATE("Thread Safe");
var.decrypt();
std::cout << var << std::endl;
var.encrypt();
}int main()
{
std::thread thread1(fun);
std::thread thread2(fun);thread1.join();
thread2.join();
return 0;
}
```Conversely, sharing an obfuscated string returned from `AY_OBFUSCATE` between multiple threads is *not* supported. In this case you must put locks in appropriate places in your code to ensure that only one thread accesses it at a time. The following usage is *not* supported:
```c++
int main()
{
for (size_t i = 0; i < 1000; i++)
{
auto var = AY_OBFUSCATE("NOT Thread Safe");
var.decrypt();
std::thread thread([&var]() {
std::cout << var << std::endl;
});
// We are encrypting the string here, but outputting it in
// another thread at the same time. This will not work.
var.encrypt();thread.join();
}
return 0;
}
```## Binary file size overhead
This does come at a small cost. In a very naive login program, which obfuscates two strings (username and password) the following binary file bloat exists.| Config | Plain string literals | Obfuscated strings | Bloat |
|:------:|:---------------------:|:------------------:|:-----:|
| Release | 18944 | 21504 | 2560 (13.5%) |
| Debug | 95232 | 101888 | 6656 (7.0%) |This output is generated by running test_bloat.py