TORN@DO presents: cRACKER's n0TES
Sistemas de Protecci�n comerciales: SecuROM



Crackeando SecuROM (Pedro))
Primero, una explicaci�n simple sobre SecuROM
SecuROM es una protecci�n del CD-ROM que no puede copiarse cuando duplicas un CD. Es usado por muchos juegos, con el prop�sito de este tutorial yo prob� Conflict Freespace (versi�n inglesa), Grim Fandango (versi�n italiana) y Might and Magic VI (versi�n italiana). Este es el primer tutorial que yo escribo, as� que me perdonas si no estoy claro o si mi ingl�s es malo. Decid� escribir este tutorial porque el crack gen�rico para SecuROM de Laxity no funciona en los juegos que yo prob�. Tambi�n encontr� que parte del c�digo de SecuROM est� encriptada, y es descifrada por una lectura de la clave del CD. Mi objetivo es permitir a la protecci�n descifrarse, entonces poner el c�digo descifrado en el ejecutable y quitar la comprobaci�n del CD-ROM por SecuROM.

Necesitas SoftICE, Adump 1.0, ProcDump32 1.1 y el gratuito & grandioso
DJGPP32 C++ - Compilador para usar este tutorial.


Primero, miremos al ejecutable principal. Conflict Freespace y Might and Magic VI no est�n empaquetados, mientras que Grim Fandango est� empaquetado con Petite. As� que la primera cosa que nosotros tenemos que hacer es desempaquetar el ejecutable de Grim Fandango. Por suerte es bastante f�cil si nosotros usamos ProcDump32, este tiene apoyo para desempaquetar los programas comprimidos por Petite.

Ok, empecemos con el cracking real ;-)

Cuando arrancamos estos juegos, vemos que cargan algo del disco y que simplemente terminan (porque pusimos una copia, no el original dentro del lector :-) Bien,podemos intentar un breakpoint en la llamada usual a SendDriverMessage, pero no pasa nada.

Hmm, parece que SecuROM no usa el Windows API para acceder al CD-ROM. Te ahorro el esfuerzo de encontrar c�mo el programa accede al CD-ROM: Usa INT 31 con AH=03 (DPMI 0.9+ - SIM�LATE REAL MODE INTERRUPT) para llamar a la interrupci�n de MSCDEX

andemos un poco despu�s del breakpoint, entramos en CMS32_95.DLL eso es parte de la protecci�n, entonces alcanzamos el ejecutable principal. �Ahora, si buscamos algunos de los bytes del c�digo que nosotros vemos, no podemos encontrarlos en el archivo ejecutable principal! Partes del c�digo est�n encriptadas, y ellas se descifran cuando el programa se ejecuta. �C�mo puede modificarse el programa durante la ejecuci�n?

Llamando a WriteProcessMemory. As� que ponemos un breakpoint en esta llamada. Vemos que todos �stos juegos lo llaman tres veces por lo menos, aun cuando no pusimos el CD-ROM en el lector. As� que este descifrado no depende de los datos en el CD-ROM original. Esto es simplemente el c�digo que hace el �ltimo descifrado. De hecho si nosotros pusi�ramos el CD-ROM original en el lector, el API es llamado una vez m�s, y el c�digo descifrado es correcto, mientras si nosotros pusi�ramos una copia en el lector, o bien WriteProcessMemory no es llamado la cuarta vez (copia mala, as� que la protecci�n comprende que es falso) o es llamado pero el c�digo descifrado es basura y el programa comprende que es err�neo y sale.

As� que el cuarto descifrado depende de la lectura de los datos del CD-ROM original.

Si miramos la referencia de API que vemos cuando el breakpoint es activado en WriteProcessMemory tenemos:

ESP+08: direcci�n del destino
ESP+0C: direcci�n de la fuente
ESP+10: longitud de �rea a copiar

As� que, nosotros podr�amos descargar los bytes del c�digo despu�s del descifrado y podr�amos sustituirlos en el archivo ejecutable principal.

Primero hacemos una copia del ejecutable principal llamado MM6_2.EXE (para este prop�sito yo uso Might and Magic VI, pero los otros funcionan de la misma manera). Es importante usar nombres de archivo cortos, de otra manera supcomp y supwrite no funcionar�n. La regla es: ejecutamos el original MM6.EXE para descifrar el c�digo y parcheamos MM6_2.exe (no ejecutar MM6_2.EXE antes de que sea parcheado completamente o se colgar�).

Ejecutemos Adump. Con el comando ' R' veo que el comienzo del �rea de memoria para descargar es 0x83651000.

Ahora ejecutemos MM6.EXE con breakpoint en WriteProcessMemory. Ok, veo que 0x5000 bytes ser�n escritos, la direcci�n de la fuente est� en 0xe80078 mientras la destino direcci�n est� en 0x4ae000. As� que copio las dos �reas (fuente y destino) en dos �reas diferentes de descarga de memoria::

M 4AE000 L 5000 83651000 (c�digo original)
M E80078 L 5000 83661000 (c�digo desencriptado)

Dej� al proceso acabar, voy al "dumpeador" y escribo las dos �reas de memoria a dos archivos.

W C:\ORIG1.DAT 5000 83651000
W C:\MODIF1.DAT 5000 83661000

Ahora abro ORIG1.DAT con un editor hexadecimal y tomo los primeros 16 bytes. Busco esos bytes en MM6_2.EXE. Los encuentro en offset 0xAD400. Veamos si todos los 0x5000 bytes son id�nticos. Abro una ventana de DOS y ejecuto:

supcomp C:\ORIG1.DAT MM6_2.EXE 0 0xAD400 0x5000

Ok, ninguna diferencia, as� que podemos parchearlos.

supwrite C:\MODIF1.DAT MM6_2.EXE 0 0xAD400 0x5000

Pero ahora si nosotros ejecutamos MM6_2.EXE se cuelga porque intenta descifrar datos ya descifrado y consigue basura. As� que ejecutemos MM6.EXE de nuevo, y cuando localizamos el breakpoint, escribimos ' u @esp ' y subimos algunas l�neas:


       :008CC2FE  8D8D64FEFFFF        LEA     ECX,[EBP-019C] 
       :008CC304  51                  PUSH    ECX 
       :008CC305  8B95C4FEFFFF        MOV     EDX,[EBP-013C] 
       :008CC30B  52                  PUSH    EDX              ; longitud 
       :008CC30C  8B85E4FEFFFF        MOV     EAX,[EBP-011C] 
       :008CC312  50                  PUSH    EAX              ; fuente 
       :008CC313  8B8DBCFEFFFF        MOV     ECX,[EBP-0144]  
       :008CC319  2B8DB4FEFFFF        SUB     ECX,[EBP-014C] 
       :008CC31F  51                  PUSH    ECX              ; destino 
       :008CC320  8B15B87D9F00        MOV     EDX,[009F7DB8] 
       :008CC326  52                  PUSH    EDX              ; manipulador 
       :008CC327  FF15B8839F00        CALL    [KERNEL32!WriteProcessMemory]
    

Debemos poner longitud a 0 as� que cambiamos:


       MOV EDX,[EBP-13C] 
       PUSH EDX
    

a:


       XOR EDX,EDX 
       NOP 
       NOP 
       NOP 
       NOP 
       PUSH EDX
    

Es decir, nosotros buscamos los bytes (en MM6_2.EXE):
8B 95 C4 FE FF FF 52 8B 85 E4 FE FF FF 50 8B 8D BC FE FF FF 2B 8D B4 FE FF FF 51 8B 15 B8 7D 9F 00 52 FF 15 B8 83 9F 00

y cambiamos los primeros 6 bytes a:

33 D2 90 90 90 90

