¿Cómo es posible utilizar la ejecución de código arbitrario para diseñar un juego dentro de un juego?

Trataré de darte una analogía aquí. Es un poco largo, pero lean y vean si tiene sentido.

Imagine que hay un interno en un gran edificio de oficinas. Comienza su día en su escritorio, que tiene una nota para decirle que vaya a ver al Gerente A, quien le dice que haga algunas tareas y luego lo envía al Gerente B para recibir más instrucciones.

El Gerente B le dice al interno que vaya al Almacén A para recuperar algunas fotos y llevarlas al Gerente C, quien trabaja un poco con ellas (por ejemplo, enviarlas por fax a alguien fuera del edificio de oficinas).

El Gerente C luego le dice al interno que vaya a la sala de correo para recuperar algo de correo y llevarlo al Gerente C, quien luego le da más instrucciones al interno en función del correo recuperado de la sala de correo.

Esto continúa una y otra vez, enviando al interno entre muchos Gerentes, tomando órdenes de ellos, hasta que la oficina está cerrada y todos se van a casa. Cuando la oficina abre al día siguiente, el interno hace lo mismo una y otra vez.


La computadora ejecuta el código de manera similar. Piense en toda la computadora como el edificio de oficinas vacío. Cuando un juego se carga en la memoria de la computadora, es como colocar a todos los Gerentes en todas las diferentes oficinas y todos los documentos en los diferentes almacenes.

Una vez que la computadora comienza a ejecutar el juego, mantiene un “puntero de ejecución”, al igual que el interno. Va de una oficina a otra, siguiendo de cerca cada una de las instrucciones del Gerente.

A veces, se le puede decir al puntero que obtenga algunos datos del juego (por ejemplo, del Almacén) de la memoria del juego. Pero el puntero solo debe transportar esos datos y no hacer nada con ellos. Después de todo, sería extraño recibir instrucciones de algunas “imágenes” en lugar de un Gerente, ¿verdad?

A veces, el puntero puede obtener entradas del controlador del juego del usuario (por ejemplo, de la sala de correo) y enviar datos de entrada a otra línea de código para procesar. Pero el puntero solo debe transportar estos datos de entrada y no hacer nada con ellos. Después de todo, sería una mala idea recibir instrucciones directamente de alguien que está enviando correo a la oficina, ¿verdad?


Ahora volviendo a la falla de TAS y Super Mario Bros.

En cierto sentido, los jugadores encontraron una manera de desencadenar una falla en la que un Gerente enviaría al interno a un Almacén que no existe en el edificio de oficinas. Después de una secuencia cuidadosamente ordenada de “direcciones incorrectas” alrededor del edificio de oficinas, el interno termina yendo a la sala de correo para recibir la siguiente instrucción, pensando que en realidad es la oficina de un gerente.

Ahora el usuario puede ingresar datos de control arbitrarios y la computadora ejecutará esos datos como si fueran código de juego para ser ejecutado. Así es como los speedrunners pueden lograr la “ejecución de código arbitrario”. Los hackers a menudo utilizan tipos de exploits similares para obtener acceso a servidores informáticos seguros.


Pero ingresar el código de instrucción para un juego completo de pong o serpiente implica una gran cantidad de datos cuidadosamente organizados. Por lo que entiendo, resuelven la lógica del juego de pong y serpiente por separado del juego Super Mario Bros., programando directamente con el código de ensamblaje de SNES. Luego utilizaron una herramienta automatizada para “escribir el código de instrucción” a través del controlador de juego simulado, una vez que se alcanza el estado de ejecución de código arbitrario.

Y ahí lo tiene: ¡un increíble esfuerzo grupal que involucra ingeniería, imaginación y determinación!

Antes de explicarlo, te voy a dar una forma diferente de pensarlo:

Hay un trabajador en un edificio. El trabajador tiene una gran hoja de papel que le dice qué hacer. Esa hoja de papel también tiene diferentes cosas, como cuánto dinero hay en un banco local y sus ingresos totales en la última semana. El trabajador lee el trozo de papel de izquierda a derecha, pero a veces dice en el trozo de papel ir a un lugar diferente y leer desde allí. Normalmente, todo funciona sin problemas y no sucede nada involuntario.

Sin embargo, hay un problema con este sistema: problemas técnicos. Si ocurre una falla, podría colocar algún código en algún lugar que diga ir a una ubicación que no sea comandos (por lo tanto, tal vez algunos datos que se suponía que debían usar en ciertas situaciones). Una vez que esto suceda, comenzarán a hacer cosas que no debían hacer.

En un juego, en lugar de un trabajador, hay un contador de programa, que lee y ejecuta ciegamente cualquier código en el que aterriza y luego continúa. La ejecución de código arbitrario se produce cuando comienza a leer datos de archivos guardados como código.

En cuanto a cómo saben qué bits de memoria modificar, supongo que son solo un grupo de personas realmente inteligentes.

En cuanto a la lógica, simplemente pusieron algunos datos en lugares e hicieron algo y comenzó. No soy realmente un experto en este tema, y ​​la mayor parte de mi comprensión proviene de un artículo XD de Bulbapedia.