¿Un ejecutable binario debe tener algunos componentes críticos de texto sin formato?

7

Cuando las compañías empaquetan ejecutables binarios, a menudo están encriptados, comprimidos, codificados y, de otro modo, creados para que su pirata informático no pueda abrir el programa en Notepad ++ y ver el código.

Sin embargo, en todos los que he visto, cada uno tiene algunos componentes de código críticos que no están encriptados, no están comprimidos y son legibles para los humanos. Aquí parece que la metodología es más "seguridad por ofuscación" al crear nombres de variables sin sentido e intentar hacer que el código sea lo más difícil de entender posible. Pero el hecho es que está allí en texto plano para ser descifrado.

¿Esto es por necesidad? Estaba pensando que podría tener ser así para que el sistema operativo tenga algo sensato de ejecutar (que luego tiene instrucciones para descomprimir / desencriptar el resto del ejecutable), pero no sé suficiente para estar seguro. ¿O hay alguna manera de encriptar un ejecutable completo sin tener componentes legibles por humanos?

    
pregunta asteri 07.02.2013 - 18:36
fuente

5 respuestas

8

En última instancia, la CPU ejecuta el código. Y la CPU espera instrucciones en "texto claro". Podría imaginar algún código de aplicación donde una pequeña parte inicial del ejecutable primero descifre el resto del código, pero esto tiene varios problemas:

  • Esto obliga a que todo el código vaya a la RAM en lugar de permanecer en el disco y se cargue a pedido, lo que implica un mayor consumo de RAM y tiempos de inicio más largos.
  • Esa rutina de "descifrado" no debe estar necesariamente encriptada.
  • La rutina de descifrado sabe todo lo necesario para descifrar el resto del código, por lo que el atacante puede descompilarlo y emularlo; no es realmente "descifrado", ya que no hay ninguna clave (o, de manera equivalente, la clave está incrustada en la rutina, que el atacante tiene bajo sus manos).

Experimentalmente, este tipo de cifrado no dificulta mucho a los atacantes, por lo que la opinión general es que "no vale la pena el esfuerzo". A menos que te encuentres en un escenario muy específico en el que el "atacante" es un autómata sin sentido que puede ser engañado por estos métodos de escondite - ese es el caso del virus, donde el "atacante" es El software antivirus.

Es posible un código realmente encriptado si la CPU está realizando el descifrado, internamente, con alguna administración de claves. Eso es lo que sucede en una consola PS3, por ejemplo.

    
respondido por el Thomas Pornin 07.02.2013 - 19:06
fuente
3

Estás hablando de dos componentes diferentes. Uno es el loader , que no es legible por humanos, pero debe ser legible por una máquina (por lo tanto, no encriptado) para ser ejecutado. Y este tiene para ser de esta manera, como dices: de lo contrario obtendrías una porción de datos no ejecutables.

Varios otros "componentes de texto simple" también pueden estar presentes, como el copyright, el manifiesto, la información del archivo, etc., que son legibles para el ser humano pero no son sensibles , es decir, el desarrollador no pudo No importa si eres capaz de leer su nombre. En realidad, probablemente lo prefiere así.

El cargador realiza varias tareas de verificación de autointegración, verificación de depuradores y cuáles no, y luego desencripta el ejecutable "verdadero" en la memoria.

El grado de cifrado del ejecutable depende del caso de uso. Por ejemplo, el binario solo puede mantener encriptadas ciertas rutinas críticas relacionadas con la protección de copia, la personalización o la marca; para que pueda abrir el archivo con un editor binario y ver todos los recursos, cadenas, cursores, etc., tan claro como el día.

O podría estar encriptado con un empaquetador / encriptador ejecutable "binario-agnóstico-por lo tanto, simplemente cifraré todo", en cuyo caso verá en texto sin formato las cadenas que pertenecen al código desencriptador , pero no los del ejecutable original. Por supuesto, los descifradores a menudo están más ofuscados para hacer que sea más difícil para un pirata informático reconocer el cifrador y obtener el descifrador adecuado (que, cuanto más difuso está el cifrador, es más probable que exista).

    
respondido por el LSerni 07.02.2013 - 18:56
fuente
1

En algún punto, un ejecutable debe parecerse a un ejecutable, de lo contrario, el sistema no sabrá qué hacer con él. Por lo general, esto implica un encabezado que indica que es un ejecutable (por ejemplo, el encabezado MZ en un Windows EXE), así como algunas estructuras que contienen punteros a varias referencias, como el punto de inicio para la ejecución, seguidas de un blob de datos binarios que es el cuerpo ejecutable del archivo.

Muchas veces también hay metadatos adjuntos que el sistema operativo utiliza como firmas de autenticidad y atributos como editor, versión, etc.

