Compile-time `memfrob()` literal for C++20.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
Avril f1f632854c
update README
3 years ago
test added \*frob 3 years ago
.gitignore initial commit 3 years ago
Makefile added -Werror to test 3 years ago
README.md update README 3 years ago
cfrob.hpp added \*frob 3 years ago

README.md

Compile-time memfrob()

glibc has a function in string.h called memfrob() which applies ROT13 to an arbitrary byte buffer. This small C++20 header allows you to do this at compile time to trivially obscure string literals without the literal itself appearing in the binary anywhere at all.

Usage

The literals can be created and stored as a sized char array, or as a C string pointer.

#include "cfrob.hpp"

const auto easter_egg = "Something cool"_frob;
const char* c_like_easter_egg = "Something cool"_frob;

To reverse just apply ROT13 on to the string again.

#include <cstring>

auto string2 = strdup(easter_egg);
memfrob(string2, strlen(easter_egg));
// `string2` now contains the string "Something cool"
free(string2);

Functions

Also provided are memfrob() and strfrob() functions of our own for both strings and binary data, which do the same as libc memfrob().

/// `memfrob()`
{
  const unsigned char data[] = {
    0xa, 0xd, 0x10, 0xf7,
  };

  const auto ctime = forb::memfrob(data); // Done at compile time, like the literal.

  const std::vector<unsigned char> cloned = frob::memfrob(data, sizeof(data)); // Clone constant data at runtime into a new `std::vector<unsigned char>`.

  unsigned char* data2 = malloc(10);
  frob::memfrob(data2, 10); // Mutated in place
  free(data2);

  const std::vector<unsigned char> xvec{0xad, 0xb, 0xc};
  std::vector<unsigned char> xfrobbed = frob::memfrob(xvec); // Cloned;

  std::vector<unsigned char> vec{0xad, 0xb, 0xc};
  frob::memfrob(&vec); // Mutated `vec` in place. (explicit pointer is used here so you know it's not mutating when you might not expect.) 
}
/// `strfrob()`
{
  const char* string= "const";
  std::string frobbed = frob::strfrob(string); // Cloned

  char* string2 = "mutated";
  frob::strfrob(string2); // Mutated in plate

  const std::string xstring = "stl const string"s;
  std::string xfrobbed = frob::strfrob(xstring); // Cloned

  std::string xstring2 = "stl mutate string";
  frob::strfrob(&xstring2); // Mutated in plate (explicit pointer is used here so you know it's not mutating when you might not expect.)

  constexpr const auto ctime = frob::strfrob<>("done at comptime, like the literal `_frob`"); // Explicit template `<>` is required here otherwise it overloads to the non `constexpr` functions, even in a `constexpr` context;
}

All functions (except the literal operator) are in the namespace frob.

Configuring

By default we use the same mechanism as memfrob(): ROT13 via bitwise xor of the number 42. If you would like to use a different number for the bitwise xor, defined the constant FROB_CONSTANT before #includeing the header.

#define FROB_CONSTANT 82
#include "cfrob.hpp"

Note that the defined constant must fit in the range 0-255 inclusive.

Test

Run make test to build and run the test that ensures the original string literal does not appear anywhere in the outputted binary.

License

Public domain.