There was a question the other day: “How to hide lines of text in a compiled application from fans of hex-editors?”. But to hide so that it does not require much effort, so, by the way ...
The task is to use strings as usual in the code, but these strings were not explicitly stored in the executable file, the capabilities of third-party utilities that work with already compiled binary files do not want to be used, everything needs to be done from plain C ++ code.
It is clear that we will have to connect the possibilities of C ++ in the field of metaprogramming and calculate the encryption of strings at the compilation stage. But templates in their pure form do not allow strings to be used as initialization parameters. Fortunately,
constexpr appeared in C ++ 11, functions whose results can be computed at compile time. In C ++ 11 itself, their capabilities are rather limited (for example, cycles and conditions cannot be used), but in the C ++ 14 standard they have been significantly expanded to almost the capabilities of ordinary functions (of course, this should be only pure functions without side effects ).
The resulting small example:
#include <string> #include <iostream> #include <iterator> // template<std::size_t SIZE> struct hiddenString { // short s[SIZE]; // constexpr hiddenString():s{0} { } // std::string decode() const { std::string rv; rv.reserve(SIZE + 1); std::transform(s, s + SIZE - 1, std::back_inserter(rv), [](auto ch) { return ch - 1; }); return rv; } }; // template<typename T, std::size_t N> constexpr std::size_t sizeCalculate(const T(&)[N]) { return N; } // template<std::size_t SIZE> constexpr auto encoder(const char str[SIZE]) { hiddenString<SIZE> encoded; for(std::size_t i = 0; i < SIZE - 1; i++) encoded.s[i] = str[i] + 1; encoded.s[SIZE - 1] = 0; return encoded; } // #define CRYPTEDSTRING(name, x) constexpr auto name = encoder<sizeCalculate(x)>(x) int main() { // , // , // CRYPTEDSTRING(str, "Big big secret!"); std::cout << str.decode() << std::endl; return 0; }
The example does not pretend to a complete program and demonstrates only the principle itself.
For example, the encoder and descrambler increment and decrement the original characters of the string, in theory, you can fasten quite complex algorithms with keys and decryption even on a remote server. True, there is a fly in the ointment, it took to use the capabilities of C ++ 14, maybe someone knows a better way?
PS The example was compiled on Arch Linux using clang 3.5.0 with the following command:
$: clang ++ -std = c ++ 1y -stdlib = libc ++ -lc ++ abi sample.cpp -o sample
Authors: Tokarev AV, Grishin M.L.