Karpoff Spanish Tutor 1999-2001

Juego:

Colin McRae Rally


 

PROTECCIÓN: DiscGuard
Descripción: El mejor juego de rallys 
Dificultad: Normalita
Herramientas: Softice 4, TRW2000 1.22, Hex WhorkShop 3.11, PEditor 1.7, IceDump 6.021, FrogSice 1.08, WDasm o IDA
CRACKER: GáDiX   FECHA: 21/02/2001

 

 

 INTRODUCCIÓN

El mejor juego de rally's se merece la mejor protección, no? Vamos a ver si lo consiguieron. Digo "consiguieron" porque el juego tiene ya sus 2 añitos. Pero no os fiéis de la antigüedad del juego, ya que la protección no es ni mucho menos fácil.

Primero de todo, veamos qué es DiscGuard: 

DiscGuard™ es un sistema anti-piratería que efectúa dos cambios básicos al software: 

- El ejecutable principal está encriptado. 
- Una firma digital especial se inscribe en el CD-ROM. Está firma es usada para desencriptar el ejecutable principal. 

A la hora de copiarlo se parece más a Securom (chequea los SUBCODES) que Safedisc o LaserLock, ya que no tiene sectores defectuosos.

Cómo podemos detectar que nuestro juego está protegido con DiscGuard? Muy fácil, la protección se basa en los ficheros IOSLINK.VXD y IOSLINK.SYS. 

Si os digo la verdad, esta protección comercial sólo la trae este juego, al menos aquí en España. R!SC me confirmó que sí, que sólo la trae este juego. Pero bueno, qué más da que la lleve un juego que quinientos...de lo que se trata es de aprender, no? :-)

 

 

 AL ATAKE


 Hacemos la instalación completa que son unos 500 Mb, vamos al directorio donde lo hemos instalado y vemos que son unos 300 Mb y no 500 como nos decían, pero no nos despistemos, vamos con la protección que es lo que nos interesa.

 Ejecutamos el juego con el CD original en el lector. Umm....nos dice que tenemos que desactivar el "depurador" antes de ejecutar el programa. Es hora de cargar nuestro querido FrogsICE. Bien, nos empieza a leer el CD, hemos pasado el antidebugging. Pero de repente ZASH! el SoftIce nos peta en las narices. Qué raro....reiniciamos por si era uno de los típicos fallos de nuestro Windoze...ejecutamos y ZASH! otra vez. Volvemos a reiniciar, pero esta vez cargamos el TRW 2000 en vez del SoftIce. Lanzamos el juego y para nuestro asombro funciona perfectamente. Esto empieza a ser mosqueante...

Veamos......ante esta situación se me ocurren dos posibles causas: que no hayamos pasado el antiSoftIce o que nos detecte el FrogsIce. Volvemos a ejecutar el juego y observamos el LOG del FrogsIce. Se trata de un simple 'MeltICE', un truco muy sencillo que se basa en abrir los drivers del SoftIce. Para ello usa la función CreateFileA. Si consigue abrirlos es que el Sice está activado. Vamos a ver cómo pasar este truquillo sin el FrogsICE. Poned el siguiente breakpoint:

BPX CreateFileA if *(esp->4+4)=='SICE' 

Ejecutamos el juego y de nuevo aparecemos en el Sice. Ponemos 

d *(esp+4)

y vemos que efectivamente (esp+4) apunta a  "\\.\SICE".   F12 y aparecemos en T29.dll, "r eax -1" y F5. Perfecto, no nos aparece esa asquerosa ventana diciéndonos "que desactivemos nuestro debugger". Nos empieza a leer el CD, pero de nuevo nos peta en T29.dll. Descartamos pues, que se trate de un truco anti-FrogsIce. Es hora de usar una de nuestras últimas cartas: la opción /PROTECT del IceDump 6.02x. Pero la cosa no mejora...es hora de ponerse el traje de buceo!!!

Algo me dice que esta T29.dll tiene que ver y mucho con este "Expediente-X". Vamos a desensamblar esta DLL a ver si encontramos algo interesante. Desensamblamos y vamos a ver que hay alrededor del MeltICE. Cáspitas! No vemos más que cosas raras.....esto está encriptado! Lo desencriptamos, no? :-)

