July 1998
"TimeSlice-32 v1.1.0"
( 'Sifting through the code'  )
Win '95 PROGRAM
Win Code Reversing
 
 
by The Sandman 
 
 
Code Reversing For Beginners 
 
 
 
Program Details
Program Name: TimeS-32.zip
Program Type: Time Management Utility
Program Location: Here
Program Size: 1.48 MB 
 
   
Tools Used:
 Softice V3.2 - Win'95 Debugger
W32Dasm V8.9 - Win'95 Disassembler
Rating
Easy ( X  )  Medium ( X  )  Hard (    )  Pro (    ) 
There is a crack, a crack in everything. That's how the light gets in.
 
  
 
TimeSlice-32 V1.1.0
( 'Sifting through the code'  )
Written by The Sandman
 
 
 
Introduction
 
The author Lois A. Genzmer of  Maui Software says about TimeSlice-32:-
 
"TimeSlice automates the task of tracking your time and billing for hourly work. You can list clients, projects and/or categories with applicable rates, then start timing when you begin work. An expense amount can be added to each time entry.  You can easily add time entries when you have been working away from your computer.  TimeSlice allows you to bill by minutes or tenth, quarter, half, or whole hour and then generate invoices or reports for any set of time recorded. You can bill time against clients, projects, or specific tasks and keep notes on exactly what you're doing. TimeSlice data can be exported to database, spreadsheet, word processing programs so that you can create custom invoices and reports.  TimeSlice stays out of your way while you work on your computer by providing the ability to command the timer and edit active time entries while TimeSlice is minimized."
 
About this protection system
 
This program uses a  Serial Number to register it with, which can be accessed via the initial nag screen that is shown at the start of the program each time it is run.
 
Within the Registration Screen you are asked for:-

Name:
Registration Code:

On startup, TimeSlice searches your Registry file for your name/handle and Registration Code for TimeSlice which it expects to find here:-
 
HKEY CURRENT USER\Software\Maui Software\TimeSlice\TimeSlice\CustomerName
HKEY CURRENT USER\Software\Maui Software\TimeSlice\TimeSlice\Registration
 
The Essay 
     
This essay is an accompniant to one written by lownoice called TimeSlice which was based on the 16-bit version of Timeslice, while this essay delves into the 32-bit version and uses a different approach to sniff out the serial No. I will attempt to explain the thinking process behind the crack rather than taking you directly to the all import instructions that reveal the real serial number used by the program.. I suggest you print this essay and read it one night when you have some time to spare..
 
Many people often wonder why so many crackers use 'Dead Listings' to help them *crack* their target programs when they can use Softice to retrace the program's steps back to where it made the decision to either display the 'Beggar off Cracker message' or the 'Thank you for purchasing bla bla bla'.. The reason is quite simply that 'dead listings' make the program far easier to follow than if you tried cracking it 'live' using just Softice on it's own. You can print a 'dead listing' then add notes to the program's source code and examining a 'dead listing under a text editor allows you to jump all over the program's code far quicker than using Softice..
 
For those interested, I use W32Dasm to create a 'Dead Listing' of my target program which then creates a .ALF file, a text file showing all the assembler instructions used within the target program.. Then I load this .ALF file into UltraEdit-32 where I can then cut & paste sections of this code into my essay's.  I can also make hard copies of certain sections of code that interest me from the dead listing for future references just in case I come across an upgrade of the same program. Get to know your target program's history, that way should it ever be upgraded you will have a pretty good idea on how to crack it even if it uses a different protection system!.

Now lets start thinking like *crackers*.. If we wish to 'back-track through the code looking for where the our fake serial number gets compared with the real one created by the program then we must first choose a likely system function used by the program which we know has a very good chance of being used within or by the program's protection system.

My favorite method of entry into a target program is via the MessageBox system function (found in the Kernel.DLL file ) if it is a 16-bit program, or via the MessageBoxA system function (found in the Kernel32.DLL file) if it's a 32-bit program.  This is often (but not always) used to display the 'Beggar off cracker' messages and the 'Thank you for purchasing bla bla messages.
 
So once I had created a 'Dead Listing' of TimeSlice-32 I immediately searched for this system function (MessageboxA) and found it mentioned just once in this program at:
 