(es mejor buscar varios bytes, porque hay partes similares de c�digo, y tenemos que asegurarnos que hemos encontrado el lugar exacto).

Tienes que trabajar de la misma manera para los otros dos breakpoints (cambia el c�digo cifrado por el c�digo descifrado y pon a cero la longitud para WriteProcessMemory). Alguien podr�an preguntarse por qu� no escrib� un programa para hacer todo esto autom�ticamente.

Bien, el problema es, el c�digo es similar pero no es el mismo para todos los juegos que prob� (por ejemplo Grim Fandango usa ECX como el registro para empujar el par�metro de longitud).

Ahora nosotros realmente necesitamos el CD-ROM original (�lo compraste?,� no lo tienes? :-) para descifrar el c�digo correctamente. Todav�a debemos repetir el procedimiento anterior para descifrar y poner la longitud a cero cuando localiza el cuarto WriteProcessMemory (esta vez EDX es "XOReado" amablemente para nosotros, as� que nosotros apenas necesitamos ' NOPear' la siguiente instrucci�n que carga EDX). Tambi�n debemos crackear la parte de c�digo donde verifica el CD-ROM original y sale sin ejecutar nuestro c�digo parcheado (esto est� en la parte del c�digo que desciframos antes, as� que si no lo hubi�ramos descifrado, no podr�amos encontrarlo f�cilmente el archivo ejecutable).

�De hecho si nosotros intentamos ejecutar el programa despu�s de cuarto descifrado pero antes del �ltimo crack, no funcionar�, incluso con el CD-ROM original en el lector!

La �ltima parte del crack es un poco m�s dif�cil porque no puedes caminar en el c�digo del programa(F8 o F10 no funcionar�n). Es m�s, si el programa descubre que est�s intentando caminar en �l, la pr�xima vez ni siquiera se cargar� hasta que rein�cies Windows, as� que no debes poner breakpoints excepto lo que yo te diga. Te ahorrar� el tiempo que yo gast� para entender lo que el hace programa. Primero puedes poner un breakpoint en GetDriveTypeA que es usado para encontrar el CD-ROM. Con F11 vuelves al c�digo del programa. Si te desplazas en la ventana del c�digo algunas p�ginas abajo, encontrar�s una serie de POPs y un RET seguida por unos INT 03. Pon un breakpoint en el RET.

Ejecuta el original MM6.EXE con el CD original.

Hmm, no alcanza el RET. Quita el CD del lector y ejec�talo de nuevo. Ah, ahora alcanza el RET con EAX=2. Pon el CD-ROM original de nuevo en el lector pero ejecuta MM6_2.EXE (debes de haberlo descifrado y lo debes de haber remendado TODO las cuatro veces). Alcanza el RET con EAX=7. Si pones una copia en el lector tambi�n consigues EAX=7. As� que es f�cil entender que EAX contiene un c�digo de error cuando algo sale mal, y el RET nunca es alcanzado cuando todo va correctos. Ahora debes ejecutar el MM6_2.EXE modificado despu�s de poner el cd original en el lector y poner un breakpoint en GetDriveTypeA y en RET. Aprieta F11 para conseguir el c�digo cuando alcance GetDriveTypeA. Recuerda, debes conseguir el c�digo de error 7 de modo que despl�zate abajo hasta que encuentres:


       TEST EDX,EDX ; �error? 
       JNZ ........ ; si salta => no error 
       CALL [.....] ; comienzo de rutina de error 
       PUSH 07 
       CALL ....... 
       MOV EAX,7    ; c�digo de error 
       JMP ........ ; salta a los POPs y RET
 

As� que el primer jnz debe cambiarse a jmp. Buscamos los siguientes bytes:

75 17 FF 15 B0 83 9F 00 6A 07
Dentro de MM6_2.EXE y cambiamos 75 a EB. Ejec�talo. Otro error, con retorno de c�digo 8. En el c�digo encontramos:


       TEST EDX,EDX ; �error? 
       JNZ ........ ; si salta => no error 
       CALL [.....] ; comienzo de rutina de error 
       PUSH 08 
       CALL ....... 
       MOV EAX,8    ; c�digo de error 
       JMP ........ ; salta a los POPs y RET
 

Busca:

75 17 FF 15 B0 83 9F 00 6A 08
Y cambia 75 a EB. Esta vez si lo ejecutas, consigues error c�digo 0. Encuentras este c�digo cerca del RET:


       JNZ ........ ; salta si error 
       PUSH 2C      ; �todos los controles pasados! 
       CALL ....... 
       JMP ........ ; corre, baby, corre :-)
 

As� que simplemente debes cambiar jnz -> nop nop. La secuencia a buscar es 75 09 6A 2C y cambia 75 09 con 90 90.

