assembly - pensamiento - lecturas revista ethos gubernamental
¿Qué es una cueva de código y hay algún uso legítimo para una? (9)
Desconocido con el término pero los mecanismos de hot-patching podrían usar espacio reservado para almacenar parches de código. Se engancha en la función defectuosa y la redirige a la nueva función mejorada. Se puede hacer sobre la marcha sin quitar el equipo crítico (interruptores de telecomunicaciones grandes).
Encontré esta palabra por primera vez en la pregunta de StackOverflow " C # Teórico: Escribir un JMP en una cueva de códigos en asm ". Veo que según Wiktionary , una cueva del código es:
un bloque de memoria no utilizado que alguien, generalmente un cracker de software, puede usar para inyectar código de programación personalizado para modificar el comportamiento de un programa.
¿Encontré la definición correcta? Si es así, ¿hay algún uso legítimo para una cueva de código?
El código de auto-modificación no se debe considerar a la ligera, pero a veces puede traer grandes ganancias de rendimiento. Si ha estado programando durante mucho tiempo, probablemente lo haya usado sin darse cuenta.
Antes del uso generalizado de la 486 y superior, muchas PC no incluían soporte flotante de hardware. Esto dejó a las personas escribiendo programas que involucran el punto flotante con un dilema. Si compilaran su programa para usar instrucciones de coma flotante en línea, se ejecutaría rápidamente en una máquina con un procesador de coma flotante, y no funcionaría en máquinas sin una. Si compilaran su programa con emulación de punto flotante de software, se ejecutaría en todas las máquinas, pero lentamente incluso en máquinas con hardware de coma flotante.
Muchas bibliotecas de compiladores usaron un truco interesante con el código de auto modificación. El comportamiento predeterminado era poner una instrucción de trampa donde se necesitaba una operación de punto flotante. El manejador de trampa emularía la instrucción en el software, o si detectaba que se estaba ejecutando en una máquina con hardware de coma flotante, modificaría el código reemplazando la instrucción de captura con la instrucción de coma flotante de hardware apropiada y la ejecutaría. El resultado fue un software que se ejecutaba en todas las máquinas y funcionaba casi igual de rápido en una máquina con hardware de punto flotante como si el código se hubiera compilado para usar hardware de coma flotante directamente (ya que la mayoría de las operaciones intensivas de punto flotante ocurren en bucles que se ejecutan muchas veces )
Esa me parece la definición correcta.
En cuanto a un uso legítimo, permítanme decir esto: no lo hagan a menos que simplemente estén experimentando por el simple hecho de experimentar y estén dispuestos a aceptar las consecuencias.
No hay forma de que este tipo de cosas entre en el código de producción:
- Es un enorme problema potencial de seguridad. Si es posible inyectar código en la memoria y luego ejecutarlo, un atacante malintencionado teóricamente puede hacer, bueno, lo que quiera.
- Es una pesadilla de mantenimiento de código y una pesadilla de depuración. Si el código que termina ejecutándose puede cambiar durante el tiempo de ejecución, es casi imposible rastrear errores y errores.
La forma en que se describe here me recuerda a los patchpoints , un uso legítimo.
Los compiladores suelen crear cuevas de código para la alignment y, a menudo, se ubican entre funciones en grandes cantidades. También debería haber cuevas de código entre estructuras y saltos (en algunas arquitecturas), pero generalmente no en cantidades significativas.
También puede buscar un bloque de memoria con cero, pero no hay garantía de que el programa no los use.
Supongo que teóricamente, si pierdes tu código fuente, puedes aplicarle un parche a tu programa con errores, y tu programa no aumentará de tamaño.
Editar
Para aquellos de ustedes que sugieren cuevas de código son solo para código generado en tiempo de ejecución: es una definición incompleta. Muchas veces escribí una estructura de datos en una "cueva de códigos" y punteros actualizados para señalar allí, y sospecho que no soy la única persona que lo hace.
Se puede usar para inyectar código en tiempo de ejecución. Se puede usar para escribir código de auto modificación en lenguajes estáticos asumiendo que el sistema operativo le permite (bit NX no establecido, etc.). Hay usos para eso, pero no es algo en lo que deberías pensar en tu aplicación comercial típica.
Uno podría querer crear intencionalmente una cueva de código como parte del uso del código de modificación automática .
Suponiendo, por supuesto, que ese es un loco.
algunos usos legítimos : parchear binarios OS activos sin un reinicio (MS hace esto), conectando funcionalidad de SO de bajo nivel (sistema de archivos, red) para firewall y antivirus, extendiendo una aplicación cuando no tienes código fuente (como raspar llamadas de bajo nivel del sistema operativo) Dibujar texto para que pueda leerlos en voz alta para personas ciegas)
Los he usado, aunque nunca había escuchado el código del término cueva hasta el día de hoy. La definición de Wiktionary sugiere que una cueva de código es algo que el cracker encuentra en el ejecutable que él o ella está tratando de descifrar. La pregunta que citas no la usa de esa manera. En cambio, sugiere que el código de la cueva se está asignando con VirtualAllocEx
para crear un nuevo bloque de memoria en el proceso de destino. Eso elimina la necesidad de buscar espacio no utilizado en el objetivo, y garantiza que tendrá suficiente espacio para poner todo su nuevo código.
En última instancia, creo que una "cueva de códigos" es solo un lugar para almacenar el código generado en tiempo de ejecución . No tiene que haber ningún propósito nefasto para ese código. Y en ese punto, la pregunta de qué es una cueva de código se vuelve completamente carente de interés. Las partes interesantes son las razones que existen para generar código en tiempo de ejecución y las técnicas que existen para garantizar que el nuevo código se ejecute cuando lo desee.