T H E E S S A Y
|
+-------------------------------------+
+ 1st APPROACH +
+ Fast non-ZEN one-minute-crack +
+-------------------------------------+
First thing we need is installing our target ... a minimal
installation will be enough.
Aurrera with our job! Fire up Soft-iCE and run matlab.exe.
Inmediately you are warned with a fatal error box: "Error
checking out MATLAB". Without closing this box pop up Soft-iCE
and check the list of window handles, you'll see something like
this:
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
... an so on
Yes, they are our error box and its OK-button. Let's make
Soft-iCE break the program execution at the moment when the
error box is destroyed. Doing so we'll be able to locate the
calling instructions that make our box appear (this is true in
95% of the protections you'll find, incredible, isn't it?) only
by PRETing within Soft-iCE. Ok, let's put our BREAKPOiNT:
bmsg 268 wm_destroy
and let the program run. After pressing the OK-button Soft-iCE
pops up again:
---USER!GETDLGCTRLiD+0017--------------------------------------
17e7:4757 push bp
17e7:4758 mov bp,sp
17e7:475a push 4793
...
-------------------------------USER(08)------------------------
A few PRET commands from here until we land on the program code:
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] ;fatal error box
--> 137:41adf6 mov dword ptr [ebp-24],0 ;bad guy
137:41adfd jmp 41ae06 ;go out!
137:41adff mov dword ptr [ebp-24],1 ;good guy, go ahead!
Incredible, eh? Can you hear it ? ... it's saying 'crack me' ;-).
Don't think it two times and try a fast non-ZEN patch:
137:41adcf jz 41adff -> 137:41adcf jmp 41adff
After live testing patching code in memory (it works fine), will
be easy to patch the code on disk:
MATLAB.EXE, 3.457.536 bytes (tiny, uhm?)
Search : 74 2e 83 3d
Replace : eb -- -- --
Now run the program and test it with a few samples and demos,
everything works well ... isn't it?!
+-------------------------------------------------+
+ 2nd APPROACH +
+ Breaking down the protection system itself +
+-------------------------------------------------+
We have our target working fine without the dongle, but we are
not satisfied. We don't want to crack the program, we are
reversing it in order to learn more ... real knowledge will be
our unique satisfaction (apart from destroying Micro$oft and see
Mr. Bill Fakes crucified, of course).
Let's take a look at the program again, and see more deeply how
the protection system works. For doing this we must restore the
original unpatched matlab.exe file. Now we are ready to begin,
take a look at the code previous to our first patch:
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
Pay attention and tell me what's could be happening in the code
above. A series of values is been located in the heap, then a
routine is called, and finally the EAX value returned from that
routine is used to check our access to the program.
Let's put a breakpoint at 137:41adc0 and trace the called
routine code. After tracing a little we land here:
-->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
This piece of code iS NOT from MATLAB itself ... where could it
be located? Take a look at our MATLAB/bin directory:
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
Most of the files have (more or less) the same date: 21-22/11/96,
but there are four of them that have not:
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 : main executable, installation date stamped
medit.exe : Matlab editor/debugger
license.dat : ASCii license file, installation date stamped
w32ssi.dll : what the hell could be this?
Take your favourite hex editor, search for our code and EUREKA!
To read it better take W32Dasm and get its dead listing (about
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 <--- call to checking_system :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 <-------- return to MATLAB
If the dongle is installed this call returns EAX = 0. If not,
it will return EAX = -1 ($FFFFFFFF). The aim is clear, isn't
it? ... we'll patch this function to return always EAX=0. There
are multiple solutions, e.g.:
: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
After live testing patching code in memory (it works fine), will
be easy to patch the code on disk:
W32SSi.DLL, 66.560 bytes
Search : 55 8b ec 53 56 57 8b 45 18
Replace : 33 c0 c2 14 00 -- -- -- --
Now run the program and test it, everything should work fine ...
We don't care (by the moment) about how messy things are done
inside the hardware checking routines, but if you trace the code
inside the DLL you'll find code snippets like this:
...
: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
...
or this:
...
: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
...
quite interesting material, but not for this essay ... may be
in a future :)
This 2nd approach give us two iMPORTANT advantages over the 1st
one:
1) Our target only calls the dongle checking routine once at
startup, but you'll find applications that make multiple
callings from anywhere at anytime during its execution.
An example of this could be AutoCAD 13 from AutoDesk.
Its protection check is mainly the same, you reach one
point in the code with a call returning EAX=0 => good boy,
and this is called not only at startup, but some more
times while the program is running. If you take the 1st
approach as a model for this kind of targets, you will
must patch *any* references to the call ...
2) When a programmer distributes part of the code in DLLs he
do it in order to reduce the size of the main EXE freeing
it from the additional load of routines that are used only
one or two times along the program, but most of the times
do it to *share* routines among different applications ...
... taking into consideration the date of the w32ssi.dll
file it won't be very strange to find the same DLL in
other applications out there, and if this was the case
we'd have broken down a ready made protection system ;-).
|