+-------------------------------------+
+ 1era APROXiMACiON +
+ Rápido no-ZEN crack en 1 minuto +
+-------------------------------------+
Lo primero que necesitamos es instalar el programa ... una instalación
mínima será suficiente.
¡A trabajar! Carga Soft-iCE y ejecuta matlab.exe. Inmediatamente
el programa te avisa con un mensaje de error: "Error checking out
MATLAB". Sin cerrar aún la ventana de mensaje entra en Soft-iCE y
examina la lista de manejadores de ventana, verás algo como esto:
Window Handle hQueue SZ QOwner Class Name Window Proc.
------------- ------ -- ------ --------------- ------------
0268(1) 262f 32 MATLAB #32770 (Dialog) 17e7:4757
026c(2) 262f 32 MATLAB Button 17e7:102e
... etc.
Sí, se trata de nuestra ventana de error y su botón de "OK". Hagamos que
Soft-iCE interrumpa la ejecución del programa en el momento en que la
ventana de error sea destruida. Hacer esto nos permitirá localizar las
instrucciones que hacen aparecer la ventana de error (esto es cierto para
el 95% de las protecciones que te puedas encontrar, ¿increíble, no?) solo
con PRETear un poco desde Soft-iCE. De acuerdo, coloquemos nuestro PUNTO
de RUPTURA:
bmsg 268 wm_destroy
y dejemos correr al programa. Justo después de pulsar el botón de "OK"
Soft-iCE aparece de nuevo:
---USER!GETDLGCTRLiD+0017--------------------------------------
17e7:4757 push bp
17e7:4758 mov bp,sp
17e7:475a push 4793
...
-------------------------------USER(08)------------------------
Unos cuantos comandos PRET desde aquí hasta entrar en el código del
programa:
137:41adc0 call 6b093c
137:41adc5 add esp,14
137:41adc8 mov [ebp-20],eax
137:41adcb cmp dword ptr [ebp-20],0
137:41adcf jz 41adff
137:41add1 cmp dword ptr [6ed6f0],0
137:41add8 jz 41addf
137:41adda call 441544
137:41addf push 10
137:41ade1 mov eax,6c1486
137:41ade6 push eax
137:41ade7 mov eax,6c1492
137:41adec push eax
137:41aded push 00
137:41adef call cs:[8d0ae4] ;ventana de error
--> 137:41adf6 mov dword ptr [ebp-24],0 ;chico malo
137:41adfd jmp 41ae06 ;largo del programa!
137:41adff mov dword ptr [ebp-24],1 ;buen chico, adelante!
Increible, ¿eh? ¿No lo oyes? ... está diciendo "crackeame" ;-).
No lo pienses dos veces e intenta un parche (no-ZEN) rápido:
137:41adcf jz 41adff -> 137:41adcf jmp 41adff
Después de testear el parche en memoria con Soft-iCE (funciona bien), será
fácil parchear el código físicamente:
MATLAB.EXE, 3.457.536 bytes (pequeñito, ¿eh?)
Buscar : 74 2e 83 3d
Sustituir : eb -- -- --
Ahora ejecuta el programa y pruebalo con algunos ejemplos y demos, todo
funciona perfectamente ... ¿no?
+---------------------------------------------------+
+ 2da APROXiMACiON +
+ Tirando abajo el propio sistema de protección +
+---------------------------------------------------+
Tenemos a nuestra víctima funcionando perfectamente sin la motxila, pero
no estamos satisfechos. Nosotros no queremos crackear el programa, lo
estamos haciendo para aprender más ... verdadero conocimiento será nuestra
única satisfacción (aparte de destruir Micro$oft y ver a Mr. Bill Fakes
crucificado, por supuesto).
Echemos de nuevo una mirada al programa, y veamos con más profundidad cómo
funciona el sistema de protección. Para hacer esto tendremos que restaurar
el ejecutable original matlab.exe sin parchear. Ahora ya estamos listos
para comenzar, echemos una ojeada al código previo a nuestro primer parche:
137:41adb2 push 23
137:41adb4 push dword ptr [ebp-1c]
137:41adb7 push dword ptr [ebp-18]
137:41adba push dword ptr [ebp-14]
137:41adbd push dword ptr [ebp-10]
137:41adc0 call 6b093c
137:41adc5 add esp,14
137:41adc8 mov [ebp-20],eax
137:41adcb cmp dword ptr [ebp-20],0
137:41adcf jz 41adff
137:41add1 cmp dword ptr [6ed6f0],0
137:41add8 jz 41addf
137:41adda call 441544
137:41addf push 10
Presta atención y dime qué puede estar pasando en el código anterior.
Una serie de valores son colocados en la pila, luego se hace una llamada
a una rutina, y finalmente el valor devuelto en EAX por esa rutina es usado
para chequear nuestro acceso al programa. Coloquemos un punto de ruptura en
137:41adc0 y sigamos la pista a la rutina llamada. Después de tracear un
poco nos vemos aquí:
-->137:94118a push ebp
137:94118b mov ebp, esp
137:94118d push ebx
137:94118e push esi
137:94118f push edi
137:941190 mov eax,[ebp+18]
137:941193 push eax
137:941194 mov eax,[ebp+14]
137:941197 push eax
137:941198 mov eax,[ebp+10]
137:94119b push eax
137:94119c mov eax,[ebp+C]
137:94119f push eax
137:9411a0 mov eax,[ebp+8]
137:9411a3 push eax
137:9411a4 call 941525
137:9411a9 add esp,14
137:9411ac jmp 9411B1
137:9411b1 pop edi
137:9411b2 pop esi
137:9411b3 pop ebx
137:9411b4 leave
137:9411b5 ret 14
Este trozo de código NO ES del propio MATLAB ... ¿dónde puede estar
localizado? Echa un vistazo al directorio MATLAB\bin:
Directorio de C:\MATLAB\bin
BCCENG~1 BAT 1.426 21/11/96 15:58 bccengmatopts.bat
BCCOPTS BAT 1.632 21/11/96 15:58 bccopts.bat
CMEX BAT 2.274 21/11/96 15:58 cmex.bat
FMEX BAT 2.274 21/11/96 15:58 fmex.bat
LIBENG DLL 29.696 22/11/96 9:51 libeng.dll
LIBMAT DLL 60.416 21/11/96 12:05 libmat.dll
LIBMX DLL 40.960 21/11/96 12:05 libmx.dll
LIBUT DLL 40.960 21/11/96 12:05 libut.dll
MATLAB EXE 3.457.536 06/01/98 7:24 matlab.exe
MEX BAT 18.152 21/11/96 15:58 mex.bat
MEDIT EXE 144.896 04/12/96 13:43 medit.exe
MEXOPTS BAT 1.721 21/11/96 15:58 mexopts.bat
MFC42 DLL 1.013.520 21/11/96 12:05 mfc42.dll
MIPC50 DLL 248.320 21/11/96 12:05 mipc50.dll
MLAPP TLB 2.789 21/11/96 12:06 mlapp.tlb
ML_16 DLL 14.708 21/11/96 12:05 ml_16.dll
MLPTOOL EXE 42.496 21/11/96 12:05 mlptool.exe
MSCTOF DLL 31.744 21/11/96 12:05 msctof.dll
MSFOPTS BAT 1.649 21/11/96 15:58 msfopts.bat
MSVCEN~1 BAT 1.701 21/11/96 15:58 msvcengmatopts.bat
MSVCIRT DLL 74.752 21/11/96 12:05 msvcirt.dll
MSVCOPTS BAT 1.599 21/11/96 15:58 msvcopts.bat
MSVCRT DLL 267.536 21/11/96 12:05 msvcrt.dll
MWOLES05 DLL 43.520 22/11/96 11:51 mwoles05.dll
PERL100 DLL 525.312 21/11/96 12:05 perl100.dll
PERL EXE 36.352 21/11/96 12:05 perl.exe
SHOWDLLS EXE 49.668 21/11/96 12:05 showdlls.exe
WATENG~1 BAT 1.701 21/11/96 15:58 watengmatopts.bat
WSPTOOL EXE 60.928 21/11/96 12:05 wsptool.exe
LICENSE DAT 167 06/01/98 7:24 license.dat
W32SSI DLL 66.560 02/04/96 11:01 w32ssi.dll
31 archivo(s) 6.286.965 bytes
2 directorio(s) 46.161.920 bytes libres
La mayoría de los archivos tienen (más o menos) la misma fecha: 21-22/11/96,
pero hay 4 que no la tienen:
MATLAB EXE 3.457.536 06/01/98 7:24 matlab.exe
MEDIT EXE 144.896 04/12/96 13:43 medit.exe
LICENSE DAT 167 06/01/98 7:24 license.dat
W32SSI DLL 66.560 02/04/96 11:01 w32ssi.dll
matlab.exe : ejecutable principal, fecha de instalación
medit.exe : Matlab editor/debugger
license.dat : fichero ASCii de licencias, fecha de instalación
w32ssi.dll : ¿qué demonios puede ser esto?
Coge tu editor hexadecimal favorito, busca nuestro código y ¡EUREKA! Para
leerlo mejor coge W32Dasm y obtén el código desensamblado (unos 245 Kb):
Exported fn(): wSSIEIni - Ord:000Fh
:40118A 55 push ebp
:40118B 8BEC mov ebp, esp
:40118D 53 push ebx
:40118E 56 push esi
:40118F 57 push edi
:401190 8B4518 mov eax,[ebp+18]
:401193 50 push eax
:401194 8B4514 mov eax,[ebp+14]
:401197 50 push eax
:401198 8B4510 mov eax,[ebp+10]
:40119B 50 push eax
:40119C 8B450C mov eax,[ebp+C]
:40119F 50 push eax
:4011A0 8B4508 mov eax,[ebp+8]
:4011A3 50 push eax
:4011A4 E87C030000 call 401525 <--- llamada al sistema de chequeo
:4011A9 83C414 add esp,14
:4011AC E900000000 jmp 4011B1
:4011B1 5F pop edi
:4011B2 5E pop esi
:4011B3 5B pop ebx
:4011B4 C9 leave
:4011B5 C21400 ret 14 <-------- volvemos a MATLAB
Si la motxila está instalada esta llamada devuelve EAX = 0. Si no,
devolverá EAX = -1 ($FFFFFFFF). El objetivo es claro, ¿no? ... parchearemos
esta función para que siempre devuelva EAX=0. Hay múltiples soluciones,
por ejemplo:
:40118A 55 push ebp :40118A 33c0 xor eax,eax
:40118B 8BEC mov ebp,esp ---\ :40118C c21400 ret 14
:40118D 53 push ebx ---/
:40118E 56 push esi
Después de probar el parche en memoria con Soft-iCE (funciona perfectamente),
será sencillo parchear el código físicamente:
W32SSi.DLL, 66.560 bytes
Buscar : 55 8b ec 53 56 57 8b 45 18
Sustituir : 33 c0 c2 14 00 -- -- -- --
Ahora corre el programa y pruebalo, todo debe funcionar perfectamente ...
No nos importa (de momento) qué es lo que pasa en el interior de las rutinas
de chequeo de hardware, pero si sigues la pista al código dentro de la DLL
te encontrarás trozos de código como éste:
...
:401712 push eax
:401713 mov eax,80992014
:401718 push eax
:401719 push dword ptr [4070A0]
:40171F call dword ptr [407050]
:401725 mov eax,[4070A0]
:40172A push eax
:40172B call dword ptr [407054]
:401731 mov dword ptr [4070A0],-1
:40173B jmp 40175A
:40173D mov ebp,[4076A4]
:401743 mov esi,[4076A8]
:401749 mov edi,[4076AC]
:40174F mov edx,9966
:401754 mov ax,8
:401758 out dx,ax
...
o éste:
...
:40197B mov edx,9966
:401980 sub eax,eax
:401982 in ax,dx
:401984 cmp ax,9966
:401988 jne 401A67
:40198E in al,dx
:40198F cmp al,55
:401991 jne 401A67
:401997 inc edx
:401998 in al,dx
:401999 cmp al,88
:40199B jne 401A67
:4019A1 mov edx,9964
:4019A6 sub eax,eax
:4019A8 in ax,dx
:4019AA and eax,FFFF
:4019AF mov edx,eax
:4019B1 cmp ax,1000
:4019B5 jb 401A67
:4019BB and al,3
:4019BD jne 401A67
:4019C3 mov [4070A4], edx
:4019C9 mov byte ptr [4070F1],1
:4019D0 jmp 401A67
...
material muy interesante, pero no para este tutorial ... tal vez en un
futuro :)
Esta segunda aproximación nos proporciona dos iMPORTANTES ventajas
sobre la primera:
1) Nuestra víctima solo llama a la rutina de chequeo de la motxila una
sola vez al arrancar la aplicación, pero te encontrarás programas que
hacen múltiples llamadas desde cualquier sitio y en cualquier momento
durante su ejecución. Un ejemplo de esto podría ser AutoCAD 13 de
AutoDesk. Su sistema de chequeo es prácticamente el mismo, llegas a
un punto en el que se hace una llamada devolviendo EAX=0 => buen chico,
y ésta es llamada no solo al comienzo, sino varias veces más mientras
el programa se está ejecutando. Si tomas como modelo la primera
aproximación para este tipo de programas, tendrás que parchear
*cualquier* referencia que exista a la llamada ...
2) Cuando un programador distribuye parte del código en DLLs, lo hace con
el fin de reducir el tamaño del ejecutable principal liberandole de la
carga adicional de rutinas que son usadas solo una o dos veces a lo
largo del programa, pero la mayor parte de las veces lo hace para
*compartir* rutinas entre diferentes aplicaciones ... teniendo en
cuenta la fecha del archivo w32ssi.dll no sería de extrañar
que nos encontrasemos la misma DLL en otras aplicaciones por ahí, y de
ser así nos habríamos cargado un sistema de protección comercial ;-).
Saludos a todos los crackers de Euskal Herria (Pueblo Vasco) ......
jotake irabazi arte !
(c) 1998 by +Aitor and the +HCU. All rights reserved.
|