c++ online ¿Cómo ocultar cadenas en un exe o un dll?




proguard obfuscator (8)

Descubrí que es posible extraer las cadenas codificadas de un binario.
Por ejemplo, la vista de propiedades de Process Explorer muestra toda la cadena con más de 3 caracteres.

Aquí está el código de un ejecutable simple que escribí simplemente para probarlo:

#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>

int _tmain(int argc, _TCHAR* argv[])
{
    _TCHAR* hiddenString1 =_T("4537774B-CC80-4eda-B3E4-7A9EE77991F5");
    _TCHAR* hiddenString2 =_T("hidden_password_or_whatever");
    for (int i= 0; i<argc; i++) {
        if (0 == _tcscmp(argv[i],hiddenString1)) {
            _tprintf (_T("The guid argument is correct.\n")); }
        else if (0 == _tcscmp(argv[i],hiddenString2)) {
            _tprintf (_T("Do something here.\n")); }
    }

    _tprintf (_T("This is a visible string.\n"));
    //Keep Running
    Sleep(60000);
    return 0;
}

Las cadenas se pueden extraer claramente del ejecutable correspondiente:

Creo que es un poco demasiado fácil encontrar las cuerdas.

Mis preguntas son:

  1. ¿Cómo simplemente ocultar hiddenString1 o hiddenString2 en el ejecutable?
  2. ¿Hay una manera más segura de usar el "código de trampa" que con alguna entrada oscura oculta?

Bienvenido al mundo más amplio de la programación defensiva.

Hay un par de opciones, pero creo que todas dependen de alguna forma de ofuscación; que, aunque no es perfecto, es al menos algo.

  1. En lugar de un valor de cadena recta, puede almacenar el texto en alguna otra forma binaria (¿hex?).

  2. Puede encriptar las cadenas que están almacenadas en su aplicación y luego descifrarlas en tiempo de ejecución.

  3. Puede dividirlos en varios puntos de su código y reconstituirlos más tarde.

O alguna combinación de eso.

Tenga en cuenta que algunos ataques van más allá de mirar el binario real. A veces investigarán el espacio de direcciones de memoria del programa mientras se está ejecutando. MS ideó algo llamado SecureString en .Net 2.0 . El propósito es mantener las cadenas encriptadas mientras se ejecuta la aplicación.

Una cuarta idea es no almacenar la cadena en la aplicación en sí, sino confiar en un código de validación que se enviará a un servidor que usted controle. En el servidor puede verificar si es un "código de trampa" legítimo o no.


También hay URL para las solicitudes http que me gustaría ocultar.

Si su aplicación está haciendo la solicitud, no tiene sentido ocultar esto. Al ejecutar una aplicación como el violinista, el analizador http o uno de los muchos métodos gratuitos y fácilmente disponibles, se mostrará todo el tráfico que crea su aplicación.


¿Todos sus códigos secretos serán GUID o solo fue un ejemplo?

Quizás guarde su secreto como una guía binaria:

const GUID SecretGuid =
    { 0x4537774B, 0xCC80, 0x4eda, { 0x7A, 0x9E, 0xE7, 0x79, 0x91, 0xF5 } };

A continuación, convierta el guid suministrado de cadena a formato binario y compare las dos guías binarias.


Además de esos métodos, Chris menciona que también podría usar un algoritmo hash. Si todo lo que quiere hacer es verificar si se especificó la ID correcta, no es necesario que almacene la ID completa en su programa.

  • Cree un hash (MD5, SHA, etc.) de la cadena / contraseña / ID con la que desea comparar, tal vez agregue un valor 'sal'. Almacene esto en su programa
  • Cuando se ejecuta el programa, haga el mismo algoritmo en la cadena de entrada / contraseña / identificación y compare los dos hashes para ver si coinciden.

De esta forma, el texto real nunca se almacena en su programa y no pueden realizar una ingeniería inversa de su programa para averiguar cuál era el texto original, ya que los algoritmos hash son unidireccionales.


Este es el método que uso para este propósito. Primero, utilizo la herramienta Strings de Sysinternals para mostrar las cadenas en un EXE o DLL. A continuación, utilizo la siguiente pequeña herramienta (ver article ) para reemplazar estas cadenas con una matriz codificada de caracteres almacenados como una expresión aritmética: por ejemplo: en lugar de la cadena: "esto es una prueba" , colocaré el siguiente código: (que es generado automáticamente por esta herramienta )

WCHAR T1[28];
 T1[22] = 69;
 T1[15] = 121 - 17;
 T1[9] = L':' + -26;
 T1[12] = L't' - 1;
 T1[6] = 116 - 1;
 T1[17] = 117 - 12;
 T1[3] = 116 - 1;
 T1[14] = L'' - 3;
 T1[13] = L'w' - 3;
 T1[23] = 69;
 T1[26] = L'Y' + 3;
 T1[19] = 111 + 0;
 T1[21] = L'k' - 34;
 T1[27] = L'\\' - 8;
 T1[20] = L'B' + 32;
 T1[4] = 42 + -10;
 T1[25] = L'm' - 17;
 T1[16] = L'H' + 18;
 T1[18] = L'A' + 56;
 T1[24] = 68;
 T1[1] = 105 - 1;
 T1[11] = L'k' - 6;
 T1[10] = 66 + 50;
 T1[2] = 105;
 T1[0] = 117 - 1;
 T1[5] = L'k' - 2;
 T1[8] = 89 + 8;
 T1[7] = 32;

Hay muchas soluciones a este problema y ninguna de ellas (incluida la mía) es perfecta, sin embargo, hay formas de codificar, disfrazar y ocultar las cadenas sensibles. Por supuesto, puede encriptarlos y descifrarlos durante el tiempo de ejecución (consulte este artículo), pero me parece más importante hacer que estas cadenas desaparezcan entre los bits y bytes del archivo ejecutable y funciona. Después de ejecutar mi herramienta, no encontrará "esto es una prueba" en el archivo ejecutable.


La forma más simple es encriptarlos con algo trivial como xor o rot-13, y luego descifrarlos sobre la marcha cuando se usan. Eso eliminará la visión casual de ellos, pero no detendrá a nadie con mucha experiencia para revertir.


Lo mejor que puede hacer es codificar su contraseña u otra cadena que desee ocultar como matriz de caracteres. Por ejemplo:

std::string s1 = "Hello";   // This will show up in exe in hex editor
char* s2 = "World";   // this will show up in exe in hex editor
char s3[] = {'G', 'O', 'D'}; // this will not show up in exe in hex editor.

Si hay una cadena específica que no desea que la gente pueda ver, encripte y descifre en tiempo de ejecución.

Si no desea que las personas vean su GUID, entonces hágalo desde bytes, en lugar de construirlo a partir de una cadena:

const GUID SecretGuid = 
      { 0x4537774B, 0xCC80, 0x4eda, { 0x7A, 0x9E, 0xE7, 0x79, 0x91, 0xF5 } };




defensive-programming