Por fin el ejecutable modificado corre de nuevo con el original. �Pero qu� pasa con la copia, oigo que preguntas? �Hurra, tambi�n funciona porque quitaste los c�digos de error 7, 8 y 0 que tambi�n produc�a la copia! Por supuesto la copia debe tener el nombre de volumen correcto, de otro modo conseguir�s el mensaje 'Wrong disc'
(n.del t.: disco incorrecto)
Bien, yo no s� si esto es la manera m�s simple de crackear SecuROM: Yo escrib� todo esto especialmente con prop�sitos did�cticos. Debe funcionar en cualquier juego protegido con SecuROM. De modo que bye, bye SecuROM, nosotros no te extra�aremos :-)


    ****************** c�digo fuente para supcomp **************************** 
      
    #include <stdio.h> 
    #include <conio.h> 
    #include <stdlib.h> 
    #include <mem.h> 
    #define AREA 32768 
      
    FILE *f,*g; 
    unsigned char *b1,*b2; 
    char notfound[]="Can't open: %s\n"; 
    char seekerror[]="Seek error: %s\n"; 
    char readerror[]="Read error or end of file: %s\nAborting\n"; 
    long l,cont,ofsrc,ofdest; 
      
    void uscita(void) 
    { 
    if (b1) free(b1); 
    if (b2) free(b2); 
    if (f) fclose(f); 
    if (g) fclose(g); 
    } 
      
    void main(int argc, char *argv[]) 
    { 
    if (atexit(uscita)) 
    { 
    printf("Atexit error\n"); 
    exit(EXIT_FAILURE); 
    } 
    if (argc!=6) 
    { 
    printf("Supcomp v1.0 by Pedro '98\n\n" 
    "Usage: supcomp <src> <dest> <offset src> <offset dest> <length>\n" 
    "N�meros deben estar en hex si precedidos por 0x\n\n" 
    "El programa compara <length> bytes de <src> con el correspondiente\n" 
    "bytes en <dest> comienzan desde el especificado offsets\n" 
    "Solo las diferencias son escritas en el output\n"); 
    exit(EXIT_FAILURE); 
    } 
    if ((b1=(char *)malloc(AREA))==NULL) exit(EXIT_FAILURE); 
    if ((b2=(char *)malloc(AREA))==NULL) exit(EXIT_FAILURE); 
    if ((f=fopen(argv[1],"rb"))==NULL) 
    { 
    printf(notfound,argv[1]); 
    exit(EXIT_FAILURE); 
    } 
    if ((g=fopen(argv[2],"rb"))==NULL) 
    { 
    printf(notfound,argv[2]); 
    exit(EXIT_FAILURE); 
    } 
    ofsrc=strtol(argv[3],NULL,0); 
    ofdest=strtol(argv[4],NULL,0); 
    if (fseek(f,ofsrc,SEEK_SET)) 
    { 
    printf(seekerror,argv[1]); 
    exit(EXIT_FAILURE); 
    } 
    if (fseek(g,ofdest,SEEK_SET)) 
    { 
    printf(seekerror,argv[2]); 
    exit(EXIT_FAILURE); 
    } 
    if ((l=strtol(argv[5],NULL,0))==0) 
    { 
    printf("Wrong length\n"); 
    exit(EXIT_FAILURE); 
    } 
    while (l) 
    { 
    long letti,i; 
      
    if (l>=AREA) letti=AREA; 
    else letti=l; 
    if (fread(b1,1,letti,f)!=letti) 
    { 
    printf(readerror,argv[1]); 
    exit(EXIT_FAILURE); 
    } 
    if (fread(b2,1,letti,g)!=letti) 
    { 
    printf(readerror,argv[2]); 
    exit(EXIT_FAILURE); 
    } 
    for (i=0;i<letti;i++) 
    { 
    if (b1[i]!=b2[i]) 
    { 
    printf("%.8lx %.2x - %.8lx %.2x\n",cont+ofsrc+i, (unsigned
    int)b1[i],cont+ofdest+i,(unsigned int)b2[i]); 
    } 
    } 
    l-=letti; 
    cont+=letti; 
    } 
    exit(EXIT_SUCCESS); 
    } 
      
      
      
      
    ****************** c�digo fuente para supwrite ****************************   
    #include <stdio.h> 
    #include <conio.h> 
    #include <stdlib.h> 
    #include <mem.h> 
    #define AREA 32768 
      
    FILE *f,*g; 
    unsigned char *b1; 
    char notfound[]="Can't open: %s\n"; 
    char seekerror[]="Seek error: %s\n"; 
    char readerror[]="Read error or end of file: %s\nAborting\n"; 
    char writeerror[]="Write error: %s\n"; 
    long l,ofsrc,ofdest; 
      
    void uscita(void) 
    { 
    if (b1) free(b1); 
    if (f) fclose(f); 
    if (g) fclose(g); 
    } 
      
    void main(int argc, char *argv[]) 
    { 
    if (atexit(uscita)) 
    { 
    printf("Atexit error\n"); 
    exit(EXIT_FAILURE); 
    } 
    if (argc!=6) 
    { 
    printf("Supwrite v1.0 by Pedro '98\n\n" 
    "Usage: supwrite <src> <dest> <offset src> <offset dest> <length>\n" 
    "N�meros deben estar en hex si precedidos por 0x\n\n" 
    "El programa escribe <length> bytes de <src> al correspondiente\n" 
    "bytes en <dest> comienzan desde el correspondiente offsets\n"); 
    exit(EXIT_FAILURE); 
    } 
    if ((b1=(char *)malloc(AREA))==NULL) exit(EXIT_FAILURE); 
    if ((f=fopen(argv[1],"rb"))==NULL) 
    { 
    printf(notfound,argv[1]); 
    exit(EXIT_FAILURE); 
    } 
    if ((g=fopen(argv[2],"rb+"))==NULL) 
    { 
    printf(notfound,argv[2]); 
    exit(EXIT_FAILURE); 
    } 
    ofsrc=strtol(argv[3],NULL,0); 
    ofdest=strtol(argv[4],NULL,0); 
    if (fseek(f,ofsrc,SEEK_SET)) 
    { 
    printf(seekerror,argv[1]); 
    exit(EXIT_FAILURE); 
    } 
    if (fseek(g,ofdest,SEEK_SET)) 
    { 
    printf(seekerror,argv[2]); 
    exit(EXIT_FAILURE); 
    } 
    if ((l=strtol(argv[5],NULL,0))==0) 
    { 
    printf("Wrong length\n"); 
    exit(EXIT_FAILURE); 
    } 
    while (l) 
    { 
    long letti; 
      
    if (l>=AREA) letti=AREA; 
    else letti=l; 
    if (fread(b1,1,letti,f)!=letti) 
    { 
    printf(readerror,argv[1]); 
    exit(EXIT_FAILURE); 
    } 
    if (fwrite(b1,1,letti,g)!=letti) 
    { 
    printf(writeerror,argv[2]); 
    exit(EXIT_FAILURE); 
    } 
    l-=letti; 
    } 
    exit(EXIT_SUCCESS); 
    }
    




Ap�ndice de +Xoanon



 ------------------------------------------------------------------------------
                                    SecuROM
                            Ap�ndice al crack de Pedro
                              por xOANINO [UCF/CLASS]
 ------------------------------------------------------------------------------

Precisamente he le�do el ensayo de Pedro para SecuROM, un ensayo muy bueno.... Pero como todas las cosas italianas... no es un trabajo completo. Como nuestros incre�bles pol�ticos, �l hizo cosas f�ciles m�s dif�ciles de lo que realmente son como te mostrar� en este peque�o 'ap�ndice' (Yo no puedo escribir un ensayo completo, como siempre tengo chicas que me esperan... ya sabes :))
(n.del t.: No s� que tiene �ste muchacho contra los italianos, a m� personalmente me caen bastante bien, aunque como es normal me gustan m�s las italianas ;o�)

Sin embargo, un trabajo muy bueno Pedro... Aun cuando tu trabajo no est� al 100% completo, funciona... y es bueno ver que tambi�n Italia tiene (de hecho) algo de valor para mostrar en la escena del cracking!!

Bien... Aqu� est� el problema: Como todos pueden leer anteriormente en el ensayo de Pedro, �l descifra correctamente todo el material en la secci�n .text e .idata y parchea el .exe. Ok, as� es c�mo SecuROM debe ser crackeado.

As�... �qu� est� equivocado en el ensayo de Pedro? Bien, intenta usar su m�todo con (por ejemplo) un juego que quieres rasgar y usar sin el CD. No funcionar�. �Por qu�? Bien, el EXE producido por Pedro no esta reconstruido al 100%. Todav�a depende de las DLLs de SecuROM, y si no encuentra un CD en la unidad con el nombre y material correcto, el programa no correr�.

Y as� que, aqu� viene tu mega-ocupado, con chicas, estudios, codificando xOANINO al rescate para producir un ejecutable completamente reconstruido trabajando al 100% :)

Simplemente sigue estos 6 pasos:


1) Sigue el ensayo de Pedro hasta el BPX GetdrivetypeA / BPX en el RET algunas p�ginas abajo.

2) Como puedes notar, algunas l�neas sobre el ret (donde Pedro remienda el �ltimo JNZ) all� hay un JMP EAX. Ahora... �qu� es este JMP? Es el salto al entrypoint del programa correcto, cuyo c�digo ya est� descifrado siguiendo el ensayo de Pedro.

3) Apunta el valor de EAX, y simplemente escribe este valor al campo entrypoint de la cabecera de PE (PE+28h. debe estar en offset A8h en cada archivo PE). Considera que debes restar de EAX el valor del imagebase:

  Ejemplo:
  EAX = 418DB4h (Omnia99 entrypoint)

  Imagebase = 400000h
  valor a escribir = 418DB4-400000 = 018DB4h (revertido, por supuesto)

4) Ahora tambi�n puedes eliminar las secciones no necesitadas... �como la secci�n .CMS_D y la secci�n .PETITE!! (usa procdump para esto, o hazlo a mano)

5) Wow, tambi�n puedes suprimir el CMSxx.DLL !

6) ri-Wow, el EXE corre sin m�s problemas !!!!


Eso es todo... es solamente un ' ap�ndice':) �Pedro hizo un trabajo muy bueno de cualquier modo!





Ap�ndice de GrimFandango (Pedro)