:0044BC0E FF153CDE4700            Call User32!MessageBoxA
:0044BC14 891E                    mov dword ptr [esi], ebx
:0044BC16 837DFC00                cmp dword ptr [ebp-04], 00000000
:0044BC1A 89450C                  mov dword ptr [ebp+0C], eax
:0044BC1D 740B                    je 0044BC2A
:0044BC1F 6A01                    push 00000001
:0044BC21 FF75FC                  push [ebp-04]
:0044BC24 FF1520DE4700            Call dword ptr [0047DE20]
:0044BC2A 6A01                    push 00000001
:0044BC2C 8BCF                    mov ecx, edi
:0044BC2E E822FFFFFF              call 0044BB55
:0044BC33 8B450C                  mov eax, dword ptr [ebp+0C]
:0044BC36 5F                      pop edi
:0044BC37 5E                      pop esi
:0044BC38 5B                      pop ebx
:0044BC39 C9                      leave
:0044BC3A C20C00                  ret 000C
 
Just in case you don't already know this, routines or blocks of code usually begin with any assembly instruction and more importantly, end with a jmp or a ret instruction, so if we want to find the BEGINNING of the above message printing routine we would scan up the dead listing until we came across either a jmp or ret instruction.. 

Lets do this right now...

If you did this correctly then you will see the beginning of the message printing routine here:-

:0044BB7F 5E                      pop esi
:0044BB80 C20400                  ret 0004 ;End of some other routine
 

:0044BB83 55                      push ebp ;Start of Message Print routine
:0044BB84 8BEC                    mov ebp, esp

OK, now we know where the beginning of the message print routine is, it starts at memory offset 0044BB83. If you now check all the conditional jump statements from here to our call User32!MessageBoxA statement you'll quickly see that these jnz's, jz's statements relate only to how the actual message will look when it's been displayed, it does NOT however, have anything to do with the protection system or serial number used within the program..  You can see this for yourself by first going into the target program's registration screen, then, once you've filled in the required details create a Softice breakpoint on bpx Messageboxa then pressing the 'OK' button to let the target program run as normal until Softice cut's in.  From here you would press the 'F11' key once to get back into the target program's code then scroll up Softice's disassembly window and place further breakpoints on all of the conditional jump statements in our target program's code up until memory offset address 0044BB83. Once you've done this simply press 'x' to let the program run as normal.. Now re-run the registration screen again, re-type in your User details and observe where Softice breaks and try and change the program's normal flow as it is halted on each of your breakpoints..

Our next job is to find where in the program this message print routine was called from, this is sometimes dead easy to find and on other times it can be very difficult to find without using the assistance of Softice.. Let's see how we can do this..

We need to find a jmp or call instruction that goes to the beginning of our Message Print Routine which we know starts at memory offset: 0044BB83..  W32Dasm does NOT tell us this information, this is because the program will be using some kind of internal address table that it 'looks up' each time it needs to direct the program to our Message Print Routine.  If your using an Editor of some sort then simply search for 0044BB83 and you should find no instruction statement that refers to this memory offset address..

What we are looking for then is an Assembly instruction that looks like one of these examples:-

jmp [eax]
jmp [eax +00000123]
jmp [eax - 00000123]
call dword ptr [eax]
call dword prt [eax+00000123]
call dword ptr [eax-00000123]

Basically what these instructions are doing is to tell the computer to call or jump to the memory offset contained within the computer's register (in this example we are using the eax register).

Call                       = Tell the computer to prepare for a new place to visit.
Dword                  = Tell the computer to expect a memory address.
prt                         = Tell the computer to  'read' the address it needs from the given
                                 register and then add or subtract from this any numeric value
                                 assigned to this register
[eax+00000123] = If eax equals 80000000h then add 0123h so the pointer
                                address now reads 800000123h

So now the computer has been 'told' where in the computer's memory it should find the actual memory address to call, so it then 'read's the first four bytes starting from 800000128h and it's THIS memory offset address that the computer WILL go to.. This is only a basic example but should give you an idea on how this system of indirect addressing works.

