Reverse Engineering MATLAB 5
Part I: Dongle Protection

 
Dongles

12 January 1998

by +Aitor

 
fra_00xx
980112
+Aitor
0100
NA
PC

I'm baffled: the level of the essays of our schoolmates is continuously improving, yet the level of the protection schemes seems (if ever possible) to decrease... does it depends from the fact that most programmers don't know any more (after so many years of compelled windoze's lobotomizing) how code works? (and I mean real, mighty code, the one you feel passing slowly your gaze on it :-)
I don't know, I don't undertand.
Anyway I'm happy to host this essay by our schoolmate +Aitor and I agree TOTALLY with his philosophy: "We have (now) our target working fine -without the dongle- but we are not satisfied. We don't want to crack this program, we are reversing it in order to learn more ... real knowledge will be our unique satisfaction..."
Rrright so +crackers! (and now let's hope that +Aitor's other essays of a series of at least three will follow rash :-)

 
 

There is a crack, a crack in everything
That's how the light gets in

 

Rating

( )Beginner (x)Intermediate ( )Advanced ( )Expert

 


"A little essay to show beginners and intermediate reversers how a dongle can be easily defeated"


Reverse Engineering MATLAB 5
Part I: Dongle Protection
Written by +Aitor

Introduction




I've chosen this program because it has got three levels of protection:


1) Program is dongle protected, that is, once you have installed it won't

   run without plugging in the dongle.


2) With the program are included *ALL* the toolboxes (sold apart at very

   expensive prices, believe me) but they're not mentioned anywhere. These

   are InstallShield packed .Z files that cannot be unpacked by the

   InstallShield file compressor because they are *ENCRYPTED* ... all the

   .Z files in the Matlab 5 CD are encrypted.


3) Once you have built a little decryptor, and all the forbidden toolboxes

   are unpacked, a license check appears ...


This essay (the 1st of a series of at least three) deals with the 1st level

of protection ...


Dongle, hardware key, security plug, motxila ... words that sound terrible

to many crackers (mainly beginners) out there.  The main aim of this essay

is to show how a hardware key protected commercial application can be

cracked in less than a minute, as easily as you do with many other

shareware targets, and if you give yourself a few more seconds you'll be

able to crack the entire ready made (probably commercial) protection

system.





Tools required


Soft-iCE v3.2 Win95 (v2.x will be enough; *required*)
Your favourite hex editor (only needed to test the patches)
W32Dasm v8.0 (any version will do; needed for a deeper approach)

Target's URL/FTP


The program *iS NOT REQUiRED* to follow the essays. Remember, we are mainly reverse engineers, not only crackers ... this series will teach you generic protection schemes, it's not my intention to write one more how-to-crack to an specific application. Anyway, it's commercial software, but (hardly) available in the net if you do know how to search.

Program History


Not too much to say. A classic among the maths/programming applications, available for different systems. In my personal software archives (for educational purposes only :) I've got version 3.5f for DOS dated from 1989, then was a package including PC-Matlab and AT-Matlab, with only a serial number. Latest version I know is the target of this essay, a CD-ROM including version 5.0 for Win95/NT and version 4.2c.1 for Win32s, both serial number + dongle protected.
If you want to know more about this product contact with the The MathWorks Web site or connect to one of the hundreds of Matlab related sites across the net.

Essay






+-------------------------------------+

+           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 twice 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 guy, 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 does 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 ;-).



Final Notes




Like many other contributors to this pages English is not my mothertongue ...

... sorry for any inconvenience, be patient ;).




Greetings to all the reverse engineers from Euskal Herria (Basque Country) ...

... jotake irabazi arte !





(c) 1998 by +Aitor and the +HCU. All rights reserved.



Ob Duh


I won't even bother explaining you that you should BUY this target program if you intend to use it ... this is not shareware ;-). If you own a legal copy of the program, take into consideration your country's laws about reverse engineering. Here you got an extract from the LiCENSE.TXT file included in the CD (read it, this is valid for any other commercial software you own in the EU):

"In relation to the Programs which Licensee is entitled to use, Licensee shall not decompile, disassemble or otherwise reverse engineer the Programs except with respect to European Union Licensees whose rights are as follows:

EUROPEAN UNION: Licensee may only decompile, disassemble or otherwise reverse engineer the Programs where any such act is necessary to create an independent program which is interoperable with the Programs or with another program or to observe, study, or test the functioning of the Programs solely in order to understand the ideas and principles which underlie any element of the Programs ("the Permitted Objective") and provided that:

(a) this may only be done if the information necessary to achieve the Permitted Objective has not already been made available or has not been provided by TMW within a reasonable time of a written request to TMW to provide such information;

(b) the compilation, disassembly or reverse-engineering is confined to those parts of the Programs necessary to achieve the Permitted Objective;

(c) the information gained is not used for anything other than the Permitted Objective and is not disclosed to any other person except as may be necessary to achieve the Permitted Objective; and

(d) the information obtained is not used to create a program substantially similar in its expression to the Programs including, but not limited to, expressions of the Programs in other computer languages, or for any other act restricted by copyright in the Programs.