Hace algunos d�as yo encontr� un peque�o cambio en la protecci�n de SecuROM que fue hecho por Sony en un reciente juego, as� que decid� escribir de nuevo sobre esto. El ensayo anterior todav�a es v�lido, pero, como nosotros veremos, hay un poco m�s de trabajo que hacer para crackear el nuevo SecuROM. En primer lugar, me gustar�a agradecer a +Xoanon por escribir su ' ap�ndice'. Yo realmente hab�a hecho las cosas m�s dif�ciles de lo que eran. Con su idea simple, nosotros no necesitamos ya poner la longitud de WriteProcessMemory a cero, ni tenemos que crackear los c�digos de error antes del RET, porque simplemente saltamos todo el c�digo de SecuROM y nos vamos directamente al punto de entrada real. Tengo todav�a mucho que aprender ... :-)

Pero hay algo m�s que decir sobre SecuROM.

Bien, en mi ensayo yo era un poco impreciso. Recuerdas que yo cracke� Might and Magic VI como un ejemplo, y por supuesto eso funcion� (yo le� el FAQ de Fravia+ y no quiero escribirle diciendo ' Mi invalido crack no funciona' despu�s de que ha publicado mi trabajo :-). Tambi�n dije que Conflict Freespace y Grim Fandango eran lo mismo. Es aqu�, donde yo he sido impreciso. De hecho yo s�lo ten�a una copia no-funcional de esos dos juegos, pero vi que hab�a el mismo descifrado multi-pasos, as� que yo asum� que la protecci�n entera era la misma.

Despu�s algunos d�as yo consegu� el original de Grim Fandango y me sent� defraudado cuando vi que Sony dejaba el descifrado multi-pasos, pero se agreg� algo m�s a la protecci�n. As� que yo quiero comportarme mejor que mis aborrecidos pol�ticos italianos y yo no quiero permitir que este crack sea otra cosa italiana inacabada :-)

En primer lugar, tienes que hacer la copia usual del ejecutable original descomprimido llamado GRIM2.EXE. Entonces debes parchear las cuatro partes del c�digo como describ� en mi primer ensayo. Puedes saltar la parte en donde puse a cero longitud para WriteProcessMemory o donde cracke� los c�digos de error, porque ya no necesitaremos esa parte del c�digo de SecuROM. Tambi�n, debes poner un breakpoint en ' jmp eax' como +Xoanon se�al�, para conseguir el punto de entrada real, y cambiarlo en la cabecera de PE. Pero si lo ejecutas, no funciona. �Por qu�? S�gueme y lo descubrir�s.

Ahora deja un breakpoint de nuevo en WriteProcessMemory y ejecuta el original GrimFandango.exe (con la copia original en el lector). Vemos que all� est� el mismo descifrado de las cuatro partes, pero despu�s de eso, WriteProcessMemory es llamado muchas m�s veces durante la ejecuci�n del juego, y s�lo son parcheados 4 bytes cada vez. Cuando estamos dentro del breakpoint si escribimos ' u (@esp+8)-2 ' para ver donde los datos est�n siendo escritos, siempre vemos la misma LLAMADA:

CALL [008D6218] (por supuesto esto cambia de juego a juego)

A prop�sito, esto es justamente el punto desde donde se llam� el procedimiento de SecuROM en [008D6218], y es este procedimiento el que est� llamando a WriteProcessMemory ahora. Si apretamos F11 podemos ver lo que pasa. Esa llamada se ha cambiado a:

CALL [KERNEL32!GetVersion]

(esto es simplemente un ejemplo, cada llamada es cambiada a su valor original, es decir el valor que estaba en el juego sin protecci�n antes de que Sony se entretuviera con �l :-)

Nosotros lo hemos entendido ahora. Todo el tiempo el juego desprotegido ten�a que llamar una rutina del sistema, o incluso a una de sus propias rutinas, Sony guard� la direcci�n de la LLAMADA en una tabla, y hizo a la llamada apuntar a una rutina de SecuROM. Cuando esta rutina es ejecutado, esto puede entender desde donde se llam� mirando el valor de retorno en la pila, entonces parchea el c�digo y as� la pr�xima vez la llamada se har� directamente. Al final debe dar el control a la rutina que ser�a llamada, y logra esto con un ' jmp eax' (en nuestro ejemplo eax contendr� la direcci�n de GetVersion). Desgraciadamente esto sigue durante la ejecuci�n entera del programa. Pero no nos gusta mantener a semejante aburrido vecino como una parte del c�digo de SecuROM, nosotros queremos eliminarlo completamente.

En primer lugar debemos ver lo que es la direcci�n real de esta rutina de SecuROM:
en la localizaci�n [8D6218] nos encontramos la direcci�n 8CB050.

Ahora tomemos Wdasm y desensambla GRIM2.exe (as� el c�digo en 8CB050 ya estar� descifrado) . Bien realmente no necesitas desensamblarlo para hacer el crack, porque yo explicar� todos los pasos para hacerlo despu�s, pero es �til aprender, porque esa es la raz�n real de por que est�s estudiando reversing y para lo que est�s leyendo esto, no simplemente para copiar algunos juegos tontos, �o tu s�? :-)

Puedes ver simplemente el c�digo con SoftICE cuando est�s dentro del procedimiento. Vamos a 8CB050. Aqu� nosotros vemos muchas referencias como �stas:


       :008CB069 8B0DBCDF8E00            MOV ECX, DWORD PTR [008EDFBC] 
        ...... 
       :008CB072 890DBCDF8E00            MOV DWORD PTR [008EDFBC], ECX 
        ...... 
       :008CB0AA 8A8240FC8E00            MOV AL, BYTE PTR [EDX+008EFC40] 
        ......
  

As� que ah� debe estar la tabla para descifrar todas las llamadas. Nota que no nos preocupamos de c�mo esta tabla est� hecha. Apenas necesitamos reconstruir el ejecutable de la misma manera que hicimos con los cuatro parches. La rutina termina as�:


       :008CB385 FF1518E78E00            CALL DWORD PTR [008EE718] 
                                         ; llama a WriteProcessMemory 
      
       :008CB38B 61                      POPAD 
       :008CB38C 8B45F8                  MOV EAX, DWORD PTR [EBP-08] 
       :008CB38F 8BF0                    MOV ESI, EAX 
       :008CB391 8B06                    MOV eax, DWORD PTR [ESI] 
       :008CB393 5F                      POP EDI 
       :008CB394 5E                      POP ESI 
       :008CB395 5B                      POP EBX 
       :008CB396 8BE5                    MOV esp, EBP 
       :008CB398 5D                      POP EBP 
      
       :008CB399 FFE0                    JMP EAX       ; aqu� hace la llamada 
                                                       ; original del juego 
      
       :008CB39B 5F                      POP EDI 
       :008CB39C 5E                      POP ESI 
       :008CB39D 5B                      POP EBX 
       :008CB39E 8BE5                    MOV ESP, EBP 
       :008CB3A0 5D                      POP EBP 
       :008CB3A1 C3                      RET
 