With this in mind and while still in W32Dasm go to the beginning of the Message Print Routine and begin scrolling up the listing and note down all jumps and calls using this kind of indirect addressing.. Do about five or six.. Next find the end of our Message print Routine and again, make notes of about five or six statements that use this kind of indirect memory addressing. We DON'T want to cover the Whole listing, just a small section of code above and below where our Message Print Routine is located.. Most of the time you'll see that the code routines that deal with the protection system sit side by side to each other.. It makes it easier for programmers to debug these routines if they are all close by to each other..:)

If you've been able to follow this essay so far then you should have made the following notes on these suspicious memory locations code instructions:--
 
:0044BB1B FF1540DE4700            Call dword ptr [0047DE40]
:0044BB43 FF1540DE4700            Call dword ptr [0047DE40]
:0044BB65 FF90B8000000            call dword ptr [eax+000000B8]
:0044BB7C FF506C                  call [eax+6C]

Our Message print Routine lies here..

:0044BBB9 FF90B8000000            call dword ptr [eax+000000B8]
:0044BC55 FF9294000000            call dword ptr [edx+00000094]
:0044BC9F FF9294000000            call dword ptr [edx+00000094]
:0044BD0A FF5004                  call [eax+04]
:0044BD1E FF5024                  call [eax+24]
 
