creo que esta pregunta merece una respuesta actualizada.
Cuando hice esta pregunta hace varios años, no consideré the difference between obfuscation and encryption. Si hubiera conocido esta diferencia, habría incluido el término Ofuscación en el título anterior.
C++ y C++ 11 14 tienen características que hacen posible la implementación de en tiempo de compilación ofuscación cadena (y posiblemente cifrado, aunque no he probado todavía) de una manera eficaz y razonablemente simple, y ya está hecho.
ADVobfuscator es una biblioteca de ofuscación creada por Sebastien Andrivet que utiliza C++ 11/14 para generar código ofuscado en tiempo de compilación sin utilizar ninguna herramienta externa, solo código C++. No es necesario crear pasos de compilación adicionales, simplemente inclúyalo y úselo. No conozco una mejor implementación de encriptación/ofuscación de cadenas en tiempo de compilación que no use herramientas externas ni pasos de compilación. Si tu lo haces, por favor compártelo.
No solo obusa cadenas, sino que tiene otras funciones útiles como FSM en tiempo de compilación (Finite State Machine) que pueden ofuscar de forma aleatoria las llamadas de función y un generador de números pseudoaleatorios en tiempo de compilación, pero están fuera del alcance de esta respuesta.
Aquí es un simple ejemplo de cadena de ofuscación utilizando 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's 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's still deobfuscation
cout << narrator.decrypt() << endl;
}
Puede reemplazar las macros DEF_OBFUSCATED
y OBFUSCATED
con sus propias macros. Ej .:
#define _OBF(s) OBFUSCATED(s)
...
cout << _OBF("klapaucius");
¿Cómo funciona?
Si se echa un vistazo a la definición de estas dos macros en MetaString.h, verá:
#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())
Básicamente, hay tres variantes diferentes del MetaString
clase (el núcleo de la ofuscación de cadena) . Cada uno tiene su propio algoritmo de ofuscación. Una de estas tres variantes se elige aleatoriamente en tiempo de compilación, utilizando el generador de números pseudoaleatorios de la biblioteca (MetaRandom
), junto con un char
aleatorio que es utilizado por el algoritmo elegido para xor
los caracteres de cadena.
"Oye, pero si hacemos los cálculos, algoritmos 3 * 255 claves posibles char (0 no se utiliza) = 765 variantes de la cadena ofuscado"
Tienes razón. La misma cadena solo puede ofuscarse en 765 formas diferentes. Si tiene una razón para necesitar algo más seguro (es paranoico/su aplicación exige mayor seguridad) puede ampliar la biblioteca e implementar sus propios algoritmos, utilizando una ofuscación más fuerte o incluso cifrado (White-Box cryptography se encuentra en el mapa de ruta de la lib).
Dónde/cómo se almacenan las cadenas ofuscado?
Una cosa que me parece interesante sobre esta implementación es que no almacena la cadena ofuscada en la sección de datos del ejecutable. En su lugar, está almacenado estáticamente en el objeto MetaString
(en la pila) y el algoritmo lo decodifica en su lugar en tiempo de ejecución. Este enfoque hace que sea mucho más difícil encontrar las cadenas ofuscadas, estáticamente o en tiempo de ejecución.
Puede profundizar en la implementación por su cuenta. Esa es una solución de ofuscación básica muy buena y puede ser un punto de partida para una más compleja.
Un enfoque común para este tipo de problema es escribir una secuencia de comandos que toma su archivo de origen como una entrada y crea un archivo modificado como salida, que luego sería utilizado por su proceso de compilación. En este caso, el script buscará 'EncryptString <" String para encriptar ">' y reemplazará la cadena con la versión encriptada/codificada. – jdigital