May 1998
"Crypt-o-Text V1.24"
( 'Going through the front door'  )
Win '95 PROGRAM
Win Code Reversing
 
 
by The Sandman 
 
 
Code Reversing For Beginners 
 
 
 
Program Details
Program Name: cot32.exe
Program Type: HTML Space Trimmer
Program Location: Here or Here
Program Size: 990 K 
 
   
Tools Used:
W32Dasm V8.9 - Disassembler
 
Rating
Easy ( X )  Medium (   )  Hard (    )  Pro (    ) 
There is a crack, a crack in everything. That's how the light gets in.
 
  
 
Crypt-o-Text V1.24
( 'Going through the front door'  )
Written by The Sandman
 
 
 
Introduction
 
The author says about Crypt-o-Text:

"Crypt-o-Text is a Microsoft Windows 3.x, Windows 95, and Windows NT utility designed to give extra privacy to e-mail messages.  Even if you send a message privately, there is still a good chance that others will see the message -- especially when sending it over large networks.  Crypt-o-Text can also be used to secure other small pieces of text, provided that it is less than 22kb in size."
 
About this protection system
 
This program is registered via the the front-end registration reminder screen that appears each time you run Crypt-o-Text.  Select the 'Enter My Code' button where you will be asked to enter your registration code. 
 
Registration Code:

On successful registration the program will save the registration code to:-
 
C:\WINDOWS\COT.INI
 
[Crypt-o-Text]
FontName=Fixedsys
FontSize=10
FontColor=0
FontBold=0
FontItalic=0
WordWrap=0
BackColor=-2147483643
RegistrationCode=999999999  ;This is NOT the real serial number.
 
The Essay 
     
  The approach I will be using to crack this program will be different to my other essay's because I felt it was time to experiment with different methods of cracking a program, it is as they say, the only way to learn.
 
Our first task here is to create a 'Dead Listing' of our target program, we want to see where we're going and examine any obvious 'weak' links within the program which we can exploit for our own purposes.
 
If you have run this program through the registration process then you will have seen the Beggar Off Cracker Message "That registration number is not valid, please try again" which is a good starting point for our attack of this program.  A quick search of the listing show's us that it is to be found here.
 
* Referenced by a (C)onditional Jump at Address :00436CD5(C)
 
:00436CF5 6A10                    push 00000010
:00436CF7 E890E3FCFF              Call User32!MessageBeep
:00436CFC 6A00                    push 00000000
:00436CFE 668B0D106E4300          mov cx, word ptr [00436E10]
:00436D05 B201                    mov dl, 01
:00436D07 B8F46E4300              mov eax, 00436EF4 ;Memory location of
                                                    ;our beggar off cracker
                                                    ;message
:00436D0C E8779FFFFF              call 00430C88     ;Display message
 
Right, lets see where this routine is called from. Our Dead listing shows that this code snippet is referenced from location 00436CD5 so lets examine that area and see what we can learn there.
 
:00436CB2 8B55FC                  mov edx, dword ptr [ebp-04] ;Our entered
                                                              ;Serial No
:00436CB5 B8B8A64300              mov eax, 0043A6B8
:00436CBA E80DC8FCFF              call 004034CC
:00436CBF A1B8A64300              mov eax, dword ptr [0043A6B8];2nd loc
                                                               ;of our
                                                               ;serial No

:00436CC4 E8C3D0FFFF              call 00433D8C ;Returns with:=
                                                ; AL=0 'Invalid Serial No
                                                ; AL=1 'Correct Serial No
 
:00436CC9 A2B4A64300              mov byte ptr [0043A6B4], al ;Save results

:00436CCE 803DB4A6430000          cmp byte ptr [0043A6B4], 00 ;Is program
                                                              ;registered?

