BrunoProg64 Blog

Archive for 8 enero 2011

Sonic R bajo Windows 7 – Análisis Técnico

Posted by brunoprog64 en enero 8, 2011

Sonic R, es un juego desarrollado por Traverlers Tales en 1997 tanto para la Sega Saturn (Una especie de Play Station 1 de SEGA) y PC. Es un juego de carreras y es “infame” por su “azucarda” música (En especial el track “Can you Feel the Sunshine?” y tener asociado a él, la maldición del Tails Doll.

Bueno, por tanto hablar, se me metió la curiosidad de que si realmente una maldición de videojuego pueda matarte. Pensándolo bien… podría ser una muerte “a la” Fringe, como esta de aquí, del Episodio 1×12.

Y bueno, tras pensármelo un rato, decidí bajarme el ISO del Juego de PC… y lo instalé. Y bueno, cuando quize ejecutar el juego, tuve esta “linda” imagen.

Error del Sonic R bajo Windows 7

Error del Sonic R bajo Windows 7

Y bueno, lo intenté ejecutar en máquina virtual de Windows XP… y el mismo error. En modo de Compatibilidad de Windows 95, y lo mismo. Si presiono Enter y lo ejecuto muchas veces, carga… pero luego se cuelga igual. No había forma posible de poderlo jugar en mi PC. Y no pienso usar una Pentium 3 para jugar Sonic R.

Pues bueno, buscando en YouTube y similares encontré una posible solución para el juego. En estos tres videos: Este, este y este.

Bueno, yo he tenido que hacer las tres soluciones. Les menciono rápidamente que problemas daba el Sonic R en mi sistema:

  • Primero… cuando el juego se “lograba” ejecutar, se iba a pantalla completa y se colgaba ahi. No podía salir… así que normalmente hacía Reset.
  • Segundo, si el juego corría, se colgaba en la pantalla de presentación o en el  “Pulsa Start”.
  • Tercero, en la máquina virtual, producía un pantallazo azul en la Máquina Virtual.

Entonces, el problema para “investigar” al juego, era que si lo ejecutaba, se me colgaba en Pantalla Completa y me colapsaba toda la máquina. Así que tenía que ubicar una forma de hacerlo funcionar en una ventana, por si fallaba y así lo podría cerrar y no comprometer mi trabajo previo.

Para eso ubiqué un programa llamado DX-WND-MS, un software que ponía en ventana el Maple Story al interceptar las APIs de DirectX que usa para la pantalla completa. Lo encontré en un servidor com mucho captcha y tonterías similares, así que lo subo a un sitio más directo como MediaFire. Pueden bajarlo aquí.

Internamente este programa trabaja haciendo “hooks”  a las funciones que ponen resolución al “lienzo” DirectX, indicándoles que será una ventana y no la pantalla entera. Aunque no se mucho de DirectX yo en realidad, los interesados en Hooks pueden leer este artículo al respecto.

Bueno, y en ese programa, agregamos nuestro juego (Ubicado en C:SEGASonic Rsonicr.exe) y dejamos corriendo ese programa, de modo que si hacemos algo mal, no nos reseteará o colgará la máquina. Ese paso ya es algo para poder seguir experimentando la razón de los erroes.

Ahora… según uno de los videos, esa era la solución. No la fue en mi caso, el programa seguía crasheando apenas inicia. Entonces hagamos algo más… laborioso. El error del juego dice que en la posición de memoria 00481d09 ha ocurrido un error. ¿Y que hay en esa zona de memoria?

Para eso tenemos que bajarnos un programa llamado W32Dasm, el cual nos permitirá desensamblar nuestro ejecutable. Pueden bajarlo aquí. Y bien, abriremos con ese software nuestro archivo sonicr.exe y en el Menú Goto -> Goto Code Location y apuntamos 0041d09. Y el W32Dasm nos llevará a este lugar:

Desensamblado de Sonic R - Pos. 004801D9

Desensamblado de Sonic R – Pos. 004801D9

La línea en cuestión (Marcada en rojo) menciona un “idiv ecx”. ¿Y qué es eso? Bueno… eso es ensamblador o lenguaje ASM, así que nos vamos a Google y preguntamos que es eso de IDIV ECX.

Aquí nos explican que IDIV es una instrucción que hace que se divida el registro EX, AL o EAX contra el operando (En nuestro caso ECX) y guarda el resultado en EDX o EAX. Para explicarlo claro a los que no entienden ni papa de lo que dije:

Todo microprocesador tiene registros auxiliares (EAX, EDX, etc) y en lenguaje ensamblador estas son operaciones de muy bajo nivel, por lo que se realizan en pocos registros. Y… ¿Cuál es el error que hace que una división salga mal? La única que se me ocurre… es la división por cero.

Pero esperen… miren abajo… ahí pone… “CalculateClockSpeed”. ¿Qué está intentando hacer el programa? Ni idea, porque no domino el ensamblador. Pero seguramente es algo de calcular la velocidad del procesador, a juzgar por el nombre de la función. ¿Saben cómo podemos confirmarlo? Usando un depurador. Así que ahora, nos conseguiremos el Ollydbg, el cual se baja de su página oficial.

Importantísimo tener el DX-WND-MS corriendo para que no nos malogre la ventana… porque un depurador ejecuta el juego, no como el desensamblador que nos permitía verlo estáticamente.

En el Ollydbg, ponemos un Breakpoint en la posición de 004801D9, tipeando el comando

bp 004801d9

Pulsamos F9 para cargar el juego y el Ollydbg hará un alto en esa instrucción. Veremos esto:

Ollydbg y Breakpoint en Sonic R - Pos. 004801D9

Ollydbg y Breakpoint en Sonic R – Pos. 004801D9

Fijémonos en los contenidos de la memoria. Vean que en la ventana de Registro se ve “O – 1” y “C – 1”, eso indica que el flag de Overflow está activado al igual que el de Acarreo. Eso quiere decir que estamos a punto de tener un desbordamiento de enteros… y por eso falla el juego.

¿Y si cambiamos los flags a 0? (Doble click sobre sus letras) Si lo hacemos, veremos que no sirve de nada. Analicemos un poco más…

Obseven en EAX. Doble click y verán que el valor de EAX está totalmente desbordado. (Signed: -1844771072 y Unsigned: 2450196224) Eso explica los flags de Overflow y Acarreo. EDI también está desbordado…

Entonces cambiar a ciegas EAX no nos ayudará. Hay algo raro en el comportamiento de este programa que lo hace fallar. Según los videos de YouTube es la función WIMM.timeGetTime. En realidad yo no soy muy conocedor de ensamblador, así que asumiremos que eso es. Así que según el video, preparamos un Breakpoint en donde es llamada esa función, en la posición de memoria: 00480184. (Dejemomos nuestro Breakpoint en IDIV, sólo por curiosear) Con Ctrl + F2, reiniciamos el depurador.

Según la solución del video, el objetivo de la solución es provocar demora entre esas instrucciones para que no se desborde IDIV. Bueno… curiosaremos en los registros para ver si es eso o no. Ahora lanzamos el sonicr.exe otra vez…

Y volvimos a parar en la posición 00480184. Miremos a EAX. Indica un valor de 5276, por lo que no está desbordado. (Los valores Signed y Unsigned son idénticos y el flag O y C están en 0).  Presionamos F9 para seguir ejecutando… y paramos en 004801D9. Miramos y vemos los bits de Acarreo y Desbordamiento activados, pero seguimos con F9 y el juego no se cuelga. La razón es que IDIV divide por signo y si el resultado es muy grande para caber en el registro destino, el juego se cuelga. Con el delay, hemos prevenido esto, pero aún no estoy 100% convencido. Tendría que leer un poco de Ensamblador otra vez… y eso quedará para nuestro otro artículo.

Al final, logramos esto:

Sonic R - Ejecución Exitosa

Sonic R – Ejecución Exitosa

Y la ansiada carrera… también la logramos:

Sonic R - Carrera con Tails

Sonic R – Carrera con Tails

No sé si podré desbloquear al Tails Doll. El punto es que hemos logrado ejecutar Sonic R en Windows 7. El único inconveniente, es que será algo lento… pero nada del otro mundo.

En resumen… para los que quieren hacer esto en el Ollydbg:

  1. Primero, Breakpoint en 004801D9.
  2. Luego buscar la primera llamada a WIMM.timeGetTime y hacer un breakpoint ahi (En 0048184)
  3. Quitar el primer Breakpoint, salvo que quieran estudiar la razón del error.
  4. Presionar F9 repetidas veces para que haya un delay o demora y el juego pueda dividir bien.
  5. Jugar Sonic R.

Los tutoriales mencionaban usar IDA Pro, que es otro muy buen debugger, pero al cual no estoy acostumbrado… y es “comercial”. Ollydbg es más ligero y hace lo mismo prácticamente.

Si logro entender la causa del error de división, lo haré saber en este post. Ah… y me olvidaba, si quieren oír la infame “Can you feel the Sunshine?” deben jugar con el ISO o CD montado. No funciona sin su CD. El Crack No-CD es otra cosa… que no se ni explicar ni hacer.

Anuncios

Posted in Bilis, Opinion, Programacion, Windows | Comentarios desactivados en Sonic R bajo Windows 7 – Análisis Técnico