Hmm, ahora una idea interesante me viene a la mente. En primer lugar la rutina no usa EBX, as� que nosotros podemos utilizarlo para conseguir el control despu�s de llamar a la rutina. Entonces nosotros podemos ' simular' las llamadas del programa usando el siguiente peque�o programa en ensamblador que puede ensamblarse en SoftICE en una zona sin usar de Adump (pobre Adump, lo estamos cargando excesivamente :-):

  
       :00000100 B9FA0F4F00              MOV ECX, 004F0FFA 
                                    ; esto es (longitud - 6 bytes) de secci�n .text 
                                    ; por supuesto tendr�s que cambiarlo con 
                                    ; los diferentes juegos 
      
       :00000105 BA00104000              MOV EDX, 00401000 
                                    ; esto es direcci�n de comienzo de secci�n .text 
      
       :0000010A 803AFF                  CMP BYTE PTR [EDX], FF 
                                    ; FF 15 18 62 8D 00 es la secuencia que 
                                    ; corresponde para call [008d6218], y 
                                    ; tendr�s que cambiarlo seg�n 
                                    ; el juego que est�s crackeando. 
                                    ; Estamos buscando esta secuencia en 
                                    ; el c�digo 
      
       :0000010D 7530                    JNE 0000013F 
                                    ; no encontrada, contin�a buscando 
      
       :0000010F 807A0115                CMP byte ptr [edx+01], 15 
       :00000113 752A                    JNE 0000013F 
       :00000115 807A0218                CMP byte ptr [edx+02], 18 
       :00000119 7524                    JNE 0000013F 
       :0000011B 807A0362                CMP byte ptr [edx+03], 62 
       :0000011F 751E                    JNE 0000013F 
       :00000121 807A048D                CMP byte ptr [edx+04], 8D 
       :00000125 7518                    JNE 0000013F 
       :00000127 807A0500                CPM byte ptr [edx+05], 00 
       :0000012B 7512                    JNE 0000013F 
      
       :0000012D 8D4206                  LEA EAX, DWORD PTR [EDX+06] 
                                    ; �encontrada! Ahora 'simulamos' la 
                                    ; llamada: ponemos 
                                    ; la direcci�n de retorno en la pila como 
                                    ; la llamada que fue hecha por el programa  
      
       :00000130 60                      PUSHAD 
                                    ; ...pero primero mejor guardamos nuestros 
                                    ; preciosos registros 
      
       :00000131 50                      PUSH EAX 
                                    ; ah, ahora la direcci�n de retorno 
                                    ; correcta est� en la pila
                                    
      
       :00000132 BB3D010000              MOV EBX, 0000013D 
                                    ; cargamos ebx con la direcci�n de la siguiente: 
                                    ; instrucci�n de 'pop eax', as� recobraremos 
                                    ; el control despu�s de parchear. Cambia este valor 
                                    ; seg�n tu offset in Adump 
      
       :00000137 FF2518628D00            JMP DWORD PTR [008D6218] 
                                    ; y ahora damas y caballeros, infrinjamos las reglas 
                                    ; SecuROM (como siempre, cambia 008d6218 seg�n 
                                    ; el juego que est�s crackeando) 
      
       :0000013D 58                      POP EAX 
       :0000013E 61                      POPAD 
      
       :0000013F 42                      INC EDX 
      
       :00000140 E2C8                    LOOP 0000010A 
                                    ; la b�squeda seguir� en... 
      
       :00000142 CC                      INT 03 
                                    ; terminado, atr�s a SoftICE
   

Ejecutemos GrimFandango.exe con el breakpoint de +Xoanon sobre ' jmp eax'. Ahora nosotros estamos a punto de entrar en el programa (recuerdas, nosotros siempre estamos ejecutando GrimFandango.exe porque GRIM2.EXE no funciona). Con ' u 8cb050 ' nosotros vemos nuestra rutina principalmente odiada :-).

Desplazando algunas p�ginas abajo vemos el ' jmp eax' sobre el que yo estaba habl�ndote. Esto debe cambiarse a ' jmp ebx', para permitir a nuestro diminuto (diminuto pero eficaz :-) programa en ensamblador recobrar el control. Entonces apuntamos el eip actual, ponemos ' i3here on' y ponemos eip al principio de nuestro c�digo en ensamblador. F5, entonces nosotros esperamos un poco (si ni tu ni yo hemos cometido ning�n error, de otra manera podr�as esperar para siempre por Windows para resucitar :-) Wow, est� terminado. �As� que qu� pas�? Bien, todas las ' call [008d6218] ' se deben de haber reemplazado con su colega original correcto. Para decir la verdad es posible (pero muy improbablemente) que una secuencia falsa FF 15 18 62 8D 00 que no representa a la antedicha llamada se haya cambiado incorrectamente. Es improbablemente, no obstante, porque 6 bytes son un modelo muy espec�fico. As� que simplemente prob�moslo primero, si todo choca -o algo peor - simplemente investigaremos aburridamente todas las localizaciones reemplazadas.

Debemos descargar ahora desde 401000 al final de la secci�n .text la que puede verse con 'map32' (comienzo=401000, longitud=4f1000 => fin=8f2000). El problema es ahora que algunas p�ginas no est�n cargadas en memoria, as� cuando nosotros escribimos el comando "m" conseguimos un error. Lo que sigue es una idea para descargar aun cuando algunas p�ginas no est�n cargadas en la memoria: sup�n que la zona de descarga de Adump empieza en 'pippo' (con una imaginaci�n italiana incre�ble :-). Debemos ensamblar este peque�o programa con SoftICE cerca del final de la zona de Adump, pon pippo+4ff000 (ah, recuerda aumentar el �rea de Adump por supuesto, si lo necesitas, como en este caso que debe ser por lo menos 0x500000 bytes):


    PUSHAD 
    PUSHF 
    CLD 
    REP 
    MOVSB 
    POPF 
    POPAD 
  

Ok, cuando necesitamos descargar apuntamos el eip actual, entonces cambiamos eip a pippo+4ff000, caminamos sobre pushad y pushf, entonces cargamos ecx manualmente con la longitud de la descarga (en este caso 4f1000), esi con el offset (401000) del comienzo, y edi con el offset (pippo) de destino y caminamos sobre las instrucciones restantes.

�Cuando hemos terminado de descargar nosotros podemos restaurar el eip que antes apuntamos, y GrimFandango continuar� apaciblemente incluso sin saber que nos lo hemos vuelto del rev�s! : -) Ah, s�lo una nota de advertencia: antes de descargar o llamar a mi rutina en ensamblador, quita TODOS los breakpoints, de lo contrario tendr�s ' int 3 ' no deseados en la descarga (como yo hice :-).

La �ltima parte es muy f�cil: mira donde empieza la zona descargada en el ejecutable y reempl�zalo con supwrite (bien, mi conocimiento de ejecutables PE es limitado, pero yo pienso que es ok para reemplazarlo todos. Por otra parte puedes escribir un peque�o programa en C para reemplazar s�lo las FF 15 18 62 8D 00 secuencias con lo correcto desde la descarga). Si el reemplazando completo es correcto, ni siquiera necesitas los primeros cuatro pasos: con este �nico descarga y el punto de entrada correcto lo consigues todos.

Que cosa tan bonita: �nuestro GrimFandango no-funcional est� vivo de nuevo! No est� tan mal para un esqueleto :-)).





Outcast Ap�ndice (R!SC)


