2009-02-05 15 views
46

¿Existe algún uso real para código de auto modificación?¿Cuáles son los usos del código de auto modificación?

Sé que se pueden usar para construir gusanos/virus, pero me preguntaba si hay alguna buena razón para que un programador tenga que usar el código de auto modificación.

¿Alguna idea? Las situaciones hipotéticas también son bienvenidas.

Respuesta

46

Resulta que la entrada de Wikipedia sobre "self-modifying code" tiene una gran lista:

optimización
  1. semiautomática de un bucle depende del estado.
  2. código de tiempo de ejecución generación, o especialización de un algoritmo en tiempo de ejecución o tiempo de carga (que es popular, por ejemplo, en el dominio de gráficos en tiempo real), tal como un código general la preparación de utilidad tipo para llevar a cabo la comparación de clave descrita en una invocación específica .
  3. Alteración del estado en línea de un objeto o simulación de la construcción de cierres de alto nivel .
  4. parcheo de dirección de llamada de subprograma a, como se hace normalmente en tiempo de carga de bibliotecas dinámicas, o, en cada invocación parches referencias internas de la subrutina a sus parámetros con el fin de utilizar sus direcciones reales. Si esto se considera 'código de auto modificación' o no, es un caso de terminología.
  5. Sistemas de computación evolutiva como la programación genética.
  6. Ocultando el código a previene la ingeniería inversa, como a través del uso de un desensamblador 0 depurador .
  7. Ocultar el código evadir la detección por el software de escaneo de virus/spyware y similares.
  8. Relleno 100% de la memoria (en algunas arquitecturas) con un patrón de rodadura de códigos de operación que se repiten, a borrado todos los programas y datos o a marcar a fuego hardware.
  9. Compresión del código para descomprimir y ejecutar en tiempo de ejecución, por ejemplo, cuando la memoria o el espacio en disco es limitado.
  10. Algunos conjuntos de instrucciones muy limitados no dejan otra opción que usar el código de auto-modificación a para lograr cierta funcionalidad de .Por ejemplo, una "Uno del conjunto de instrucciones del ordenador" máquina que utiliza sólo el de resta y ramas-si-negativas "instrucción" no puede hacer una copia indirecta (algo así como el equivalente de "* a = ** b "en el lenguaje de programación C ) sin usar el código de auto modificación .
  11. instrucciones Alterar para tolerancia a fallos

En el punto acerca de frustrar a los piratas informáticos que utilizan auto-modificable código:

A lo largo de varias actualizaciones de firmware, DirectTV ensamblados lentamente un programa en su tarjeta inteligente para destruir tarjetas que han sido pirateadas para recibir ilegalmente canales no pagados. Consulte el artículo Jeff's Coding Horror en el Black Sunday Hack para obtener más información.

+0

DirectTV's Black Sunday Hack? – Brian

+0

¡Eso es todo! ¡Gracias! –

+0

Gracias por eso Zach !!! – Niyaz

4

La vinculación dinámica es una especie de autoformación (parcheado de ubicaciones de salto absolutas y/o relativas) ... eso normalmente lo hace el cargador de programas de O/S.

12

que he visto código mutante utilizada para:

  1. optimización de la velocidad, haciendo que el programa de escribir más código por sí mismo sobre la marcha

  2. obsfucation, hacer ingeniería inversa mucho más difícil

+0

Históricamente, esto era bastante popular para los mecanismos de protección contra copia en el software del juego. – ConcernedOfTunbridgeWells

+0

de hecho, eso es exactamente donde lo he visto :) – Alnitak

+0

que por cierto se requería en algunos juegos antiguos de micro de 8 bits (BBC) para que se ejecutaran desde el disco en lugar de la cinta de casete. – Alnitak

3

Neural networks son un tipo de código de auto-modificación.

Luego hay evolutionary algorithms que se modifican.

+1

No estoy seguro de que las redes neuronales modifiquen el código. Nunca lo supe. http://www.hoozi.com/Articles/Neural-Networks-Artificial-Neuron.htm – Niyaz

+0

Creo que cualquier cambio que deba hacerse a la estructura de una red neuronal se puede hacer en la parte de datos. ¿Por qué debería modificar el código? – Niyaz

+2

redes neuronales son _no_ código de auto modificación. no son más que transformaciones complejas no lineales cuyos pesos están determinados por el entrenamiento. – Alnitak

11

En épocas anteriores en las que la RAM era limitada, se usaba código de auto modificación para ahorrar memoria. Hoy en día, por ejemplo, las utilidades de compresión de aplicaciones como UPX se usan para descomprimir/modificar el propio código después de cargar una imagen comprimida de la aplicación.

+0

Pensé que estos compresores binarios solo comprimidos en el disco, y descomprimidos cuando se cargan en la memoria? También leí una vez que, dado que se descomprimen al cargarse en la memoria, no se pueden paginar en el disco, por lo que consumen más RAM. ¿No es este el caso? –

+1

