martes, 10 de septiembre de 2024

Creamos el mejor "Crack No CD" para un juego retro (Tarzán)

 Descarga Tarzan PC Portable aquí.

Aunque el tema del crackeo es un tema delicado, si que es verdad que hay veces donde puede estar medio justificado en abandonware y PCs que ya no disponen de lector de CD. El problema es que estos cracks no siempre son del todo fiables (algunos incluso pueden llevar algún regalito), y los creadores de estos cracks nunca revelan detalles de como lo hicieron, permaneciendo ademas en el anonimato mediante un pseudonimo.

Pues por primera vez, y con motivos didácticos, vamos a crear nuestro propio crack de código abierto para un juego abandonware: Tarzán de Disney Interactive.

Pues bien, este juego aunque copia todos los archivos del juego al disco duro al instalarlo, requiere tener el CD insertado para poder jugar. Si abres el juego sin el CD aparece la siguiente pantalla y no permite jugar

Pues tras un breve análisis, detectamos que existe un flag en memoria en 0x837A24 que indica cuando el juego original esta insertado, y buscando la rutina que setea este flag encontramos lo siguiente
En el primer call el juego comprueba que hay un CD insertado y que contiene determinados archivos, haciendo luego comprobaciones adicionales en el segundo call. Pues bien, nosotros queremos setear siempre ese flag sin hacer todas estas comprobaciones, así que reemplazaremos todas las instrucciones hasta el mov del final por nop.
"TARZAN.EXE"+A39C9: //CD Check db 90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90
Y tampoco nos olvidemos de dejar nuestra firma ;) reemplazaremos el mensaje de CPU con MMX ya que en 2024 no es que nos aporte mucha información
"TARZAN.EXE"+1050E0: //Crack NOCD signature db 'CRACK NOCD JUANMV94',0 "TARZAN.EXE"+8FF33: db 90,90,90,90,90,90,90,90,90
Y... voilà. ¡Crackeo completo! Ya podemos jugar sin CD

FIN


Pero... Esperad un minuto... ¡El juego no tiene música! Resulta que el juego es un CD mixto y la música se encuentra en los distintos tracks del CD.
Y aquí es donde sacamos el armamento pesado, y procedemos a hacer una locura que a ningún cracker se le ocurriría hacer...
Vamos a reescribir las rutinas del juego que leen las pistas del CD, para que lean ficheros MP3 en su lugar ¡y todo ello en puro ensamblador!
Esto lo hacemos usando la librería WinMM que ya usaba el juego, concrétamente usando comandos MCI.
Pues bien, tenemos que localizar las funciones del juego de "reproducir el track XX", "parar CD",... y reescribirlas, aparte de almacenar un handle al archivo MP3 que se este reproduciendo en algún sitio. Nos quedamos con lo siguiente:
define(MUSHANDLE,1051C8) "TARZAN.EXE"+89020: //Stop track push 00 push 00 push 0804 //MCI_CLOSE push ["TARZAN.EXE"+MUSHANDLE] call dword ptr ["TARZAN.EXE"+AF234] //WINMM.mciSendCommandA mov ["TARZAN.EXE"+MUSHANDLE],00000000 ret "TARZAN.EXE"+88FB0: //Disable music call "TARZAN.EXE"+89020 //Stop track ret "TARZAN.EXE"+89070: //Request track mov eax,[esp+04] push 00 push eax call "TARZAN.EXE"+89170 //Play track add esp,08 ret "TARZAN.EXE"+89170: //Play track mov eax,["TARZAN.EXE"+12A5C4] test eax,eax //Music enabled? je RETPLAY sub esp,0C //Alloc 12 bytes for file name push [esp+10] //Track no push FILENAME //File name template with %02d lea eax,[esp+08] push eax call "TARZAN.EXE"+A4190 //sprintf call "TARZAN.EXE"+89020 //Stop track //push MCI_OPEN_PARMS to stack push 00 //LPCTSTR lpstrAlias; lea eax,[esp+10] push eax push MPEGVIDEO //LPCTSTR lpstrDeviceType; push 00 //MCIDEVICEID wDeviceID; push 00 //DWORD_PTR dwCallback; push esp //MCI_OPEN_PARMS push 2200 //MCI_OPEN_ELEMENT | MCI_OPEN_TYPE push 0803 //MCI_OPEN push 00 call dword ptr ["TARZAN.EXE"+AF234] //WINMM.mciSendCommandA mov eax,[esp+4] //store handle mov ["TARZAN.EXE"+MUSHANDLE],eax push MCI_PLAY_PARMS push 00010000 //MCI_DGV_PLAY_REPEAT push 0806 //MCI_PLAY push [esp+10] call dword ptr ["TARZAN.EXE"+AF234] //WINMM.mciSendCommandA add esp,2C RETPLAY: ret MCI_PLAY_PARMS: dd 0 //DWORD_PTR dwCallback; dd 0 //DWORD dwFrom; dd 0 //DWORD dwTo; MPEGVIDEO: db 'mpegvideo',0 FILENAME: db 'MUS/%02d.MP3',0
* Os habréis fijado que hay una función que solicita reproducir un track, y otra que procede a reproducirlo. Esta primera función realizaba varios checks del CD que no nos interesan, así que la re-implementamos de forma que únicamente re-ordenará los parámetros y llamará a la segunda función sin realizar ningún check.
* La función que silencia el audio del CD al des-habilitar la música en el menú de opciones la simplificaremos a simplemente parar la reproducción. No es el mismo comportamiento exacto, pero nos vale.
* La función que reproduce el track comprobará que la música este habilitada en el menú de opciones, y convertirá ese numero de track en un path a un archivo MP3 con sprintf, de forma que el track 2 sea por ejemplo "MUS/02.MP3", lo cargará y lo empezará a reproducir de inmediato en modo repetición, habiendo parado previamente la reproducción previa en caso de existir.

¡Y ahora sí! Extraemos los tracks del CD a MP3 y ya podemos jugar a nuestro juego con la música del CD original en un PC sin unidad de disco.

Hacedme saber si queréis más contenido como este en los comentarios