What we can do here is fire up our target program again, go into the registration screen and fill in the User details again. Then, press Ctrl-D and set a bpx messageboxa softice breakpoint (if you haven't already done this) and press the OK button to let the program begin checking our User details.. Once again the target program will display the 'beggar off cracker message' and Softice will break once you've clicked the 'OK' button to this message.  Now, scroll up AND down the disassembly listing and locate the instructions that I've shown above and when found, DOUBLE-CLICK on them which will tell Softice you want break on this line if it should ever get executed.

At this point all you need to do is re-run the program and when Softice breaks on one of these 'special' call statements do the following:-
 
Example:

Suppose you land on this instruction:
:0044BB65 FF90B8000000            call dword ptr [eax+000000B8]

Then you will need to type:
 
d eax+000000B8

This will display [in hex format] a series of number in your code window.

Now, in order to find out where this call instruction will take the program to we must now take the FIRST FOUR NUMBERS shown in our code window and REVERSE the sequence of numbers..

Like this.. The first four numbers in this case is: 6A284400 so all you need to do is type:
u 0044286A and this will show you where the program will go next.. Does this equal the start of our Message Print Routine at: 0044BB83?.

Now do this on ALL the Softice breakpoints that we've set..
 
Very quickly you'll come to this statement:

:0044BC9A 8B10                    mov edx, dword ptr [eax]
:0044BC9C FF75F0                  push [ebp-10]
:0044BC9F FF9294000000            call dword ptr [edx+00000094]
:0044BCA5 834DFCFF                or dword ptr [ebp-04], FFFFFFFF
:0044BCA9 8D4DF0                  lea ecx, dword ptr [ebp-10]
:0044BCAC 8BF0                    mov esi, eax

This is our 'babe', this is the one that we're interested in.

For those of you who are a little more *experienced* in cracking then yes, there is a much easier way to have found this instruction.. Once the 'Beggar off cracker' message was displayed we could have simply pressed the 'F11' key once to return to the target program's code then by pressing the 'F10' a few times we would come to a RET instruction which would have returned us here but I wanted to show how to find this return address for those occasions that this RET address method does not work.

Back to the essay...

If you scroll up the disassembly listing in W32Dasm you'll see there is only ONE conditional jump statement within this routine and dozens of further locations where this routine is called from, The single conditional jump statement inside this routine will still execute the 'beggar off cracker' routine so this we 'feel' is not where our serial number can be 'fetched', it still lies somewhere else..

Can you see that RET instruction at memory location:

:0044BCC1 C20C00                  ret 000C

You need to get back into the target program's code (use bpx messageboxa) again then type: bc * then place a new Softice breakpoint on THIS ret instruction.

Run the target program again through the registration screen and once again Softice will stop on this line, simply press the 'F10' key once and we will land here:-
 
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00418691(C), :004186A2(C)
 
:004189B9 6AFF                    push FFFFFFFF
:004189BB 6A00                    push 00000000
:004189BD 6A29                    push 00000029
:004189BF E89A320300              call 0044BC5E
:004189C4 8D4C2410                lea ecx, dword ptr [esp+10] ;We land here
:004189C8 C644243001              mov [esp+30], 01
:004189CD E8DBA90200              call 004433AD

We're nearly there..  Notice here that there are no cmp or test instructions in this small routine, so we know that this routine isn't the one we're after. If you look in your 'Dead Listing' of our target program you'll see two references to conditional jump statements that execute this routine. So simply pressing the F10 key to the end of this routine won't take you to any of these conditional jumps so we must locate them ourselves..  The two references shown are quite close to each other so lets examine this code a little more closer..

But first....

 type bc * to clear away any previous Softice breakpoints then x to leave Softice..
Run our target program through the registration screen.
Next, type bc messageboxa to create a new softice breakpoint.
Press 'OK' to let the program check our User details..  Softice now breaks...
Press the 'F11' key to allow the program to display the 'beggar off cracker' message.
Press 'OK' to close this message box.  Softice breaks again.
Type: bc * then bpx 00418681 then x to leave softice.

For the very LAST time re-run the target program again, fill in the User details again and let the program check our User details again.
 
Here's where the Softice breaks, it's before the two conditional jump statements that we've tracked down.
 

:00418681 8B4560                  mov eax, dword ptr [ebp+60]
:00418684 8D7560                  lea esi, dword ptr [ebp+60];esi=our User
                                                             ;Name
:00418687 C644243002              mov [esp+30], 02
:0041868C 8B48F8                  mov ecx, dword ptr [eax-08]
:0041868F 85C9                    test ecx, ecx
:00418691 0F8422030000            je 004189B9 ;If Username blank etc then
                                              ;jump
:00418697 8B4D5C                  mov ecx, dword ptr [ebp+5C];ecx=our fake
                                                             ;Serial No
:0041869A 8D7D5C                  lea edi, dword ptr [ebp+5C]
:0041869D 8B41F8                  mov eax, dword ptr [ecx-08]
:004186A0 85C0                    test eax, eax
:004186A2 0F8411030000            je 004189B9 ;if Serial No blank etc then
                                              ;jump
:004186A8 8D542414                lea edx, dword ptr [esp+14]
:004186AC 6A01                    push 00000001
:004186AE 52                      push edx
:004186AF 51                      push ecx
:004186B0 8BCC                    mov ecx, esp
:004186B2 89642430                mov dword ptr [esp+30], esp

;Save memory location of the real serial number at esp+30
:004186B6 56                      push esi
:004186B7 E8B6AB0200              call 00443272
:004186BC E8EF030000              call 00418AB0
:004186C1 8B442420                mov eax, dword ptr [esp+20] ;Real Serial

; At this point if you type: d eax you will see your 'REAL serial #

:004186C5 8B0F                    mov ecx, dword ptr [edi] 'fake serial
:004186C7 83C40C                  add esp, 0000000C
:004186CA 50                      push eax
:004186CB 51                      push ecx
:004186CC E85F5F0100              call 0042E630
:004186D1 83C408                  add esp, 00000008
:004186D4 F7D8                    neg eax
:004186D6 1BC0                    sbb eax, eax
:004186D8 40                      inc eax
:004186D9 84C0                    test al, al
:004186DB 0F84D7000000            je 004187B8 ;Invalid serial #? then jump

;Notice, instead of jumping to 004187B9 it jumps instead to 004187B8, one instruction LESS to our previous routine that we just examined.. The dead listing of our target program using W32Dasm didn't show this jump!

So here we have it, by typing  d eax when we have stopped at 00416C5 we can sniff out the real serial number for the user name we have typed into the program. Of course there are perhaps easier methods to get to this location but sooner or later your going to have to start to employ this cracking method shown if your going to *crack* some programs that try and fool the newbie cracker into giving up on cracking it's inner secrets.
 

Job Done.
 
The Crack 
     
None needed..
Final Notes 
 
This essay was not meant to be a straight forward go here then go here then type bla bla to get the serial number, instead I choose this program as an example of showing you how you might attack this program and more importantly, the actual 'thinking' process involved and why I did what I did before I was able to get to the actual instructions that revealed the real serial number. I suggest you treat this essay as a rough guide to this kind of *cracking* rather than one that takes you directly to the protection systems inner core without explaining to the reader (you) why or how this was done.

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 encourage them to produce even *better* software for us to use and enjoy.

Ripping off software through serials and cracks is for lamers..
 
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: 4th July 1998