:00436CD5 741E                    je 00436CF5 ;Jump if not registered.
 
 
Perhaps our first attempt to *crack* this program would be to Nop (90h) out the je 00436CF5 instruction at memory location: 00436CD5 since that would then force the program to go into the 'Good Guy' routines..  If you do this then, yes, the program will indeed display the 'Thank you for registering this software bla bla bla'  but if you checked what the program saves to it's cot.ini file then you will see that it will save the invalid serial number you had type in, instead of the real serial that the program looks for.  So when the program is re-run it will see your invalid serial number in it's cot.ini file and ignore it, therefore it will continue on as still being unregistered.. Nice try though..
 
Lets take another look at the above code segment, the call 00433D8C will always return with the low part of the EAX register as having a value of '0' or '1' then the program saves this value at memory location 43A6B4.  Why?..  Think about it..
 
If you were a programmer and your program had just performed a check on someone's registration number then the possible outcome of this would either be a Yes, registration is correct, or No, invalid registration code.  In computers a Yes and No can be replaced with a '1' = Yes or '0' = No.  We can confirm that this is the case because:-

:00436CC4 E8C3D0FFFF              call 00433D8C ;Returns with:=
                                                ; AL=0 'Invalid Serial No
                                                ; AL=1 'Correct Serial No
Then the program saves the result in a safe memory location where it knows it can find it again should it ever need to check if it's been registered or not:-
 
:00436CC9 A2B4A64300              mov byte ptr [0043A6B4], al ;Save results
 
