[recovery mode] Обфускация строк на этапе компиляции

Возник на днях у нас вопрос: «Как спрятать от любителей hex-редаторов строчки текста в скомпилированном приложении?». Но спрятать так, чтобы это не требовало особых усилий, так, между прочим…Задача состоит в том, что бы использовать в коде строки как обычно, но при этом в исполняемом файле эти строки в явном виде не хранились, возможности сторонних утилит, которые работают с уже скомпилированными бинарными файлами, задействовать так же не хочется, все нужно делать из обычного C++ кода.Ясно, что нам придется подключить возможности С++ в области метапрограммирования и вычислять шифрование строк на этапе компиляции. Но шаблоны в чистом виде не позволяют использовать в качестве параметров инициализации строки. К счастью, в C++11 появились constexpr — функции, результат которых может быть вычислен на этапе компиляции. В собственно C++11 их возможности довольно ограничены (нельзя использовать, например, циклы и условия), но в новом стандарте C++14 они были существенно расширены практически до возможностей обычных функций (естественно, это должны быть только чистые функции без побочных эффектов).Получившийся небольшой пример: #include #include

//хранилице зашифрованных строк template struct hidedString { //буффер для зашифрованной строки short s[SIZE + 1];

//конструктор для создания объекта на этапе компиляции constexpr hidedString (): s{0} { }

//функция дешифрации в процессе исполнения приложения std: string decoder () const { std: string rv; for (int i=0; i

//вычисление размера строки на этапе компиляции constexpr int sizeCalculate (const char* str) { int cnt = 0; while (*str++) cnt++; return cnt; }

//функция шифрации на этапе компиляции template constexpr hidedString encoder (const char* str) { hidedString s;

for (int i = 0; i < SIZE; i++) s.s[i] = str[i] + 1;

s.s[SIZE] = 0; return s; }

//макрос для удобства использования #define CRYPTEDSTRING (name, x) constexpr hidedString name = encoder(x)

int main () { //выведем зашифрованную на этапе компиляции строку, //если посмотреть содержимое скомпилированного файла, //то оригинал там отсутствует CRYPTEDSTRING (str, «Big big secret!»); std: cout << str.decoder(); return 0; } Пример не претендует на законченную программу и демонстрирует лишь сам принцип.Шифратор и дешифратор просто для примера инкрементируют и декрементируют оригинальные символы строки, в теории можно прикрутить достаточно сложные алгоритмы с ключами и расшифровкой хоть на удаленном сервере. Правда есть ложка дегтя, потребовалось задействовать возможности С++14, возможно кто-то знает способ лучше?ПС. Пример компилировался на Arch Linux с помощью clang 3.5.0 следующей командой: $: clang++ -std=c++1y -stdlib=libc++ -lc++abi sample.cpp -o sample

Авторы: Токарев А.В., Гришин М.Л.

© Habrahabr.ru