Como mínimo, necesita esos bits de encabezado y el cuerpo ejecutable. Ese cuerpo ejecutable necesitaría suficiente código de texto claro para ejecutar el mecanismo de descifrado / descompresión y luego ingresar el nuevo código para la ejecución.

    
respondido por el Steve 07.02.2013 - 18:53
fuente
1

La forma en que se compila un ejecutable, y lo que se ve en su interior varía bastante dependiendo de la plataforma y el lenguaje de programación involucrado. Los portons "cifrados codificados" no están realmente cifrados y codificados. Solo son datos no textuales. Es un código de máquina, que es ejecutado por el sistema operativo.

Por ejemplo, en Windows ... Si pudieras tener en tus manos una .dll creada en .NET, una comparada en VB6, una en C ++, probablemente encontrarías una gran diferencia en cuánto texto "es visible si lo abres en el bloc de notas.

.NET. Los archivos .dll o .exe no se compilan realmente en el código de la máquina, se compilan en la MSIL, una forma de bytecode que se compila en el código de la máquina mediante el tiempo de ejecución de .NET. Java bytecode funciona de la misma manera. Allí hay información que es muy fácil de descompilar, y para alguien que sabe cómo leer códigos de byte o msil, no es en absoluto absurdo.

Los archivos C ++, por otro lado, están compilados a código de máquina y son mucho menos difíciles de leer (si es que hay) abriéndolos en el Bloc de notas.

En otras palabras, no tiene nada que ver con cifrar o codificar, tiene que ver con cómo se prepara el archivo para que la PC lo lea y lo ejecute.

Cuando se trata del texto plano en los archivos, estás en lo correcto. Parece un riesgo para la seguridad, pero como se ha señalado docenas de veces en StackOverflow, en realidad no es posible evitar que la gente descompile / examine su código, especialmente si se hace en un lenguaje como .NET o Java. Debe asumir que su código está completamente abierto a una persona capacitada. ( Como se me indicó cuando hice una pregunta sobre cómo proteger los datos confidenciales en Windows aplicación construida con .NET )

En lo que respecta a la información que se muestra, eso está determinado en gran medida por el compilador y las herramientas utilizadas para crear el archivo .exe.

    
respondido por el David Stratton 07.02.2013 - 18:56
fuente
0

Hay algunas cosas diferentes que están sucediendo aquí. Hay dos formas principales de ejecutar el código en una computadora. La mayoría de los programas (aplicaciones nativas) se compilan a lo que se conoce como código de máquina. Es un conjunto de instrucciones no legibles para ser procesadas por la CPU. Este código de máquina puede incluir datos que deben cargarse en la memoria como parte de la ejecución. Es por esto que algunas cadenas de texto sin formato son visibles dentro del ejecutable. Estos son simplemente elementos de datos que se cargarán en una dirección de memoria a la que apuntará el código de máquina ilegible. Su punto es puramente para mostrarlo al usuario y / o usarlo como constantes para la comparación de cadenas. En realidad no son instrucciones en las que trabaja la computadora.

Este código de máquina se puede ejecutar a través de un desensamblador, sin embargo, el código que resulta es a menudo muy difícil de leer y está completamente sin documentar. Por lo tanto, es extremadamente raro que se coloque una protección adicional en un ejecutable de este tipo porque realmente no es necesario y dado que el código debe poder ser leído por la CPU con el tiempo, alguien que quisiera saber qué estaba pasando simplemente podría mire las instrucciones a medida que se decodifican para enviarlas al compilador.

El otro tipo principal de programa son los lenguajes que usan un intérprete, una máquina virtual o un tiempo de ejecución para ejecutar su comportamiento. Los idiomas como PHP, Java y .Net (C #, VB) se incluyen en esta categoría. Como en realidad no se compilan en código de máquina, se pueden "descompilar" mucho más fácilmente y obtener algo que está mucho más cerca del código original. Para hacer este proceso más complicado, existe una técnica conocida como ofuscación de código. No es encriptación, sino más bien, simplemente eliminando los identificadores que harían más fácil para alguien decir lo que está sucediendo y posiblemente alterando las rutas del código para que sea más difícil que el código se interprete de nuevo al código fuente original.

Hay algunas plataformas que intentan permitir que el código cifrado se ejecute utilizando un segmento de código nativo que maneja el descifrado, de modo que el código real que está utilizando el tiempo de ejecución solo está disponible inmediatamente antes y durante el uso, pero estos sistemas rara vez Se utiliza debido a la sobrecarga que introducen.

Si está viendo cadenas de texto sin formato en una imagen ejecutable, es casi seguro que las cadenas se carguen en la memoria como datos, ya que si el archivo ejecutable estaba comprimido o encriptado, las cadenas tampoco serían visibles.

    
respondido por el AJ Henderson 07.02.2013 - 19:51
fuente

Lea otras preguntas en las etiquetas