Then, once the results of checking the serial number has been completed it will test this memory location to see if the program is still unregistered (it's checking for a value of '0' meaning unregistered).
 
:00436CCE 803DB4A6430000          cmp byte ptr [0043A6B4], 00 ;Is program
                                                              ;registered?
 
Now. depending on this comparison will deiced if the je (Jump if Equal) instruction is set or not.  If it is 'set' then the value stored at memory location 0043A6B4 was found to contain a '0'.
 
We should now understand this code section, so what would you do now?.
 
Well, at this point I fired up Softice and at the registration screen I set a softice breakpoint with:  bpx hmemcpy so that once I had typed in the first letter of my fake serial number Softice breaks on this system function. From here pressing 'F11' followed by 9  'F12's.  Finally get into the target program's code. It's not important what function we use to break into the program with, all we want is to set a breakpoint at the call instruction that returns with either a '0' or '1' in the 'AL' register.  OK, we're in the target program's code so we now type u 00436CC4 which gets Softice to display the line where we want to place another breakpoint.  OK, now type: bc * this clears any previous breakpoints we may have made in softice now double-click with your mouse on this line:-

:00436CC4 E8C3D0FFFF              call 00433D8C

This line should now be highlighted, indicating that Softice will break on this line if and when it comes across it.  Now type x to leave softice and finish typing in your fake serial number.  Once your fake serial number is typed in press the 'OK' button to get the program check our serial number.  Softice will once again break, and as expected it's stopped at memory offset: 00436cc4 our call instruction.
 
If our analysis from the 'dead listing' is correct, pressing the F10 key will execute the Call instruction and return a '0' in the 'AL' register, since this is the default setting of the program and the chances of guessing the real serial is highly remote we can safely assume that the program will find it incorrect..
 
From here single step through the code (using the 'F10' key) until you get to the je instruction, where, Softice shows that it's been 'set' and if you continue then the program will jump to our 'Beggar off Cracker' routine.  Press x to leave softice, then, while in our target program press the 'Ok' button again to get the program to re-check our serial number. Again, Softice breaks on our single breakpoint at memory offset 00436cc4.  We do this because we WANT to make sure that the program behaves as we expect it to when it's unregistered and when it's been registered.
 
OK, press the F10 key again to execute the call instruction so that it once again returns a '0' in the AL register. Now type into Softice: r al=1 which tells softice to ignore the present value stored in the AL register and replace it with a value of '1'.    Now type x to leave softice.  Although we don't see anything different (well, yes we do, the program has cleared the registration screen and placed us directly into the main program itself instead of re-showing the registration screen when we get the serial code wrong) the program now 'thinks' it's been registered but remember, this will only last as long as the program is running, because if we re-run the program again it it will be back in the unregistered mode.
 
OK. exit Crypt-o-text then re-run it again, head straight into the registration screen and type in a fake serial number then press the OK button again to get softice to break on our single breakpoint at memory offset:00436cc4
 
Let's go fishing... While still in Softice type:  bpm 0043a6b4 then type: x to leave softice.

bpm means: Breakpoint on memory access which in this case Softice will stop every time the program tries to either write or read the memory contents at location 0043a6b4, the place where we suspect that it stores the registration status of the program. Wether it's registered or not.

OK, exit Crypt-o-text and then re-run it.  Here's where the fun begins..:)
 
Softice breaks at:-
 
:004369A2 A1B8A64300     mov eax, dword ptr [0043A6B8] ;eax = memory loc
                                                       ;of our fake serial
                                                       ;serial number

:004369A7 E8E0D3FFFF     call 00433D8C                 ;Validate serial No
                                                       ;and return either a
                                                       ;0 or 1 in the al
                                                       ;register.
 
:004369AC A2B4A64300     mov byte ptr [0043A6B4], al   ;save result
 

Press X to now let the program continue on...
 
Softice break's again at:
 
:00436BED 803DB4A6430000      cmp byte ptr [0043A6B4], 00 ;Check to see
                                                          ;if the program
                                                          ;has been
                                                          ;registered.

:00436BF4 0F8535010000        jne 00436D2F                ;jump if
                                                          ;registered else
                                                          ;display nag
 
Can you see the pattern here?: On our first softice break the program had already read our fake serial from it's cot.ini file and had then stored the address of where our fake serial number could be found, in this case inside memory location 43A6B8.  The call 00433D8C then validated this serial number and returned a value of '0' in the al register, which was then saved into our magic 43a6b4 memory address.
 
On our second Softice break the program now 'reads' our magic 43a6b4 address to see if the program has been registered or not.  Based on what we know so far our best point of attack then is where Softice first stopped, at memory offset :004369A2, where it checks our fake serial number.
 
Take another look at where Softice first broke:-
 
BEFORE:-
:004369A2 A1B8A64300              mov eax, dword ptr [0043A6B8]
:004369A7 E8E0D3FFFF              call 00433D8C
:004369AC A2B4A64300              mov byte ptr [0043A6B4], al

Lets replace the Call 00433D8C that checks our fake serial number with the instruction mov eax,00000001

AFTER:-
:004369A2 A1B8A64300              mov eax, dword ptr [0043A6B8]
:004369A7 B801000000              mov eax,00000001
:004369AC A2B4A64300              mov byte ptr [0043A6B4], al

See what I've done?.  I loaded the eax register with a value of 00000001, so that the low value of eax is 1, which is represented by the instruction al here. This patch might be considered a tad messy from a 'perfectionist's' point of view but its 100% reliable and effective so I'm happy with it.
 
Job Done.
The 'Crack' 
 
Load up cot.exe into your favourite hex editor then:-
 
SEARCH FOR THE FOLLOWING BYTES: 4300E8E0D3FFFF
THEN REPLACE HIGHLIGHTED BYTES: 4300B801000000
 
Final Notes 
 
We've *cracked* the program from the front door because it 'begged' that it should be done this way.. Since the 'About' screen within our target program never changes and never shows any details to who has registered the program it makes sense to patch the program so 'internally' it thinks it been registered. This is, after all, how the program was meant to run.
 
My thanks and gratitude goes to:-
 
Fravia+ for providing possibly the greatest source of Reverse Engineering
knowledge on the Web.
 
+ORC for showing me the light at the end of the tunnel.
 
Ob Duh 
 
Do I really have to remind you all that by buying and NOT stealing the software you use will ensure that these software houses will continue to  produce even *better* software for us to use and more importantly, to continue offering even more challenges to breaking their often weak protection systems.
 
If your looking for cracks or serial numbers from these pages then your wasting your time, try searching elsewhere on the Web under Warze, Cracks etc.
 


 
 
 Next   Return to Essay Index   Previous 
 


Essay by:          The Sandman
Page Created: 14th June 1998