Vamos allá....ponemos:

BPM  12010039 W

y efectivamente el breakpoint surge efecto. Investigamos un poco y llegamos a la conclusión de que esta es la rutina que desencripta la sección .etext. Llegamos hasta el RET para ver desde dónde ha sido llamada esta rutina. También nos fijamos que la rutina devuelve EAX=1 si todo va bien. La rutina es llamada desde 120010C1. Vamos a volcar la sección:    (con el IceDump)

/DUMP   1200E000    7000  c:\etext.bin

1200E000 es el Virtual Offset  (E000) + ImageBase (12000000) de la sección .etext
        7000 es el Raw Size de la sección .etext

Con  la opción "Section Split" de PEditor dividimos T29.dll en secciones, sustituimos la 'antigua' .etext por la nueva y lo juntamos todo con el comando "copy/b" del MS-DOS.

Si ejecutamos ahora el juego, lógicamente, obtenemos un bonito fallo de protección general, ya que T29.dll vuelve desencriptar la ya desencriptada sección .etext. Tenemos que "chafar" la rutina que se encarga de todo esto:

:120010B6    FF36                 push dword ptr [esi]
:120010B8    8D45E4             lea eax, dword ptr [ebp-1C]
:120010BB    68EC800112    push 120180EC
:120010C0    50                      push eax
:120010C1    E83A1A0000    call 12002B00
:120010C6    83C40C            add esp, 0000000C

Sustituimos por:

:120010B6    90         nop 
:120010B7    90         nop 
:120010B8    90         nop 
:120010B9    90         nop 
:120010BA   90         nop 
:120010BB   90         nop 
:120010BC   90         nop 
:120010BD   90         nop 
:120010BE    90         nop 
:120010BF    90         nop 
:120010C0    90         nop 
:120010C1    90         nop 
:120010C2    90         nop 
:120010C3    33C0    xor eax,eax 
:120010C5    40         inc eax 

En realidad sólo tenemos que parchear ese "call 12002B00", pero es conveniente machacar siempre también los "push" que preceden a las "call", para evitar problemas posteriores con la pila.

De paso también eliminamos el MeltIce:

:12010030   FF1568E30112   Call CreateFileA
:12010036   83F8FF               cmp eax, FFFFFFFF
:12010039   7416                    je 12010051

por

:12010030   FF1568E30112   Call CreateFileA
:12010036   83F8FF               cmp eax, FFFFFFFF
:12010039   EB16                   jmp 12010051

 

LA SOLUCIÓN AL EXPEDIENTE-X

Bueno, ahora ya tenemos nuestra T29.dll lista para ser desensamblada. Tras estudiar un rato el "listado muerto" encontramos una función que nos llama especialmente la atención:

GetTickCount 

La función GetTickCount devuelve el número de milisegundos que han pasado desde que Windows arrancó. 

Recuerdo haber usado esta función en un programilla en ensamblador para obtener valores aleatorios. Pero no sé porqué que me da que aquí no es usada con ese propósito. Vamos a investigar con el Sice, poned un breakpoint en esta función. Vemos lo siguiente:

:120127F6     8B3520F00112      mov esi,[1201F020] <----------- ESI = 7530h
:120127FC    FF157CE30112     call [Kernel32!GetTickCount] 
:12012802     03C6                      add eax,esi 
<---------------------- Le añade a EAX el valor de ESI 
:12012804     8BCF                      mov ecx,edi 
:12012806     8987D4150000       mov [edi+000015D4],eax 
<--- Y lo almacena en una variable

De momento nada relevante, ningún salto condicional ni nada sospechoso. Pulsamos F5 para continuar. Atentos que ahora viene "lo bueno". Volvemos a caer en GetTickCount, F12 y:

:12011693     FF157CE30112     call [Kernel32!GetTickCount] 
:12011699     3B85D4150000     cmp eax,[ebp+000015D4] 
:1201169F     776D                      ja 1201170E
<--- Forzar este saltito ;-)

