Ответ 1
Я думаю, что этот вопрос заслуживает обновленного ответа.
Когда я задал этот вопрос несколько лет назад, я не рассматривал разницу между обфускацией и шифрованием. Если бы я знал эту разницу, я бы включил термин Obfuscation в названии раньше.
С++ 11 и С++ 14 имеют функции, которые позволяют реализовать компиляцию string obfuscation (и, возможно, шифрование, хотя я еще не пробовал это) в эффективном и достаточно простой способ, и это уже сделано.
ADVobfuscator - это библиотека обфускации, созданная Sebastien Andrivet, которая использует С++ 11/14 для генерации сфабрифицированного кода времени компиляции без используя любой внешний инструмент, только код на С++. Нет необходимости создавать дополнительные шаги сборки, просто включите его и используйте. Я не знаю лучшей реализации шифрования/обфускации строкой времени компиляции, которая не использует внешние инструменты или шаги сборки. Если да, разделите.
Он не только обдумывает строки, но и имеет другие полезные вещи, такие как FSM компиляции (Конечный автомат), который может случайным образом запутывать вызовы функций и генератор псевдослучайных чисел времени компиляции, но они не входят в объем ответа.
Вот пример простой обфускации с использованием ADVobfuscator:
#include "MetaString.h"
using namespace std;
using namespace andrivet::ADVobfuscator;
void Example()
{
/* Example 1 */
// here, the string is compiled in an obfuscated form, and
// it only deobfuscated at runtime, at the very moment of its use
cout << OBFUSCATED("Now you see me") << endl;
/* Example 2 */
// here, we store the obfuscated string into an object to
// deobfuscate whenever we need to
auto narrator = DEF_OBFUSCATED("Tyler Durden");
// note: although the function is named `decrypt()`, it still deobfuscation
cout << narrator.decrypt() << endl;
}
Вы можете заменить макросы DEF_OBFUSCATED
и OBFUSCATED
на свои собственные макросы. Например:.
#define _OBF(s) OBFUSCATED(s)
...
cout << _OBF("klapaucius");
Как это работает?
Если вы посмотрите на определение этих двух макросов в MetaString.h, вы увидите:
#define DEF_OBFUSCATED(str) MetaString<andrivet::ADVobfuscator::MetaRandom<__COUNTER__, 3>::value, andrivet::ADVobfuscator::MetaRandomChar<__COUNTER__>::value, Make_Indexes<sizeof(str) - 1>::type>(str)
#define OBFUSCATED(str) (DEF_OBFUSCATED(str).decrypt())
В принципе, существует три разных варианта класса MetaString
(ядро обфускации строки). Каждый из них имеет свой собственный алгоритм обфускации. Один из этих трех вариантов выбирается случайным образом во время компиляции, используя генератор псевдослучайных чисел библиотеки (MetaRandom
), а также случайный char
, который используется выбранным алгоритмом для xor
символов строки.
"Эй, но если мы сделаем математику, 3 алгоритма * 255 возможных char ключей (0 не используется) = 765 вариантов обфускации строки
Ты прав. Та же строка может быть запущена только 765 различными способами. Если у вас есть причина нуждаться в чем-то более безопасном (вы параноидны/ваше приложение требует повышенной безопасности), вы можете расширить библиотеку и реализовать свои собственные алгоритмы, используя более сильное обфускацию или даже шифрование (White -Box-криптография находится в дорожной карте lib).
Где/как он хранит запутанные строки?
Одна вещь, которая мне интересна в этой реализации, заключается в том, что она не хранит обфускацию в разделе данных исполняемого файла.
Вместо этого он статически сохраняется в самом объекте MetaString
(в стеке), и алгоритм декодирует его на месте во время выполнения. Этот подход значительно усложняет поиск запутанных строк, статически или во время выполнения.
Вы можете погрузиться глубже в реализацию самостоятельно. Это очень хорошее базовое решение для обфускации и может быть отправной точкой для более сложного.