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
|
|