Herramientas
* HexEditor (Hacker's View)
* SoftICE 3.2x + Memory Dumper (IceDUMP)
* ProcDump
* RPP 1.2i
* TASM 5.0


Mi objetivo, LOADER.EXE, comprimido con ' Petite' del juego ' Outcast' de Appeal/Infogrames (bonito objetivo, porque 50% del tiempo no quiere correr aun cuando tengas el CD correcto).


Yo he estado jugando con SecuROM... Me encanta el tutorial de Pedro sobre �l (
http://crknotez.cjb.net), y esto me ayud� a que crackeara algunos juegos de SecuROM, pero, �ay!, pienso que Sony ha puesto al d�a SecuROM, as� que el tutorial de Pedro no ayuda mucho ahora... �Recuerdas c�mo ello parec�a que supiera que hab�as estado corrigi�ndolo, como y se neg� ya a correr, hasta un reseteo ? Bien, ch�pate esto , y antes hab�a unos breakpoints seguros que podr�as usar, bpx writeprocessmemory, bpx getdrivetypea, erm, bien, ahora los conoce, y tambi�n se niega a correr... �ay!, nos encontramos con algunos problemas.. :D

�bien, eres un cracker o un rat�n?? he, he, nosotros no nos asustamos de NINGUN SecuROM ...

Digamos que quiero poner un bpx en writeprocessmemory, para averiguar donde descifra los datos en el c�digo de los programas, consigue una interrupci�n, la primera donde descifra alg�n c�digo de SecuROM, entonces ninguna m�s, el programa corre en un loop continuo, ctrl-alt-del para eliminarlo, entonces �l habitualmente correr� de nuevo... digamos que quiero evitar la parte de descifrado del c�digo de �l, y romper en GetDriveTypea, no no no, si tienes cualquier punto de ruptura puesto, �l simplemente correr�, y despu�s de quitarlos, seguir� sin correr ...

Yo not� una cosa, CMS16.DLL, CMS32_95.DLL & CMS32_NT.DLL est�n dentro del programa, y son escritos al disco cuando es ejecutado... probablemente para evitar que los manoseemos.. :D si sabe que has estado corrigi�ndolo, sale sin cerrar el manipulador del archivo para CMS16.DLL. Prueba a suprimirlo, consigues un bonito error, 'Cannot delete CMS16: The specified file is being used by Windows'.

Bien, esto es una pista, quiz�... quita todos los breakpoints, bpx createfilea ... ejecuta el juego protegido por SecuROM: algunas de las primeras interrupciones no son importantes... Windows cargando el archivo, entonces una pausa corta, d�nde se descomprime, entonces �stos son los �nicos que queremos, el primero se abre, �el segundo?

CMS16.DLL? el tercero, CMS16.DLL ... espera, echa una mirada a este c�digo ...

0137:005A1298  50                  PUSH    EAX                      <-- ptr para x:\xx\cms16.dll
0137:005A1299  FF1534685C00        CALL    [KERNEL32!CreateFileA]
0137:005A129F  8945DC              MOV     [EBP-24],EAX
0137:005A12A2  837DDCFF            CMP     DWORD PTR [EBP-24],-01   <-- �l ya est� all�, y 
0137:005A12A6  753B                JNZ     005A12E3                   - no puede ser abierto de nuevo..
0137:005A12A8  C70580645C0000000000MOV     DWORD PTR [005C6480],00000000
0137:005A12B2  6A00                PUSH    00
0137:005A12B4  6A00                PUSH    00
0137:005A12B6  6A03                PUSH    03
0137:005A12B8  6A00                PUSH    00
0137:005A12BA  6A00                PUSH    00
0137:005A12BC  6800000080          PUSH    80000000
0137:005A12C1  8D8D38FFFFFF        LEA     ECX,[EBP-00C8]
0137:005A12C7  51                  PUSH    ECX                      <-- mismo ptr para cms16.dll
0137:005A12C8  FF1534685C00        CALL    [KERNEL32!CreateFileA]
0137:005A12CE  8945DC              MOV     [EBP-24],EAX
0137:005A12D1  837DDCFF            CMP     DWORD PTR [EBP-24],-01   <-- oh mierda, todav�a est� a -1
0137:005A12D5  750A                JNZ     005A12E1                   - pero forzando este salto
0137:005A12D7  6A00                PUSH    00                         - correr� de nuevo :D    
0137:005A12D9  E8022C0000          CALL    005A3EE0
0137:005A12DE  83C404              ADD     ESP,04
0137:005A12E1  EB0A                JMP     005A12ED
0137:005A12E3  C70580645C0001000000MOV     DWORD PTR [005C6480],00000001
0137:005A12ED  8B15C4675C00        MOV     EDX,[005C67C4]

 

Bien, mira, intenta crear este archivo, y si falla, devuelve el c�digo FFFFFFFF, y sale... si nosotros lo enga�amos, haci�ndolo pensar que puede crear este archivo, s�lo forzando cualquiera de estos saltos, corre de nuevo :D

As� no todo est� perdido.. oops, nosotros todav�a no podemos bpx writeprocessmemory, o bpx getdrivetypea, as� que las cosas son m�s complicadas, pero no imposible ...

Lo que not� sobre las versiones m�s viejas de SecuROM, es que descifra 20 KB de c�digo del programa, alrededor del punto de entrada original, entonces verifica el disco, y si el correcto est� dentro, descifra 200h bytes m�s de c�digo en el punto de entrada original... el otro c�digo descifrado no era tan importante, como lo era �ste c�digo de SecuROM... teor�a, rastrea Petite hasta que haya desempaquetado el programa, descarga la memoria, bpx en el punto de salida del c�digo de SecuROM, y cuando lo alcances, descargas la memoria de nuevo, y simplemente haces una comparaci�n del archivo, debes encontrar un bonito bloque de 20 KB de c�digo descifrado en el segundo volcado... arrgh! �c�mo hacemos para el bpx en el punto de salida del c�digo de SecuROM?? eh, no hagas ph34r, es f�cil :D

Yo espero que tengas ya jodido al programa, as� que ya no correr�, y tenemos que hacerle correr cambiando uno de los saltos despu�s de la llamada a CreateFileA, ' CMS16.DLL '... good ... Yo utilic� mi arriesgado parcheador de procesos para hacer un loader que arregl� esto para m� ...

T=10000:
F=loader.exe:
O=securomfix_cc.exe:
P=5A12A6/75/CC: ; 0137:005A12A6 753B JNZ 005A12E3
$

Cambiar esto a un EB le hace correr todo el tiempo, pero Yo quise romper aqu�, as� que lo cambie a CC, INT 03, entonces en SoftICE, bpint 03, X. ejecuta el loader... eh, cuando rompa, no te olvides de cambiar el CC a un EB... e eip eb ... bien, cuando rompa, y hayas cambiado tu INT 03 a un JMP, simplemente haz tu ventana de c�digo grande y bonita, y despl�zate, ctrl-page-down.

Aqu� es donde nosotros normalmente podr�amos romper, pero bpx getdrivetypea o simplemente bpx 5a25a2, el los conoce y detiene la ejecuci�n... malo, sigue desplaz�ndote


0137:005A259B  52                  PUSH    EDX
0137:005A259C  FF15E04F5C00        CALL    [KERNEL32!GetDiskFreeSpaceA]
0137:005A25A2  8D8548FCFFFF        LEA     EAX,[EBP-03B8]
0137:005A25A8  50                  PUSH    EAX
0137:005A25A9  FF15004B5C00        CALL    [KERNEL32!GetDriveTypeA]
0137:005A25AF  83F805              CMP     EAX,05

 

Mira, otro lugar donde normalmente podr�amos romper, pero, �ay!, no podemos nunca m�s... sigue desplaz�ndote ...


0137:005A28E0  8D9548FCFFFF        LEA     EDX,[EBP-03B8]
0137:005A28E6  52                  PUSH    EDX
0137:005A28E7  FF15E04F5C00        CALL    [KERNEL32!GetDiskFreeSpaceA]
0137:005A28ED  8D8548FCFFFF        LEA     EAX,[EBP-03B8]
0137:005A28F3  50                  PUSH    EAX
0137:005A28F4  FF15004B5C00        CALL    [KERNEL32!GetDriveTypeA]
0137:005A28FA  83F805              CMP     EAX,05

 

Yippee!! este es otro lugar donde nosotros romper�amos, muchas muchas p�ginas de c�digo han pasado ante nosotros, y lo sabemos, aqu� es donde el c�digo del securom termina, y salta al programa apropiado :D


0137:005A31A8  B8A1535000          MOV     EAX,005053A1
0137:005A31AD  90                  NOP
0137:005A31AE  90                  NOP
0137:005A31AF  50                  PUSH    EAX
0137:005A31B0  EB03                JMP     005A31B5
0137:005A31B2  58                  POP     EAX
0137:005A31B3  FFE0                JMP     EAX

  

Hmm, buenas noticias, podemos bpx aqu� 0137:005A31B3 FFE0 JMP EAX, y todo estar� bien... el programa todav�a funciona bien :D yah... ��Bien!!

Aqu� hay otro loader para ayudarnos en nuestra tarea ...

T=10000:
F=loader.exe:
O=securom.cc.jmp.eax.exe:
;P=5A12A6/75/EB: ; eh, mi pc choc� por alguna raz�n, as� que esto no es necesario todav�a :)
P=5A31B3/FF/CC: ; Solamente quiero romper en el punto de salida de securom, el jmp eax ...
$

Bonito R!SC, casi es el momento para ser destructivo :D


Ahora, usando este loader, cu�ndo el softice rompe en el int 03, nosotros podemos conseguir nuestro c�digo descifrado, �qu� sobre nuestras arriesgadas llamadas? �recuerdas al viejo securom? �call dword ptr [securom] para cada importaci�n? �y si remontaras encima de �l, el bonito c�digo del securom reemplaz� [securom] con la direcci�n real de la importaci�n a fuera IAT en alguna parte en memoria? he, he, bien, jodido si esto trabaja ahora :( Mira aqu� ...

Esto es mi punto de entrada de programa original, mira 005053C7.. eso es donde la api llama a GetVersion, pero llama al c�digo de securom, que a un tiempo, jmp a GetVersion, remonta en una de las llamadas, entonces desplaza la ventana del c�digo hasta un jmp eax... pon un breakpoint en este ... y ejec�talo ...


0137:005053A1  55                  PUSH    EBP
0137:005053A2  8BEC                MOV     EBP,ESP
0137:005053A4  6AFF                PUSH    FF
0137:005053A6  6810EB5100          PUSH    0051EB10
0137:005053AB  68C0525000          PUSH    005052C0
0137:005053B0  64A100000000        MOV     EAX,FS:[00000000]
0137:005053B6  50                  PUSH    EAX
0137:005053B7  64892500000000      MOV     FS:[00000000],ESP
0137:005053BE  83EC58              SUB     ESP,58
0137:005053C1  53                  PUSH    EBX
0137:005053C2  56                  PUSH    ESI
0137:005053C3  57                  PUSH    EDI
0137:005053C4  8965E8              MOV     [EBP-18],ESP
0137:005053C7  FF1528C25A00        CALL    [005AC228]       <-- llamada [securom] ...
0137:005053CD  33D2                XOR     EDX,EDX
0137:005053CF  8AD4                MOV     DL,AH
0137:005053D1  891594585900        MOV     [00595894],EDX
0137:005053D7  8BC8                MOV     ECX,EAX
0137:005053D9  81E1FF000000        AND     ECX,000000FF
0137:005053DF  890D90585900        MOV     [00595890],ECX

  

mi 'jmp eax' estaba en 59F16F

Rompe debido a BPX #0137:0059F16F (ET=286.97 microsegundos)
:?eax
BFF9137C 3220771708 (-1074195588) "��|"
:�qu� eax?
El valor BFF9137C es (a) KERNEL32!GetVersion <-- ha

Ahora, teor�a, el petite desempaqueta el c�digo, y desempaqueta una tabla de direcci�n de importaci�n real :D, nosotros apenas tenemos que encontrar el IAT real en memoria, buscamos las importaciones correctas para nuestras llamadas, y arreglamos las llamadas para llamar nuestra tabla de importaci�n en lugar del c�digo del securom ...

:s 400000 l ffffffff 7c 13 f9 bf
modelo encontrado en 0137:0051B110 (0011B110)
:s
modelo encontrado en 0137:005C6530 (001C6530)
:s
modelo encontrado en 0137:005CA3E8 (001CA3E8)
:s
modelo encontrado en 0137:0095067C (0055067C)

Bien, nosotros conseguimos cuatro opciones por el momento, Yo rastre� el c�digo desempaquetado, y simplemente se detiene antes de que el c�digo de securom se ejecuta... entonces busca de nuevo ...

:s 400000 l ffffffff 7c 13 f9 bf
modelo encontrado en 0137:005CA3E8 (001CA3E8)

Yippee, s�lo encuentra uno... as� si cambio esta l�nea ...


0137:005053C7 FF1528C25A00 CALL [005AC228]
a

0137:005053C7 FF15E8A35C00 CALL [KERNEL32!GetVersion] ; llamada [005CA3E8]

Eso es una llamada arreglada, s�lo deja aproximadamente 300 para irse:) deja algo de c�digo ...

WHOOPS, Yo codifiqu� algunas cosas, arregl� todo, descargu� la memoria, lo copi� y lo pegu� en mi anterior volcado, y funcion� ok... pero ... no funcion� en Win95 (Yo trabajo con Win98) ...

M�s all� el debugging revel� alg�n c�digo as� ...


015F:00508FE0  55                  PUSH    EBP
015F:00508FE1  8B2D68B15100        MOV     EBP,[KERNEL32!CloseProfileUserMapping]
015F:00508FE7  56                  PUSH    ESI
015F:00508FE8  57                  PUSH    EDI
015F:00508FE9  33DB                XOR     EBX,EBX
015F:00508FEB  33F6                XOR     ESI,ESI
015F:00508FED  33FF                XOR     EDI,EDI
015F:00508FEF  3BC3                CMP     EAX,EBX
015F:00508FF1  7533                JNZ     00509026
015F:00508FF3  FFD5                CALL    EBP

  Mira esta l�nea :
  

015F:00508FE1  8B2D68B15100      MOV     EBP,[KERNEL32!CloseProfileUserMapping]


  

Es realmente MOV EBX, DWORD PTR [0051B168], moviendo una direcci�n del api desde el primer IAT nosotros encontramos... lo �nico que no es suyo cuando es desempaquetado... no estropearon securom con esto, porque no es una llamada directa al IAT.. bien, desempaquet� el ejecutable con ProcDump... lo ejecut� con LOADER32, y comprob� la memoria en 51B168, conten�a 72981200... obviamente, como esto es reemplazado con la direcci�n lineal de la funci�n del api, esto era mi primera cosa 'rota'.. Yo busqu� en el exe desempaquetado por 72981200, y encontr� dos lugares, uno justo antes de todos los nombres de las funciones importadas, y el otro, uno que ya hab�a encontrado antes, adem�s estudiando el exe con mi editor hex, localic� el comienzo de la tabla de importaci�n.. la lista de mi image_import_descriptors, 8 de ellos, seguidos por 14h bytes nulos... terminando el descriptor :D yippee!! simplemente usa ProcDumps PE Editor, edita la estructura del directorio, dirige la tabla de importaci�n al real... para este programa, era 528ed8, - la imagebase hace 128ed8 ...

Bien, ejecut�ndolo de nuevo con LOADER32, comprueba la direcci�n 51b168, s�, est� escrito encima con la direcci�n lineal de la funci�n del api correcta... grande... a medio camino de el ...


Algo de c�digo de nuevo ...


;------------------------------------------------------------------------------
; R!SC's dodgy call fixer for 'newer' SecuROM
; (c) august 27th 1999 risc@notme.com
;
; tasm32 /mx /m3 /z /q call_fix
; tlink32 -x /Tpe /aa /c call_fix,call_fix
;
; copia y pega el c�digo dentro del ejecutable comprimido de securom.. 
;Yo prefiero la cabecera de pe ...   
; Rompe en jmp eax (en el c�digo de securom, jmp orig_entry_point)  
; recodifica el 'jmp eax' en el c�digo de la llamada [securom] a jmp ebx  
; i3here on, faults on  
; copia el c�digo a una zona de memoria vac�a.. m 400300 l 60 530000, r eip 530000, ejec�talo :0
;------------------------------------------------------------------------------

.486P
.Model Flat

.code
main:
    call    @1  ; por favor excusa mi primer esfuerzo del tipo un c�digo reubicable
@1:
    pop ebx
    mov esi, ebx
    add ebx, offset here-offset @1  ; devuelve direcci�n desde jmp [5ac228]
    add esi, offset boring-offset @1
    mov edx, 401000h
    mov ecx, 51b000h-401000h    ; mi iat empieza en 51b000, as� que el c�digo termina ,espero, antes de �l
search_loop:
    cmp [edx], 0c22815ffh   ; busca modelo para llamada [005AC228]
    jne try_again
    cmp word ptr [edx+4],005ah  ; -
    jne try_again
    
    lea eax, [edx+6]        ; consigue la direcci�n que ser� empujada a la pila
    pushad
    push eax
    ;jmp dword ptr [5ac228h]
    db 0ffh,25h,28h,0c2h,5ah,0  ; jmp blah..

here:                   ; k, retornamos aqu� desde el c�digo de securom, la direcci�n del api est� en EAX
    mov edx, 51b000h    ; comienzo de la direcci�n de mi *real* IAT, primer tronco..
search_iat:
    cmp [edx],eax
    jz  got_match
    inc edx
    cmp edx, 51b2a0h
    jne search_iat
    pop eax         ; seguridad, si no puede encontrar una pareja para lo que est� en EAX en nuestro IAT
    popad
    int 03          ; la pareja no fue encontrada, rompe en int 03, apunta la direcci�n en EDX
    jmp try_again   ; y arr�glalo a mano..
got_match:
    mov [esi+4],edx ; guardando la direc de la importaci�n de la direcci�n conseguimos una pareja para
    pop eax
    popad
    mov eax, [esi+4]    ; recupera la direcci�n de la importaci�n en nuestro IAT
    mov [edx+2], eax    ; p�galo encima de 005ac228 en la llamada [securom]
try_again:
    inc edx
    mov [esi],edx   ; guarda la �ltima direcci�n que estaba en EDX.. (en caso de alg�n problema..)
    dec ecx
    jne search_loop
    int 03
    nop
boring:
end main
;------------------------------------------------------------------------------

  
  

Correcto, comp�lalo, ed�talo en hex y edita en hex el exe de SecuROM comprimido, corta y pega el c�digo en alguna parte del fixer de la llamada en el ejecutable securom.. Yo escog� el offset 300h del archivo, en la cabecera del pe ...

Ejecuta tu loader que rompe en el punto de salida de securom. mueve el c�digo desde la cabecera del pe a alguna otra parte si no.. m 400300 l 100 530000 , r eip 530000 ...

Pon un bpx en JMP [005AC228], y ejec�talo. cuando consigas una interrupci�n, remonta en el jmp, y desplaza tu ventana del c�digo hasta que veas alg�n c�digo as� ...


015F:0059F15E  83C408              ADD     ESP,08
015F:0059F161  61                  POPAD
015F:0059F162  8B45F4              MOV     EAX,[EBP-0C]
015F:0059F165  8BF0                MOV     ESI,EAX
015F:0059F167  8B06                MOV     EAX,[ESI]
015F:0059F169  5F                  POP     EDI
015F:0059F16A  5E                  POP     ESI
015F:0059F16B  5B                  POP     EBX
015F:0059F16C  8BE5                MOV     ESP,EBP
015F:0059F16E  5D                  POP     EBP
015F:0059F16F  FFE0                JMP     EAX

  

Entonces cambia el jmp eax que ser�a JMP a la llamada de API, a JMP EBX... para saltar atr�s a nuestra rutina de llamada ama�ada

:a 59f16f
0137:0059F16F jmp ebx

bc*, i3here on, faults on, a causa de que queremos atrapar cualquier error, y softice romper� si golpea cualquiera de nuestras int 03's ...

Bien, de cualquier modo, ejecuta el c�digo, y cruza tus dedos... Yo consegu� algunos errores, tres llamadas devolvieron direcciones err�neas, as� que no podr�a encontrarlos en mi IAT, y dos llamadas causaron una ca�da... con faults on, softice cogi� la ca�da, y todo lo que tuve que hacer fue mirar en la direcci�n de memoria al final de mi c�digo, donde se almacena el contador de direcci�n, para ver qu� llamada lo provoc� ...

502bdd lo provoc�, y despu�s de arreglar eso, 50ce1c lo provoc�, as� que cuando lo ejecut� de nuevo, revis� aqu�llas situaciones de memoria, reemplazando el FF 15 con CC 15 que detuvo el c�digo encontrando el modelo de byte correcto, as� deteniendo la ca�da, e investigando esas llamadas a mano ...

Tambi�n rompi� en este int 03 tres veces ...

int 03 ; la pareja no fue encontrada, rompe en el int 03, apunta la direcci�n en EDX jmp try_again ; y arr�glalo a mano ...
Simplemente apunta la direcci�n en edx, y contin�a, nosotros podemos investigar esas llamadas a mano tambi�n ...

Las llamadas malas eran 507c39, 50a324 50e0be, as� que ejecuta el programa con tu interrupci�n en el punto de salida de securom, edita el eip para apuntar a una de esas llamadas arriesgadas, y remonta, rompe en el jmp eax... y busca la direcci�n del api en tu IAT a mano :D, despu�s de que todas las llamadas est�n arregladas, vuelca la memoria, pagein 400000 11b000 c:\callsfixed.dat .. copia y pega esto dentro del archivo que desempaquetaste con ProcDump, y arregla la direcci�n del IAT en la cabecera del pe ...

Cruza tus dedos, ejec�talo :D hey, funciona :P

�Eso es! SecuROM es un poco m�s divertido esta vez por todas partes, pero si no fuera por Pedro y +Xoanon, yo dudo que este tutorial hubiera sido posible. En los tres d�as o as� que este crack me llev�, yo aprend� mucho, y espero que, t�, aprendas algo de �l tambi�n ...

R!SC 27th August '99





 

The cRACKER's n0tES esta dividido dentro de 12 partes principales:
 TX. Notas del Traductor
 00. INDICE
 01. Ensamblador para Cracker (CoRN2)
 02. SoftICE (Men� de arranque , Configuraci�n, Comandos)
       
 1 Men� de arranque
       
 2 Configuraci�n
       
 3 Comandos
 03. Breakpoints & Detalles de API de Windows
       
 1 Programas restringidos
       
 2 Cajas de di�logo
       
 3 Verificando el Tipo de unidad
       
 4 Acceso a archivos
       
 5 Acceso al Registro
       
 6 Cogiendo n�meros de serie
       
 7 Accediendo a Tiempo & Fecha
       
 8 Generando ventanas
 04. Instrucciones de salto
 05. Instrucciones SET
 06. Tips & Trucos para Crackear
       
 1 Programas restringidos
       
 2 Dongles
       
 3 General
       
 4 Configuraci�n de InstallSHIELD
       
 5 Protecciones con Archivo llave
       
 6 Pantallas molestas
       
 7 L�mites de Runtime
       
 8 Serials
       
 9 Limites de Tiempo
       
10 Programas Visual BASIC
 07. Ventanas de Mensajes Para los Cracker
 08. Identificando funciones, Argumentos, y Variables (Rhayader)
 09. Los Sistemas de Protecciones de comerciales
       
 1 Armadillo
       
 2 C-Dilla SafeDISC
       
 3 SalesAgent
       
 4 SecuROM
       
 5 softSENTRY
       
 6 TimeLOCK
       
 7 VBox
 10. Bitmanipulation (Cruehead)
 11. Teor�a general de Cracking
 12. FAQ

 +A. C�mo contactar conmigo
 +B. �Que es lo Nuevo?


 



The cRACKER's n0TES are Copyright 1998-2000 by TORN@DO of ID.
Todo los Derechos Reservados.
Traducido por
Revisado por X-Grimator.