Los archivos ejecutables empaquetados tienen una aplicación "bootstrap" que se carga en la memoria y se inicia allí. Esto carga los datos comprimidos, los descomprime y agrega las instrucciones descomprimidas a su propio código. Cuando termina la descompresión, este código se inicia. La paginación ocurre como de costumbre. – Kosi2801

+0

JavaScript autodescomprimible se utiliza abundantemente en páginas web. –

1

Las aplicaciones que implementan sus propios lenguajes de scripting a menudo lo hacen. Por ejemplo, los servidores de bases de datos a menudo compilan procedimientos almacenados (o consultas) de esta manera.

3

LOL - que he escrito código mutante en dos ocasiones:

  1. cuando el primer lenguaje ensamblador de aprendizaje, antes de comprender acceso indexado indirecta
  2. accidentalmente, como errores de puntero en lenguaje ensamblador y C

me imagino que puede haber situaciones en las que el código de auto modificación sería más eficiente que las alternativas, pero no se me ocurre nada obvio. En general, esto es algo que hay que evitar: depurar pesadillas, etc., a menos que intentes ofuscar deliberadamente como se mencionó anteriormente.

6

Porque el Commodore 64 no tiene muchos registros y tiene un procesador de 1Mhz. Cuando necesite leer una dirección de memoria compensada por un valor, es más fácil modificar la fuente.

@Reader: 
LDA $C000 
STA $D020 
INC Reader+1 
JMP Reader 

Esa fue la última vez que escribí código mutante de todos modos :-)

5

Por muchas razones. Fuera de la cabeza:

  • Runtime clase de construcción y meta programación. Por ejemplo, tener una fábrica de clases que toma una conexión con una tabla SQL y genera una clase de cliente especializada para esa tabla (con accesodores para las columnas, métodos de búsqueda, etc.).

  • Luego, por supuesto, está el famoso ejemplo de bitblt y los análogos de regexp.

  • dinámicamente optimizando basan en la información RT A la JITs rastreo

  • Subtipo especialización de estilo ada funciones genéricas en un entorno aumente.

- MarkusQ

4

Inteligencia Artificial?

0

La generación de código dinámico en SwiftShader es una forma de código de auto modificación que le permite implementar Direct3D 9 de manera eficiente en la CPU.

5

Porque es realmente genial, y a veces eso es motivo suficiente.

+0

sí/se siente/genial, pero ¿qué - racionalmente - lo hace genial? – Rabarberski

+1

¿No le parece genial refrescarlo? –

6

Los lenguajes de ensamblaje de la era de los años 60 usaban código de auto-modificación para implementar llamadas a funciones sin una pila.

Knuth, v1, p.182 1ed:

MAX100 STJ EXIT ;Subroutine linkage 
     ENT3 100 ;M1. Initialize 
     JMP 2F 
1H  CMPA X,3 ;M3. Compare 
     JGE *+3 
2H  ENT2 0,3 ;M4. Change m 
     LDA X,3 ;(New maximum found) 
     DEC3 1  ;M5. Decrease k 
     J3P 1B  ;M2. All tested? 
EXIT JMP *  ;Return to main program 

En un programa más amplio que contiene esta codificación como una subrutina, la única instrucción "JMP Max100" causaría registro A que se establece en la corriente valor máximo de las ubicaciones X + 1 a X + 100, y la posición del máximo aparecería en rI2. El enlace de subrutina en este caso se logra mediante las instrucciones "MAX100 STJ EXIT" y, más tarde, "EXIT JMP *". Debido a la forma en que funciona el registro J, la instrucción de salida saltará a la ubicación siguiente al lugar donde se hizo la referencia original a MAX100.

Editar: Puede ser difícil ver lo que está pasando, incluso con la breve explicación aquí. En la línea MAX100 STJ EXIT, MAX100 es una etiqueta para la instrucción (y por lo tanto para el procedimiento en su conjunto), STJ medios almacenar el registro de salto (en el que acabamos de de), EXIT significa la posición de memoria etiqueta 'EXIT' es el objetivo de la TIENDA. EXIT, vemos más adelante es la etiqueta de la última instrucción. ¡Así que está sobrescribiendo el código! Sin embargo, muchas instrucciones (incluido STJ aquí) sobrescriben implícitamente solo la parte de operando de la palabra de instrucción. Por lo tanto, el JMP permanece intacto, y el * es un token ficticio, ya que no tiene nada significativo colocar, solo se sobrescribe.


código mutante también se utiliza en el direccionamiento indirecto por registro no está disponible, y sin embargo la dirección que necesita está sentado allí mismo en el registro. PDP-1 LISP:

dap .+1 ;deposit address part of accumulator in (IP+1) 
lac xy ;load accumulator with (ADDRESS) [xy is a dummy symbol, just like * above] 

Estas dos instrucciones realizan ACC := (ACC) modificando el operando de la instrucción de carga.

Las modificaciones como estas son relativamente seguras, y en las arquitecturas antiguas, son necesarias.

Cuestiones relacionadas