Registrarse

[General] Ensamblación estructural y perspectivas de futuro

Estado
Cerrado para nuevas respuestas.

Mikelan98

WaH used to be a bigger place...

Antes de nada, aviso que en este thread no voy a publicar nada que haya descubierto ni nada por el estilo. Simplemente quiero dar visibilidad a un aspecto del ASM que no he visto a nadie aprovechar, y que sin embargo considero que tiene mucho potencial y que varios deberíamos empezar a investigar.​

Durante todos estos años, los que nos hemos atrevido con ASM sólo nos hemos preocupado de ir localizando las rutinas que nos interesaban, y estudiarlas a fondo para ver qué hacían y cómo modificarlas. A eso le llamo yo ensamblación funcional. Es lo que siempre se ha hecho, y naturalmente siempre ha funcionado porque no había otra alternativa para descubrir nuevas cosas.

Sin embargo, en la época en la que estamos, en la que el trabajo a pequeña escala está siendo cada vez más relegado y se aplican técnicas de big data a casi todos los campos, podemos inspirarnos en los programas que se usan hoy en día para investigar cosas similares. Esto nos permite ampliar el horizonte, y plantearnos nuevos problemas (y nuevas soluciones) que antes no considerábamos.

Cuando nos enfrentamos a ROM hackear unos videojuegos que son tan extremadamente similares entre sí (como pueden ser las distintas versiones de una misma región, como Diamante, Perla y Platino; o distintos idiomas de un mismo juego, como Esmeralda y Emerald) podemos sacar más información de la que está escrita en el código y usarla para intercambiar información entre estas ROMs. Es decir, conocer no sólo el contenido, sino la forma del código que estamos viendo: localización las rutinas a lo largo de la RAM, elevada similitud entre el código de dos funciones casi idénticas, el porqué de las divisiones del código en un overlay o en otro... A esto se le puede conocer como ensamblación estructural, y responde a todas aquellas cuestiones que no se pueden contestar simplemente deduciendo la función de las instrucciones que estamos viendo en la pantalla.

¿Cómo podemos aprovechar esto de forma práctica, y por dónde deberíamos empezar para poder aplicarlo? Los compiladores (los programas que transforman el source que escribió Game Freak a código ensamblador que lee la consola) funcionan de una forma compleja, pero casi siempre de una forma determinada y concreta. Esta determinación es la que nos va a permitir establecer relaciones útiles. Veamos un caso práctico de la ensamblación estructural, aplicado a mis investigaciones en NDS:


Vamos a investigar los efectos gráficos de los climas en HeartGold, para saber dónde se quedaron todos aquellos climas beta programados en Diamante, Perla y Platino, y si con suerte siguen ahí ocultos entre el código en Johto. En el peor de los casos, nos dará pistas sobre cómo tendríamos que adaptar el código de Platino a HeartGold para introducir esos efectos.

El programa que voy a usar lo he hecho yo mismo, cogiendo código de algunos programas de comparación de secuencias biológicas (ADN y proteínas). Estos programas tienen un algoritmo muy preciso y muy bueno. ¿Por qué no podría funcionar directamente buscando los bytes del ensamblado, o buscando por texto las instrucciones? Recordad que os he dicho que los compiladores funcionan de una forma muy compleja: cualquier mínimo cambio realizado en el source original puede hacer que el ensamblado sea relativamente distinto, aunque el cambio se haya realizado no tuviera nada que ver con esa rutina (intercambios de registros, a veces aparece alguna instrucción de más...). Estas particularidades nos originarían "huecos" (gaps) en ambos códigos a comparar, y una búsqueda directa nos daría, con mucha probabilidad, muchísimos resultados o ningún resultado.

En primer lugar, usamos IDA para desensamblar una ROM cualquiera de HeartGold, y nos situamos en cualquier mapa exterior (para asegurarnos de que, si el código de los climas está en un overlay, que ese overlay esté cargado en la memoria). A continuación, cogemos y copiamos toda la pantalla del IDA (es decir, todo el IDA View-A, no los diagramas de bloques sino el texto), porque ahí tenemos las instrucciones ya desensambladas. Solo nos quedaría saber de antemano el código del clima que queramos buscar, ya que es lo que tenemos que comparar. En este caso he elegido la lluvia normal, para asegurarnos de que el código aparezca en la RAM de HeartGold.

La comparación de las secuencias (el dump grande de HG y el código pequeño de lluvia de Pt), tras pasarlo por la herramienta, devuelve la siguiente colisión.


Efectivamente vemos que esta colisión es muy fiable, que es casi seguro que HeartGold usa prácticamente el mismo código para la lluvia normal. De hecho, buscando punteros en la ROM, vemos que efectivamente esta rutina es llamada cuando se tiene que ejecutar el clima de lluvia.



A lo que quiero llegar con esto, es a que la ensamblación estructural tiene muchísimo potencial y prácticamente no está reconocida. No sólo nos va a servir para cosas como el ejemplo que he puesto (conocer código análogo entre distintas ROMs), sino que también abre la puerta completamente a poder utilizar los conocimientos en ASM de las ROMs inglesas en las ROMs españolas, sin ningún tipo de problema (bastaría con hacer un análisis de secuencias muy parecido para saber dónde hay que editar). Además, una automatización de este análisis de secuencias permitiría incluso aplicar un verdadero big data con distintas ROMs y extraer, automáticamente, todas aquellas rutinas que sean equivalentes entre ambas.

Por eso, desde aquí hago un llamamiento para darle importancia también al cómo y dónde están distribuidas las rutinas por la RAM, y no ir sólo a lo directo, a lo simple, a lo sencillo de hallar su función y modificarla como buenamente se puede.
 
Estado
Cerrado para nuevas respuestas.
Arriba