Pregunta

Descubrí que es posible extraer las cadenas codificadas de un binario.
Por ejemplo, la vista de propiedades de Explorador de procesos 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:
alt text

Creo que es demasiado fácil encontrar las cuerdas.

Mis preguntas son:

  1. Cómo simplemente esconder cadena oculta1 o cadena oculta2 en el ejecutable?
  2. ¿Existe una forma más segura de usar "código de trampa" que con una información oculta oscura?
¿Fue útil?

Solución

Bienvenido a un mundo más amplio de programación defensiva.

Hay un par de opciones, pero creo que todos ellos 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 que puede almacenar el texto de alguna otra forma binaria (hex?).

  2. Puede cifrar las cadenas que se almacenan en su aplicación, y luego descifrarlos en tiempo de ejecución.

  3. Se puede dividir ellos a través de varios puntos de su código y reconstruir más tarde.

o alguna combinación de los mismos.

Tenga en cuenta, que algunos ataques van más allá de mirar el binaria real. A veces van a investigar el espacio de direcciones de memoria del programa mientras se está ejecutando. MS se le ocurrió algo que se llama un SecureString en .Net 2.0 . El propósito es mantener las cadenas cifradas mientras la aplicación se está ejecutando.

Una cuarta idea es no almacenar la cadena en la aplicación en sí, sino que se basan en un código de validación que se someterá a un servidor que controles. En el servidor puede verificar si se trata de un "código de trucos" de fiar o no.

Otros consejos

Hay muchas maneras a oscuras los datos en un archivo ejecutable. Otros aquí han publicado buenas soluciones - algunos más fuertes que otros. No voy a añadir a esa lista.

Ten en cuenta: es todo un juego del gato y el ratón:. Es imposible Garantía que nadie se enterará de su "secreto"

No importa cuánto cifrado u otros trucos que utiliza; no importa cuánto esfuerzo o dinero que puso en él. No importa cuántos tipos "NASA / MIT / CIA / NSA" están involucrados en ocultarlo.

Todo se reduce a la física simple:
Si fuera imposible para cualquier de usuario a sacar su secreto para el ejecutable y "Mostrar", entonces el equipo no sería capaz de mostrarla tampoco, y su programa no sería capaz de utilizar eso. Cualquier desarrollador moderadamente hábil con suficiente incentivo encontrará la manera de mostrar la secreta.

En el momento en que usted ha entregado su ejecutable a un usuario, tienen todo lo que necesitan para averiguar el secreto.

Lo mejor que puede esperar es que sea tan duro para descubrir el secreto que los beneficios que puede obtener de conocer el secreto convertirse no vale la pena.

Por lo tanto, está bien para tratar de ocultar los datos si es simplemente "no-bueno" para que sea pública, o si las consecuencias de que se convierta en pública sólo sería "inconveniente". Pero ni siquiera pensar de esconderse en su programa "la contraseña de su base de datos principal cliente", una clave privada, o algún otro secreto crítico. Usted simplemente no puede.

Si usted tiene información realmente crítico secreto que su programa de alguna manera necesita, pero nunca debe convertirse en información pública (como una clave privada), entonces usted tendrá que tener su charla programa a un servidor remoto bajo su control, aplicar la autenticación apropiada y controles de autorización (, es decir, asegurarse de que sólo las personas o equipos que cumplan son capaces de hacer la solicitud al servidor ), y tienen ese servidor a mantener el secreto y lo utilizan.

La forma más sencilla es cifrar con algo trivial como XOR o pudrirse-13, y luego descifrarlos sobre la marcha cuando se utilizan. Esto eliminará la visión ocasional de ellos, pero no se detendrá cualquier persona con mucha experiencia en la marcha atrás.

Además de los métodos de Chris menciona también se podría utilizar un algoritmo de hash. Si todo lo que quiere hacer es comprobar si se ha especificado el ID correcto que en realidad no necesita almacenar toda la ID en su programa.

  • Crear un hash (MD5, SHA, etc.) de la cadena / contraseña / ID desea comparar en contra, tal vez añadir un valor 'sal' a ella. Almacenar esto en su programa
  • Cuando se ejecuta el programa, haga lo mismo algoritmo en la cadena de entrada / contraseña / ID y comparar los dos valores hash para ver si coinciden.

De esta manera el texto real nunca se almacena en su programa y que no puede realizar ingeniería inversa a su programa para averiguar cuál era el texto original porque son los algoritmos hash de un solo sentido.

  

Hay direcciones URL para las solicitudes HTTP que me gustaría ocultar también.

Si su aplicación está realizando la petición, no hay punto de ocultar esto. Ejecución de una aplicación como violinista, analizador http, o uno de los otros métodos de forma gratuita y fácilmente disponibles docenas mostrará todo el tráfico que su aplicación está creando.

¿Todos sus códigos secretos ser GUID o era que sólo un ejemplo?

Tal vez guarde su secreto como un GUID binaria:

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

A continuación, convertir sus GUID de cadena en formato binario y comparar los dos guids binarios suministrados.

Si hay una cadena específica que no quiere que la gente sea capaz de ver, a continuación, cifrar y descifrar que en tiempo de ejecución.

Si no quieres que la gente vea a su GUID, entonces construirla a partir de bytes, en lugar de construido a partir de una cadena:

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

Lo mejor que puede hacer es codificar su contraseña u otra cadena que desea ocultar matriz como carbón. 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.

Este es el método que utilizo para este propósito.Primero, uso el Instrumentos de cuerda herramienta por Sistemas internos para mostrar las cadenas en un EXE o DLL.entonces uso el siguiente herramienta pequeña (ver artículo) 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 cifrarlos y descifrarlos durante el tiempo de ejecución (consulte este artículo), pero creo que es más importante hacer que estas cadenas desaparezcan entre los bits y bytes del archivo ejecutable y funcione.Después de ejecutar mi herramienta, no encontrará "esto es una prueba" en el archivo ejecutable.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top