Recuperado gracias a Alek, webmaster de dark-alex.org
Traducción del inglés por largeroliker
Éste es un artículo para ayudaros a distinguir una vulnerabilidad exploitable (por ejemplo, el GripShift de MaTiAZ) de un simple crash no explotable (o al menos, no lo suficiente), como el de Phantasy Star de yyoossk. Podría ser visto como un tutorial sobre "cómo buscar un exploit de partida guardada de PSP"
Si, como yo, desafortunadamente quieres liberar tu PSP 3000 o Go, esto es parecido a cómo ocurre en los sitios dedicados a PSP.
De vez en cuando, alguien aleatoriamente postea con la "idea" de cómo liberar la PSP o, con suerte, llega de repente con un savedata que crashea la PSP, con la esperanza de que sea de utilidad. Reportar un crash es hoy día una buena idea, ya que son el primer paso paraa un exploit. Y si no vale para ello, al meeos ayuda a Sony a mejorar su firmware (xD)
Recientemente, un tipo de nick yyoossk intentó reproducir lo que MaTiAZ había hecho con GripShift en la demo japonesa de "Phantasy Star Portable". Uoh, un exploit en una demo, estaría bien, no hay necesidad de comprar caros UMDs!!! Es por eso por lo que decidí darle una oportunidad. Intentaré explicar aquí por qué este crash es sólo eso, un crash, y posiblemente nunca pueda ser aprovechado con un exploit.
==
NOTA del traductor: Nótese que en este apartado ya se ha quedado anticuado, actualmente podemos encontrar el Half Byte Loader de m0skit0 y el propio wololo basado en la demo de Patapon 2. Más información en el foro de Noticias PSP...
==
Compararé el crash de Phantasy Star Portable con lo que ocurre con el exploit de GripShift. Antes de comenzar, tienes que saber que no intento ser el mejor hacker o desarrollador del mundo. Sólo estoy un poco por encima del nivel de "completo noob" pero con la suficiente experiencia en ESTO para comprender lo que veo en mi pantalla. Así que este texto podría ser inapropiado en algunas partes.
Para leer este artículo, necesitas tener un buen conocimiento de conceptos básicos de programación como variables, direcciones y arrays (cadenas, o cómo lo queráis traducir XD). También deberías tener una ventana del navegador abierta con la lista de comandos de ensamblador de MIPS. En realidad no hace falta conocer ensamblador MIPS si sabes lo más básico de programación, pero seguro que ayuda a tener una idea general de qué lenguaje ensamblador es.
Los fundamentos de un exploit de partidas guardada
La mayoría de los exploits de partidas guardadas confían en el concepto de "buffer overflow" o "desbordamiento de búffer", que consiste en escribir más datos en el array que el que deberías. Por ejemplo, si tu tienes un array de tamaño 10, e intentas escribir 11 elementos en ñel, tendrás un desbordamiento de búffer de 1 elemento. Lo que ocurre en ese caso es que escribes algo en memoria que no deberías, y esto podría dar resultados interesantes de los que hablaremos más tarde. Para más información sobre desbordamientos de buffer, por favor leed éste artículo (en inglés).
Ahora, una manera muy empleada para buscar desbordamientos de búffer (en las partidas, pero no únicamente) es poner una cadena muy larga en alguna parte. Las cadenas normalmente se representan como arrays o chars, y son fáciles de identificar en saves descifrados. No puedes saber con facilidad qué números representan la cantidad de monedas de oro que tienesn en tu inventario, pero es muy fácil buscar "wololo" en el archivo.
Una vez la cadena se ha localizado, el primer paso es poner un nombre muy largo en ella. Es lo que MaTiAZ hizo con GrpShift ("Spartaaaaaaaaaaa"), y posiblemente lo que produjo el crash de Phantasy Star también.

Por supuesto, no puedes hacer esto a través del juego en sí (la interfaz no te permitiría poner más de, pongamos, 10 caracteres), así que tienes que descifrar tu partida, editarla y volverla a cifrar. Una herramienta como el savegame-deemer es muy útil en estos casos, ya que te permite trabajar directamente en partidas cifradas sin preocuparte de descifrarla.
Así que fundamentalmente, pones algo de basura en tu partida guardada, e intentas a ver si esto hace que el juego crashee. En la mayoría de los casos, el juego no crahseará, pero simplemente te dirá que tu savedata es inválido (típico mensaje de Datos corruptos o no válidos). Fin del juego, no encontrarás ningún exploit con este juego y este método ( no necesariamente significa que el juego no tenga ningún agujero, sólo que necesitas pensarlo y currarlo más, pero eso está más allá de lo que quiero explicar en este artículo)
Pero, ¿y qué si el juego crashea cuando carga la partida?. Bien, significa que algunos desarrolladores no hicieron bien su trabajo, y hay una vulnerabilidad en el juego. NO SIGNIFICA QUE HAYA UN EXPLOIT AÚN, por ahora es sólo un bug. Para ver si es interesante, tienes que ejecutarlo con PSPLink y analizar el volcado de error.
Ejecutando el juego con PSPLink
Aquí es donde la dificultad comienza. Para este paso necesitarás una PSP con CFW y PSPLink instalado. No ahondaré en los detalles de instalación de PSPLink ya que se pueden encontrar con facilidad.
Aquí tienes un tutorial bastante completo
Necesitamos utilizar PSPLink como plugin ya que ejecutaremos un juego. Para ello necesitas tener tanto usbhostfs.prx como psplink.prx en tu carpeta seplugins, y tenerlos activados en en game.txt. No daré más detalles ya que necesita la misma instalación que el RemoteJoy, menos por la parte del control renoto :p
Una vez esté todo instalado, ejecuta usbhostfs_pc y pspsh desde tu ordenador, conecta la consola al ordenador por USB y ejecuta el juego.

