Speedran Legend of Zelda manipulando la memoria del juego
La primera parte de Legend of Zelda es un clásico inmortal. Un jugador normal necesita un par de días para completarlo, pero para los corredores de velocidad más experimentados, esta es una pregunta de media hora. Sin embargo, el error muy confuso y complejo abierto por Sockfolder permite al usuario ejecutar código arbitrario directamente desde el juego para completar el juego en menos de tres minutos.Brevemente, esto sucede de la siguiente manera:- Ingrese el código en la pantalla de ingreso de nombre.
- Entramos en la segunda mazmorra, tomamos el silbato.
- Pasamos al cementerio, llamamos a diez fantasmas.
- Esperamos las condiciones necesarias, ponemos el juego en pausa cuando las criaturas están en ciertos lugares.
- Tómese un descanso, presione A y B al mismo tiempo, ¡y eso es todo!
Sí, esto es asombroso. Ahora echemos un vistazo más de cerca a lo que está sucediendo en el juego y cómo se ejecuta este increíble error de Legend of Zelda.
Cómo causar un error
Entonces, primero ingresamos el código en la pantalla de ingreso de nombre. Los nombres de los archivos se almacenan en la memoria y cada carácter corresponde a un byte específico en la memoria. Damos nombres extraños a los archivos, porque de hecho escribimos los bytes necesarios en la memoria, que luego se convertirá en código ensamblador. Solo hay dos limitaciones:- podemos trabajar con solo tres archivos, es decir, el programa puede contener solo 3 * 8 caracteres = 24 bytes;
- necesitamos ingresar como los primeros cinco caracteres de uno de los archivos ZELDA si queremos comenzar con la segunda búsqueda.
Necesitamos comenzar con la segunda búsqueda por una razón que explicaré más adelante. Llamamos al primer archivo ZELDA porque este nombre es el más adecuado. Ahora comencemos el juego. Antes de llegar al cementerio, nuestro comportamiento prácticamente no difiere del juego habitual. Lo principal que debemos hacer es tratar de no morir dos veces. Por "morir" se entiende tanto la muerte misma como la frecuente transición al menú. Comprenderá por qué esto es así, a partir de más explicaciones.
Después de recibir el silbato, vamos a la pantalla de este cementerio para completar el error. El error se activa aquí, porque cuando se usa el silbato, se crea un objeto a partir de la lápida, que abre una escalera oculta. Esto es necesario para la aparición de un error. Y todo esto se debe a las limitaciones de los sprites. En Legend of Zelda, la pantalla puede tener hasta 11 sprites a la vez. Si intentas crear un 12º sprite, el juego no te permitirá hacer esto. Para reproducir el error, rompemos el límite de desbordamiento y creamos el duodécimo sprite.
Cuando creas el objeto silbato, el juego se olvida de comprobar cuántos sprites había en la pantalla antes. Por lo tanto, cuando creamos el número máximo de sprites, el sprite se crea fuera de la tabla de sprites, la memoria se sobrescribe y se produce un estado inesperado.Hay un pequeño fragmento en la memoria que comienza en el desplazamiento 350 que almacena los identificadores de once sprites. Se crea un sprite cuando se carga la pantalla, comenzando desde una posición con el desplazamiento más pequeño posible del sprite. Esto significa que los sprites están buscando una posición con un desplazamiento mínimo, comenzando en el desplazamiento 350 y más allá. Cuando se va a crear un sprite, el juego busca un valor vacío en la tabla de sprites para reemplazarlo con el identificador de sprite, y así lo crea. A diferencia de crear sprites al cargar la pantalla, al intentar crear un sprite, el juego busca una posición con un desplazamiento máximo para el sprite. Esto significa que primero verifica si es posible crear un sprite en la posición 10 (0A). Si no, ella verifica la posición 9 (09), es decir compensar 359, y así sucesivamente. Si todas las posiciones de los sprites están ocupadas, entonces el juego "se rinde" y no crea un sprite.
Sin embargo, los desarrolladores se olvidaron de realizar controles de bordes para que el juego pudiera "darse por vencido" al intentar crear un objeto "silbato", y el juego continúa buscando bytes con el valor 00 en un lugar fuera de la tabla de sprites para anotar el identificador de objeto allí. Pero, ¿dónde busca primero este significado? De hecho, esta tabla es parte de una matriz más grande que almacena información sobre sprites. Cuando el silbato encuentra un lugar para crear al comienzo de la tabla, comienza a buscar posiciones con el valor 00 desde el final de la matriz.En la pantalla del cementerio, este fragmento de la matriz contiene información sobre el estado actual de las acciones fantasma. Ahora hablemos de los estados de acción de los fantasmas. Los fantasmas creados en el cementerio se mueven al azar. Esto se debe a que sus acciones están controladas por un comportamiento determinado por su estado de acción. Estos estados de acción pueden tener cualquier valor de 0 (00) a 5 (05), dependiendo de las acciones del fantasma. Están escritos al final de una matriz que contiene información sobre sprites.En general, todos estos estados de acción corresponden a una posición en la tabla de funciones que define las acciones de los fantasmas. Como los estados solo pueden tener 6 valores, la tabla tiene el tamaño necesario para almacenar las seis acciones. Aquí, el estado de acción 0 (00) corresponde a la aceleración del fantasma. Esto es importante, porque cuando el silbato comienza a buscar un lugar para crear su sprite, llenará la primera posición encontrada en la memoria con el valor 00. La aceleración fantasma corresponde a la acción 0, registrada en el código con el valor 00, por lo que el juego lo considera una posición vacía y le escribe el identificador. silbato 5E.
Luego, el juego intenta ejecutar el código en la posición 5E de la tabla, pero dado que la tabla contiene solo valores hasta 05, el juego ejecuta datos "basura" como un código mucho más allá de la tabla. Si haces todo bien, los datos "basura" nos llevarán al código que grabamos con los símbolos de archivo, el juego irá a Zelda y lo revisaremos.Sin embargo, para que el error funcione, debemos dañar el tercer estado de la acción en la tabla. Por lo tanto, el tercer fantasma creado debe acelerarse, y todos los fantasmas posteriores deben realizar otras acciones (cuyo código no es igual a 00). Esta es información importante. Ahora veamos qué sucede cuando ejecutamos un error.Ejecución de errores
Si hicimos todo bien, el juego intenta ejecutar los datos en la posición 5E de la tabla. Comienza a leerse como un código de datos que comienza en el desplazamiento 602. La información asociada con el estado de la acción Enlace se almacena en la memoria en el desplazamiento 602 y 603, para que podamos controlarla. Cuando Link está de pie, los valores en las compensaciones 602 y 603 serán 00. Pero cuando presionamos el botón B para usar el silbato, el valor en 602 será 10, y cuando presionamos A para usar la espada, el valor en 603 será 01.
Por lo tanto, cuando presionamos ambos botones simultáneamente, los datos vecinos serán 10 01. El juego interpreta estos datos como un comando de rama BPL para ir a compensar 605 y ejecutar los datos como código. Los valores de 605 y 606 serán 00 si nuestra salud no es demasiado baja y 40 si nuestra salud es baja. Para pasar rápidamente el juego, estos valores deben ser iguales a 00, por lo que debe intentar mantener la salud hasta que se complete el error. El valor 00 corresponde a la instrucción BRK (pausa). Como no hace nada aquí, necesitamos que los valores sean 00 y que el juego continúe ejecutando el código.
Como usamos la espada, el juego continuará ejecutando instrucciones en el próximo byte impar. La siguiente instrucción, que no es BRK, está en el desplazamiento 08, pero como usamos la espada, el juego salta sobre ella y ejecuta el código en 09 y 0A. El valor en el byte 09 siempre es 10, lo que significa que nuevamente estamos tratando con la instrucción de rama BPL. Los bytes en el desplazamiento 623 (62E) se relacionan con la música. Ella trata de aumentar el proceso de reproducción de música, pero a veces salta a valores más bajos.Esto significa que para completar el error necesitamos aplicarlo a una pieza musical específica. Si el valor es pequeño, tenemos la oportunidad de saltar en la memoria a un área con valores que cambian significativamente. Cambian tan al azar que no podemos controlarlos en tiempo real para recibir instrucciones que el juego debe seguir. Por lo tanto, es probable que la transición aquí conduzca a un bloqueo del juego.
Sin embargo, después de estos datos caóticos, hay un área de datos seguros. Por lo tanto, intentaremos saltar allí. Necesitamos más datos en el 60A para omitir con precisión el área insegura y llegar a los datos permanentes y seguros. Si fuimos allí, entonces todo está en orden. Pero en la compensación 630, hay un contador para las muertes de Link. Si Link murió dos veces, este valor será 02, que forma una instrucción y detiene el juego. Por eso es importante que no mueras dos veces. Entonces, como resultado, pasamos al desplazamiento 638, que es el comienzo de la tabla que almacena los nombres de los archivos. Si llegamos aquí, el juego ejecutará el código que ingresamos en la pantalla del archivo. Y aquí comienza ...Código
Los nombres de los archivos se almacenan en la memoria en orden. Esto significa que los primeros bytes que ejecutamos son un archivo llamado ZELDA. Afortunadamente, el código ejecutado por estos bytes es seguro, por lo que podemos pasar al resto. Como el nombre ZELDA no es importante, veamos qué hace el resto del código. Primero, ejecutamos tres comandos PLP (extraer de la pila, extraer de la pila). Cuando llamamos a una función, escribe dos valores en la pila. Estos valores corresponden a dónde estaba en el código cuando ejecutó la función. Entonces, el juego puede averiguar dónde regresar después de realizar la función.Comenzamos extrayendo tres valores de la pila, y luego realizamos la función de retorno. Hacemos esto para volver al lugar en el que estábamos antes de la ejecución del error. De lo contrario, el juego no terminará de ejecutar los datos como un código y se congelará como resultado. Pero antes de llegar al código que daña la memoria y termina el juego, necesitamos hablar de algunos valores más.Los valores en el desplazamiento de memoria 10 corresponden al número del mundo en el que estamos. Si estamos en el mundo por encima del suelo, el valor es 00. Para la primera mazmorra, el valor es 01, para la segunda - 02, y así sucesivamente. Dado que Zelda está en la novena mazmorra, necesitamos que este valor sea 09. Sin embargo, estamos realizando un error en el mundo por encima del suelo y el valor es 00. Por lo tanto, debemos encontrar una manera de equipararlo a 09. El valor en el desplazamiento 11 corresponde a algunos datos sobre el estado del juego. Cuando se carga el juego, el valor es 00, cuando el juego no se carga - 01. Necesitamos cargar la novena mazmorra, por lo que este valor debería ser 00.El valor en el desplazamiento 12 corresponde a alguna parte del estado. Cuando se carga la pantalla, el valor suele ser 02, cuando no se carga, suele ser 05. Dado que queremos cargar la mazmorra, este valor debería ser 02.El último valor que queremos cambiar corresponde a la búsqueda en la que estamos. El valor en el desplazamiento 62D corresponde a la primera o segunda búsqueda, y tiene el valor 00 o 01. Comenzamos desde la segunda búsqueda, pero queremos terminar en la primera búsqueda, porque así es como confundimos el juego. Por lo tanto, necesitamos cambiar este valor a 00. Esto nos colocará en un extraño híbrido de la primera y segunda misiones. Necesitamos este estado híbrido para ejecutar código para un propósito específico. Lo veremos cuando expliquemos lo que hace el código.
Bueno, nos fijamos objetivos, pasemos al código. Primero, tenemos la función LSR (desplazamiento lógico a la derecha) para el desplazamiento 11. Esta función divide el valor a la mitad y escribe el resto en el carry. 11 es un lugar en la memoria que almacena el valor correspondiente al estado del juego, y antes de esta instrucción su valor es 01. Cuando dividimos entre dos, obtenemos 00 con el resto 01, ya que la división es entera. En el desplazamiento 11, se escribe el valor 00, y en la transferencia, 01.Luego tenemos la función ROX para el desplazamiento 0D (girar a la izquierda, a la izquierda) con el índice X. Dado que sobrescribimos el estado de acción del tercer fantasma que creamos, X es igual a tres. 0D + X es 0D + 03, que es hexadecimal 10. Por lo tanto, esta función gira a la izquierda en el desplazamiento 10. Esta función multiplica el valor en el desplazamiento 10 por 2 y agrega a la separación silábica. El valor comienza en 0. Cero veces 2 es igual a 0 y 0 + 1 es igual a 1, por lo que el valor se escribe en el desplazamiento 10.Ahora la operación ROX se repite nuevamente para compensar 0D con el índice X. El valor de X no ha cambiado, sigue siendo tres, por lo tanto, este es otro giro a la izquierda en el desplazamiento 10. 1 * 2 = 2, y dado que ya hemos usado la transferencia, su valor es 0. 2 + 0 = 2, por lo que el valor 2 se escribe en el desplazamiento 2.A continuación, tenemos la tercera operación ROX para offset 0D. 2 * 2 = 4 y 4 + 0 = 4, por lo que el valor se escribe en el desplazamiento 10.La siguiente instrucción es LSR en el desplazamiento 12. Comenzamos con el valor 5, por lo que dividir por dos nos da el resto 1. 2 se escribe en el desplazamiento 12 , y 1 - en la transferencia.Luego, el último ROX gira a la izquierda en el desplazamiento 10. 4 * 2 = 8. El valor de transferencia es 1, lo agregamos al producto, obteniendo 9.La última instrucción antes de regresar es un desplazamiento lógico a la derecha en el desplazamiento 62D. El valor aquí es 1, porque estamos en la segunda búsqueda. Y como dividimos entre 2, el valor será igual a 0. Así que entramos en el modo de búsqueda híbrido.Ahora realizamos la función de retorno y el juego actualiza los valores de su estado con los valores registrados en nuestro código. Esto completa el error y entramos en la habitación de Zelda. Llegamos allí porque la búsqueda híbrida confunde el juego. Ella no sabe exactamente dónde poner a Link. Y así nos encontramos en la habitación de Zelda, después de haber pasado el juego.
Espero que esto te ayude a comprender lo que sucede dentro del juego Legend of Zelda cuando ejecutas código arbitrario y ejecutas un error rápido en el juego.Source: https://habr.com/ru/post/es398171/
All Articles