Sí, si forzamos ese salto ("r fl c")... "bye, bye antisoftice!" :-D  Y muchos os preguntaréis: ¿cómo cojones se lo monta para detectarnos el SoftIce con esa función? De todos es sabido que el reloj de Windows trabaja en Ring-3 y que cuando entramos en Ring-0 no se actualiza correctamente. Y el SoftIce como VXD que es, trabaja en Ring-0. Hay que reconocer que a veces nuestros queridos programadores se lo curran mucho. Por cierto, nunca habéis llegado tarde a una cita por culpa del reloj de Windows? Ahora ya sabéis a que es debido ;-)

Bien aún nos queda dos cosillas, una de ellas es encontrar el verdadero Entry Point. Me vienen a la cabeza dos formas de hallarlo:

- Ir trazando todo el código del DiscGuard, hasta encontrarlo. NO! Muy aburrido y pesado.
- Utilizar el truquillo del GetVersion. Casi todos los programas a la primera función que llaman es a ésta. BPX GetVersion, F12 y:

:00508C20     55                             push ebp  <--- Tiene pinta de ser el verdadero Entry Point, no? ;-)
:00508C21     8BEC                       mov ebp,esp 
:00508C23     6AFF                        push FF 
:00508C25     68D0FF5100            push 0051FFD0 
:00508C2A    68C44C5100            push 00514CC4 
:00508C2F     64A100000000        mov eax,fs:[00000000] 
:00508C35     50                             push eax 
:00508C36     64892500000000     mov fs:[00000000],esp 
:00508C3D     83C4A4                   add esp,-5cC 
:00508C40     53                             push ebx 
:00508C41     56                             push esi 
:00508C42     57                             push edi 
:00508C43     8965E8                     mov [ebp-18],esp 
:00508C46     FF158CE15100        call [Kernel32!GetVersion] 
:00508C4C    A32C77E900            mov [00E9772C],eax
<--- Aparecemos aquí

Como bien sabemos la prácticamente totalidad de programas (menos los programados en Win32ASM), empiezan por la secuencia "push ebp, mov ebp,esp...". Vamos a asegurarnos. A ver, normalmente las protecciones de CD, saltan al verdadero Entry Point o bien mediante una "CALL xxx" o bien con un "JMP_reg". Si hemos venido a parar aquí mediante una CALL podemos hallar desde dónde hemos sido llamadas gracias a "la dirección de retorno". Vamos a probar suerte. Desde el Sice y tras volver del GetVersion:

u *(ebp+4)

:1200E592    FF55B8    call [ebp-48] 
:1200E595    50             push eax 
<--- Esta es la dirección de retorno, por tanto hemos sido llamados      ............................................................ desde ese "call [ebp-48]" 

Ummm este código está dentro de T29.dll, tiene pinta de ser lo que buscamos...pero mejor nos aseguramos. Ponemos un BPM en 1200E592 ( BPM 1200E592 X ), matamos el proceso (r eip ExitProcess) y volvemos a ejecutar. Aparecemos en 1200E592:

d *(ebp-48) 

y vemos que es 00508C20. Yehaaaaaa! Ya lo tenemos. Si pero......DiscGuard basa el CRC de T29.dll para desencriptar la sección .text, tenemos que restaurar la T29.dll original. Por tanto tendremos que saltarnos el MeltIce y el GetTickCount "a mano". Tras cualquiera de estos dos breakpoints ponemos un BPM en 00508C20. Una vez en este punto, volcamos .text:

/DUMP    401000  11C400  c:\colin_text.bin

Y la pegamos en rally.exe. Ejecutamos y ZASH! otro GPF! A qué es debido? Como en la mayoría de protecciones la IAT no es correcta. Vamos a buscarla...

Si abrimos 'rally.exe' con PEditor y vamos a 'Imports' vemos lo siguiente:

T29.dll ya no nos interesa, la vamos a eliminar de la Tabla de Importación. Vemos que la primera librería es DPLAYX.dll. Posiblemente estés pensando que ahora buscaremos la IAT como en mi anterior tute sobre Securom. Pero no, con ese método no la encontramos,  ya que ha sido retocada/dañada por DiscGuard. Buscaremos qué apunta al 'OriginalFirstThunk'. Con HexWorkShop vamos al offset 12128C. Vemos los siguientes bytes:  4153 5300. Los buscamos hacia arriba y los encontramos  en el offset 121184. Corregimos este valor con nuestro editor PE, sacamos el CD, probamos....y rula!!!

El juego entra, pero todavía nos pide el CD, pero esta protección no es del DiscGuard, sino del propio juego. Vamos a quitarla. BPX GetDriveTypeA, ejecutamos y caemos en el Sice....Opps! La pantalla del Sice no se ve correctamente. Podríamos cambiar los colores del Sice con el comando "COLOR", pero no nos calentemos tanto la perola, utilicemos el WDasm. Buscamos el mensaje de error en las 'Strings References' y vamos a parar aquí:

* Possible StringData Ref from Data Obj ->"INTRODUCE EL CD DE COLIN MCRAE "
->"RALLY EN LA UNIDAD O PULSA ESCAPE"
|
:004ED046    mov [ebp-18], 0055C96C

Subimos un poco hacia arriba y encontramos esto:

* Referenced by a CALL at Address:
|:004ADC13 

Vamos a  004ADC13 y:

:004ADBFB    call 004AEAA0  <--- Rutina de comprobación del CD
:004ADC00     test eax, eax
:004ADC02     jne 004ADC69
<--- Si todo ha ido bien salta
:004ADC04     cmp dword ptr [00B26D2C], 00000000
:004ADC0B     jne 004ADC69
:004ADC0D    cmp dword ptr [ebp-14], 00000000
:004ADC11     jne 004ADC3A
:004ADC13     call 004ED001
<--- Rutina del mensaje que nos pide el CD
:004ADC18     mov ecx, dword ptr [0054E3C0]

Hacemos incondicional el salto en 004ADC02 y ya tenemos nuestro 'Crack NO-CD' del Colin McRae.

 

SE COGE ANTES A UN MENTIROSO QUE A UN COJO...

Palabras de la compañía del DiscGuard:

"Una firma digital especial se inscribe en el CD-ROM. Está firma es usada para desencriptar el ejecutable principal" 

Como no merece la pena perder mucho el tiempo en esta parte de la protección, doy directamente la solución final.  SIN el CD metido en el lector, repetid los pasos de arriba, pero además poned un breakpoint en GetDriveTypeA. Cuando "caigáis" en este breakpoint, F12, "r eax 5". Ya podéis crackearlo igual que si tuvieseis el CD insertado en el lector....simplemente  PATÉTICO. 

RIPEANDO...

Ya para terminar de 'estrujar las tuercas', vamos a ver si podemos ripear los videos y la música que están en los siguientes directorios: 

Directorio   x:\CMRally\New_Fe\FMV:

FMV.AVI                   10,469,376 
INTRO.AVI                  2,074,624  

Directorio   x:\CMRally\New_Fe\Sounds\Music

FRONTEND.WAV    55,389,204 

Optamos por lo más fácil, por borrarlos, si cuela...y.... sí, esta vez lo hemos tenido fácil, no obtenemos ningún mensaje de error, el juego va perfectamente!  Y puestos a borrar, podemos eliminar también los ficheros que forman parte de DiscGuard:

IOSLINK.VXD, IOSLINK.SYS, T29.DLL, TTR2.DLL, TTR1.DLL y ALTERNATE.EXE

 

PALABRAS FINALES

Este tutorial se lo dedico a la "nueva generación de CD-Crackers hispanos":

- Ni2. Eres de lo mejorcito que he visto nunca, espero volver a verte pronto en el mundillo
- SkUaTeR. Tres cuartos de lo mismo (cuando quieras nos ponemos con otro unpacker... ;-)
- KeopS. Se te ha resistido alguna vez una protección? :-)

Dudas, erratas y demás a:

gadix_crk@hotmail.com

 

 

 

Karpoff Spanish Tutor: Página dedicada a la divulgación de información en Castellano, sobre Ingeniería Inversa y Programación. Email "Colabora con tus Proyectos"
www.000webhost.com