Si todo va bien, usbhostfs_pc debería mostrar un "connected to device" ("Conectado al dispositivo") y pspsh un "all modules loaded" ("todos los módulos cargados") y luego un comando "/host0:>"

Cuando cargues la partida, el juego crasheará, y deberías ver un volcado de memoria mostrado en pspsh, como abajo

¿Qué buscamos?
Ahora viene la pequeña dificultad sobre ensamblador. PSPLink nos muestra el estado de varios registros justo antes del crash. Los registros son simplemente "integers" de 32 bits usados en cualquier programa, y que pueden representar cualquier cosa (caracteres, direcciones en memoria, integers...) dependiendo de cómo los interprete el programa.
Lo que queremos cuando escribimos un exploit es poder saltar a una posición arbitraria de la memoria. Desafortunadamente, no hay muchas maneras para hacer esto. La única solución que conozco para esto es sobreescribir los contenidos del registro llamado "$ra". ra significa "return address" ("dirección de retorno"), así que comprende por qué es tan importante. Aquí es donde el código vendrá cuando acuda a una subrutina, con el comando "j $ra" (jump [saltar] a $ra). $ra por sí sola normalmente consige sus datos de $sp, así que si podemos manipular los datos relacionados com $sp, es también una buena señal.
Los otros registros no son inútiles, son los que eventualmente rellenen los contenidos de $sp y $ra, pero eso ya es demasiado complejo para explicarlo aquí (y, honestamente, no sé demasiado sobre eso además de que necesita un análisis detallado del programa, cosa que no voy a hacer)
Comparando el crash de GripShift (por qué funciona) y el crash de Phantasy Star (por qué no funciona)
Comparemos nuestros dos crash.

Ponemos muchas letras "a" en el nombre de los jugadores, cosa que vemos en el reporte del crash ya que el valor de $ra es 0x61616161. Esto es un dato interesante ya que 61 es el valor hexadecimal de "a": bingo, básicamente hemos encontrado una forma fácil para saltar a una localización arbitraria en memoria. Lo que queda es reemplazar "aaaa" con una dirección normal, para lo que usaremos un poco de código. (Notad que edité el POC original de MaTiAZ para hacerlo crashear aparte de ejecutar código)
El crash de Phantasy Star:

Vemos algunos "61" aquí y allí, pero nada interesante en $sp o $ra. Es un muy mal comienzo. Pero todavía podemos echar un vistazo al código, ver si esos $a1, $a2 o $a3 hacen algo bueno.

Nada parece cambiar algo en $sp, el código salta una vez, dos, meh...
Es muy complejo, normalmente es ahora cuando te cansas y empiezas a buscar agujeros en otro juego.
Así que, ¿el crash de Phantasy Star no vale para nada?
No exactamente, es un bug, así que puede haber una manera para exploitearlo, pero cuando un salto no es obvio pierdes menos tiempo buscando un crash en otro juego, la verdad.
Buscar un salto que puede que nunca se de no es divertido y puede llevarse cientos de horas, así que no vale la pena (si deseas hacerlo, llegarás más lejos descifrando el firmware y buscando exploits en el kernel)
Esto es muy complejo para mí, ¿no hay otra manera que me diga si un crash es bueno o no?
Bueno, primero usa tu cerebro. sabes que la scene PSP ha trabajado mucho, cuando alguien llega con un exploit potencial puedes estar seguro que alguien te dará una portunidad si vale la pena. Si después de unas pocas semanas no hay una discusión "seria" sobre el fallo (con código de por medio o archivos POC) deberías perder un poco la esperanza.
Además, en este caso específico, hay otra señal que tampoco funcionaría: si fueran tan fácil como el exploit de GripShift, el crash ocurriría cuando el nombre de usuario se cargara. No es el caso, como puedes ver el nombre del jugador se muestra correctamente después de cargar la partida.

Así que la demo de Phantasy Star tiene una comprobación de seguridad en la longitud del nombre del jugador. Esto no es una prueba de que el crash es inútil, pero sí un buen punto para saber que no puede ser tan fácil como el de GripShift.
Personalmente creo que es bueno reportar un crash como hizo yyoossk, su reporte fue detallado y aportó todos los archivos para reproducir el fallo, cosa que me hizo querer probarlo (eso, y que era una demo a la que cualquiera tiene acceso). Si hubiera docenas de reportes como ese todos los días, ¡algunos de ellos es muy posible que contengan agujeros de utilidad!