Nov 1998
"The File Chopper V2"
( 'How to *think* like a cracker'  )
Win Code Reversing
by The Sandman 
Code Reversing For Beginners 
Program Details
Program Name: TheFileChopper.exe
Program Type: File Splitting Utility
Program Location: Here 
Program Size: 770K 
Tools Used:
 Softice V3.24 - Win'95 Debugger
W32Dasm V8.93 - Disassembler
Winice.Dat - Softice settings I used
Easy ( X )  Medium (X )  Hard ( )
There is a crack, a crack in everything. That's how the light gets in.
The File Chopper V2
( 'How to *think* like a cracker...'  )
Written by The Sandman
The author of The File Chopper  says:-
"1. Splits a big file into smaller files of desired sizes. These  sizes may be chosen either from a fully editable list of Base Sizes, or calculated from within the program.

2.  Restores the big file from the smaller ones."
About this protection system
This program has a 30 day, 5mb file handling restriction and a simple Nag Screen associated with it and is 'protected' by a serial registration code to prevent this program from be pirated.

On first running this program the following key is created in your System Registry File.

HKEY_USERS\.Default\Software\Matex Data HB\The File Chopper\

If you use REGMON or REGVIEW then you will discover the following entries that are of interest to us..

HKEY_USERS\.Default\Software\Matex Data HB\The File Chopper\License

ExpireDay     = 00008D37 (36151 Decimal)  DWORD
UserName     =""

The program is able to detect any tampering you may make to the ExpireDate value, in which case it will set the 'ExpireDate' so that you have just 1 day left to evaluate this program if you try and increase this value.. It's a simple job to do and is a somewhat wasted effort on behalf of the programmer(s) since if you delete the whole Key then the program then *thinks* it's never been run before and gives you yet another 30 free days to evaluate this program with. Obviously they hope you don't think of this simple trick *grin*
The Essay 
On october 23rd 1998 I opened up a new 'live' Cracking Forum called 'Cracking Challenges For All'  that is aimed at helping newbies learn how to crack in ways that tutorials and essay cannot teach you. This forum will perhaps for the FIRST time, open your eyes to the *real* world of cracking, forget about diving into a program and finding the 'crack', that's not what cracking is all about. Instead, here you will find out exactly what tuts and essay fail to show you, the inner workings of protection systems examined in a much greater detail than you thought possible.

This essay is the Third in a series of tuts based on a program that was featured in the 'Cracking Challengers For All' forum that shows what can be achieved if people join together to crack the same program.

OK, lets crack on with this essay...

On running this program you'll see a simple dialog box (a nag screen) showing you how many days you have left to evaluate this program, click OK to this message box.  Your now in the main program.. The Registration screen is found by selecting the Help then License Information option.

There's no Cancel button for this screen, so to quit it you need to either enter a valid serial number or click on the 'X' button found at the top right hand corner of the Registration Screen..

The program expects you, the User, to enter a User Name/Handle and a valid License Code.. One of the best ways to see if a programs expects an integer number or a alpha-numeric code is to type in a series of letters for the serial number.. That way, if the program expects just numbers then it will either crash or give you an error message stating that the serial number must be within the ranges of an Integer or words to this effect.. In our particular case, clicking on the 'Check The Code' button results in the message "Sorry, the license Code Entered Is Wrong!".  The program uses an Alpha-numeric serial number.
When you try and register this program you'll see a standard messagebox appear informing you that 'The license code entered is wrong!" which is ok because we can easily get softice to break on this function when we fire up Softice a little later on..

Lets create a Dead Listing of this program using W32Dasm, you can use IDA Pro if you wish but unless your an experienced cracker you might find the output a little hard to follow.

A quick look in our dead listing at the String Data Resources shows that there is a lot of text in both English & German, but lets carry on..

Having viewed the String Data Resources, I  tend to then perform a Search for my two favourite text strings:-

The Good Guy Message
The Bad Guy Message

Ok, lets search for the 'Good Guy' text "Thank you"

Remember, we're still in our Dead Listing... You should now see this section of code..:-

*StringData Ref from Data Obj ->"Correct license code entered. "
                              ->"Thank you for buying this program."

:00412964 BAA33B4800              mov edx, 00483BA3
:00412969 8D85E0FAFFFF            lea eax, dword ptr [ebp+FFFFFAE0]
:0041296F E8288D0600              call 0047B69C
:00412974 FF431C                  inc [ebx+1C]

<--------Snip, Snip------------>

:00412A08 BA02000000              mov edx, 00000002
:00412A0D E8E28D0600              call 0047B7F4
:00412A12 66C74310980C            mov [ebx+10], 0C98

*StringData Ref from Data Obj ->"Sorry, the license code entered is wrong!"

:00412A18 BA723C4800              mov edx, 00483C72
:00412A1D 8D85D4FAFFFF            lea eax, dword ptr [ebp+FFFFFAD4]
:00412A23 E8748C0600              call 0047B69C

OK, we've found the Good Guy & Bad Guy messages very close to each other, so no need to do any more searches..  Normally from here we would be able to back-track our way through the code to the conditional jump statement that would then decide which of these messages to display but 'The File Chopper' uses a different method of accessing routines to ones we're normally used to....

A quick look at the dead listing tells me that this program relies heavily on Memory Address Pointers which means W32Dasm is unable to work out where certain calls to routines are made from.

One of the main reasons for selecting 'The File Chopper' for this project was because of it's use of pointers to locate and execute many of it's internal routines, as well as some German text strings thrown in for good measure.  So often we read about and rely on Text strings to guide us around unfamiliar code, that when a program such 'The File Chopper' uses a different method of executing the code then we too must adopt a new perspective to this problem. For many of you, this is perhaps the first time you've come across a program that uses pointer addresses to move around the code with.

While our dead listing may at first seem somewhat hard to understand, we mustn't forget that the information we want is still being shown to us and we can still see some *possible* places to use some softice BPX's on. With programs that use pointers we will come to rely more and more on Softice's ability to show us where the program reads the pointer addresses from and where the program goes once it has read a pointer address. Our dead listing shows us possible places to place a bpx so make as many as you feel is necessary.  I find that the 'RET' instruction at the end of routines are extremely helpful, since they will automatically help us to 'back-track' through the code without worrying about where to Jump/Call the previous routine.

Using Memory pointers is a simply way to make life hard for newbie crackers when they try and follow the program's flow in their dead listings.  They are also very useful from the programmer's point of view because it's quite easy to perform 'self modifying' code techniques on the program itself,  now that would make things very interesting indeed but that's a totally different story!.

Here's a simple overview how Memory Address Pointers work..

The programmer sets aside an area of memory that he will use to hold the locations where some of his routines can be found. Lets call this area Table 1.

These memory addresses will be stored side-by-side and don't contain any assembler instructions such as jmp, jnz etc.

Suppose the target program has three routines, Routine 1, Routine 2, Routine 3 which the programmer wants to place their memory locations in a Table 1 then here's how it could be achieved..

Routine 1. Begins at memory address 4703ED32
Routine 2. Begins at memory address 416EDD00
Routine 3. Begins at memory address 445F3400

OK, we have three routine and we know where the begin, normally a program would use CALL 4703ED32 to execute the first routine or perhaps use a JNZ 4703ED32 which we all should be familiar with by now..  However, the programmer doesn't want you to see this in your dead listing so he will replace the normal Call and JNZ statements with ones that cannot be calculated easily by W32Dasm.

The programmer will 'take' the memory address of the above three routines and store them in an area within the program which we've called Table 1.


32ED0347  00DD6E41   00345F44
     :                   :                    :
     :                   :                    :------------Routine 3
     :                   :-----------------------------Routine 2
     :---------------------------------------------Routine 1

Notice how the routine addresses are 'reversed', that's how they are stored in PC's and other computer systems and dates back to the early days of computers..

OK, now the programmer has created a kind of look-up table but the rest of his program now need to be told WHERE and HOW to 'find' the addresses for Routine 1, Routine 2, Routine 3

First, the programmer will use one of the PC's internal registers to 'point' to Table 1.

Mov  EAX,40100000    <-------  Set Register EAX to point to Table 1

If you type d EAX then you'll see this:-

XXXXXXXX:40100000    32ED034700DD6E4100345F44

EAX is 'Pointing' to Table 1

XXXXXXXX:40100000  32
XXXXXXXX:40100000  ED
XXXXXXXX:40100000  03
XXXXXXXX:40100000  47
XXXXXXXX:40100000  00
XXXXXXXX:40100000  DD
XXXXXXXX:40100000  6E
XXXXXXXX:40100000  41

Now in order for the program to execute say, Routine 2 then it has to give the computer a little math's sum to tell it where to find the start of Routine 2.

CALL ptr [EAX+00000004]
           :      :
           :      :--------Memory offset =Routine 2 Address
           :---------------EAX           =Table 1

Table 1.

XXXXXXXX:40100000  00 ---  First Memory address at 40100000 offset 00 - Routine 1
XXXXXXXX:40100001  CD :
XXXXXXXX:40100002  67 :
XXXXXXXX:40100003  46 ------------

XXXXXXXX:40100004  56 --- Second Memory address at 40100004 offset 04 - Routine 2
XXXXXXXX:40100005  EF :
XXXXXXXX:40100006  32 :
XXXXXXXX:40100007  41 -----------

Looking at the above Call ptr [EAX+00000004] instruction we can see that the program will take the address of Routine 2 out of Table 1 by adding the offset value [00000002] in order to retrieve the memory address stored in this table.

Since memory addresses are stored in REVERSE order we need to reverse the order of these four bytes to get the correct address.

Does this make any sense?  Don't worry too much if it doesn't yet,  it will one day when your ready..:)
OK, back to cracking File Chopper....
We're going to crack this babe via two different methods, the first method we will choose is the nop'ing of a conditional jump, a classic newbie crack and the other way we shall sniff out the *real* serial number so that we can *register* this program with whatever Name/Handle we choose.. Interestingly, when we come to sniffing out the serial number we will come across an interesting 'bug' in the program, more of this later...

CRACK METHOD ONE - A Classic Newbie Patch

One of the most popular methods a program can use to determine how many days you have left to evaluate the program is to read the PC's internal clock and then take this date from the date of the file itself..  In fact, the program could use an entry in your System Registry file but it doesn't matter what it uses, for us all we need to know right now is that we can get Softice to trap this process using the function found in  Kernel32!GetLocalTime.
Why would we use GetlocalTime and how does this help us?..  Well, before a program is able to determine if it's been 'registered' or not or that you've 'run of of time' for evaluating the software with the program must carry a set of steps that we can make use of.. This knowledge comes from experience and a dash of logic..

Here's a simple overview of what I mean..

On start-up the program obtains the pc's internal date.  It then checks this date against an entry stored in your System Registry File or with the program's .EXE file itself. If, by subtracting the 'current' pc's date by the date stored in your system registry file or from the date assigned to the program's .EXE file produces a 'negative' number then the program will now check to see if it has been 'Registered' or not.  It does this by trying to retrieve the user's details from the System Registry file, or even from a hidden file stored someone on the User's hard disk. If this checks out ok then the program will insert a value of '1' into a memory location that signifies to to the rest of the program that it has been registered, if not then a value of '0' will be inserted into this same memory location..

At this point if the program has not been registered and the User has 'run out of' credit then a messagebox, the first sign of any activity from the program appears,  informing the User they have no more 'free' time, after which the program will exit back to windows.   If the User does have some 'free' time left and the program has not been registered then a 'Nag Screen' appears before the main program has had chance to be displayed.

If the program has been registered then the Nag Screen is bypassed and the main program is executed...

All this sounds very complicated but in reality it's just a set of logical steps that makes sense if you give this matter some further thought...

OK, we have a general idea of the processes involved before the Nag Screen is displayed, so lets see how this looks in 'The File Chopper'...

Before running The File Chopper, lets fire up Softice (Ctrl & D keys together) and type: bpx getlocaltime then x to exit Softice..

Now start up File Chopper..

Softice breaks at: KERNEL32!SetFileTime :BFF7717D

Type: bd 00 to disable the GetLocalTime breakpoint, it's done it's job so we don't need it anymore.

Press F11 once to allow Softice to finish executing this function and break once again at the point where File Chopper originally called this function,,

We should now see this snippet of code...

:00467905 668B4C240E              mov cx, word ptr [esp+0E]  ;cx= current day
:0046790A 668B54240A              mov dx, word ptr [esp+0A]  ;dx= current month
:0046790F 668B442408              mov ax, word ptr [esp+08]  ;ax= current year
:00467914 E81FFEFFFF              call 00467738
:00467919 DD1C24                  fstp qword ptr [esp]       ;esp=036134h
:0046791C 9B                      wait
:0046791D DD0424                  fld qword ptr [esp]
:00467920 83C418                  add esp, 00000018
:00467923 C3                      ret                        ;this RETurns us to 0047BD30

OK, the above code snippet simply assigns the cx,dx,ax registers with the current date from our PC's local clock, which is stored at ESP+0E,ESP+)A, and ESP+08 respectively.. F10 through this code and you will be RETurned to this code block:-

:0047BD30 5D                      pop ebp ;F10 through these two instructions.
:0047BD31 C3                      ret     ;this RETurns us to 00403E2E

Once you F10 on the RET instruction we are now taken to this large code block... Now some of you have commented on some of my tuts that they don't always show the 'thinking' behind the tracing of code blocks so here's what I did..

:00403E2E DD9D28FFFFFF            fstp qword ptr [ebp+FFFFFF28] ;We land here...
:00403E34 DD8528FFFFFF            fld qword ptr [ebp+FFFFFF28]
:00403E3A E841000700              call 00473E80
:00403E3F 898530FFFFFF            mov dword ptr [ebp+FFFFFF30], eax
:00403E45 8D5720                  lea edx, dword ptr [edi+20]
:00403E48 8D8314030000            lea eax, dword ptr [ebx+00000314]
:00403E4E E8D1790700              call 0047B824
:00403E53 8B55FC                  mov edx, dword ptr [ebp-04]
:00403E56 8D4DFC                  lea ecx, dword ptr [ebp-04]
:00403E59 52                      push edx
:00403E5A 51                      push ecx
:00403E5B 66C74610A400            mov [esi+10], 00A4
:00403E61 BA0BD64700              mov edx, 0047D60B 
:00403E66 8D45C0                  lea eax, dword ptr [ebp-40] ;Type: edx = UserName
:00403E69 E82E780700              call 0047B69C
:00403E6E FF461C                  inc [esi+1C]
:00403E71 8B08                    mov ecx, dword ptr [eax]
:00403E73 51                      push ecx                    ;Type: ecx = UserName
:00403E74 8B8314030000            mov eax, dword ptr [ebx+00000314]
:00403E7A 50                      push eax                    ;Type: eax = License
:00403E7B 57                      push edi
:00403E7C E84FC50100              call 004203D0
:00403E81 83C414                  add esp, 00000014
:00403E84 FF4E1C                  dec [esi+1C]
:00403E87 8D45C0                  lea eax, dword ptr [ebp-40]
:00403E8A BA02000000              mov edx, 00000002
:00403E8F E860790700              call 0047B7F4
:00403E94 66C74610B000            mov [esi+10], 00B0
:00403E9A BA20D64700              mov edx, 0047D620
:00403E9F 8D45BC                  lea eax, dword ptr [ebp-44]  ;Type: edx = ExpireDay
:00403EA2 E8F5770700              call 0047B69C
:00403EA7 FF461C                  inc [esi+1C]
:00403EAA BA14D64700              mov edx, 0047D614
:00403EAF 8B08                    mov ecx, dword ptr [eax]     ;Type: edx = LicenseCode
:00403EB1 8D45F8                  lea eax, dword ptr [ebp-08]
:00403EB4 51                      push ecx
:00403EB5 50                      push eax
:00403EB6 8D45B8                  lea eax, dword ptr [ebp-48]
:00403EB9 E8DE770700              call 0047B69C
:00403EBE FF461C                  inc [esi+1C]
:00403EC1 8B10                    mov edx, dword ptr [eax]
:00403EC3 52                      push edx                                         ;Type: edx = LicenseCode
:00403EC4 8B8B14030000            mov ecx, dword ptr [ebx+00000314]
:00403ECA 51                      push ecx                                         ;Type: ecx = License
:00403ECB 57                      push edi
:00403ECC E8FFC40100              call 004203D0
:00403ED1 83C414                  add esp, 00000014
:00403ED4 FF4E1C                  dec [esi+1C]
:00403ED7 8D45B8                  lea eax, dword ptr [ebp-48]
:00403EDA BA02000000              mov edx, 00000002
:00403EDF E810790700              call 0047B7F4
:00403EE4 FF4E1C                  dec [esi+1C]
:00403EE7 8D45BC                  lea eax, dword ptr [ebp-44]
:00403EEA BA02000000              mov edx, 00000002
:00403EEF E800790700              call 0047B7F4
:00403EF4 8D8D3CFFFFFF            lea ecx, dword ptr [ebp+FFFFFF3C]
:00403EFA 6A00                    push 00000000
:00403EFC 51                      push ecx
:00403EFD BA21D64700              mov edx, 0047D621
:00403F02 66C74610BC00            mov [esi+10], 00BC                    ;Type: edx = ExpireDay
:00403F08 8D45B4                  lea eax, dword ptr [ebp-4C]
:00403F0B E88C770700              call 0047B69C
:00403F10 FF461C                  inc [esi+1C]
:00403F13 8B08                    mov ecx, dword ptr [eax]
:00403F15 51                      push ecx
:00403F16 8B8314030000            mov eax, dword ptr [ebx+00000314]
:00403F1C 50                      push eax
:00403F1D 57                      push edi
:00403F1E E811C70100              call 00420634
:00403F23 83C414                  add esp, 00000014
:00403F26 FF4E1C                  dec [esi+1C]
:00403F29 8D45B4                  lea eax, dword ptr [ebp-4C]
:00403F2C BA02000000              mov edx, 00000002
:00403F31 E8BE780700              call 0047B7F4 ;Check if this is the first time we are running
                                                ;this program for the first time.

; Check if memory address ebp+FFFFFF3C = 0.
; If it does then this is the first time this program has been run on the User's computer.

:00403F36 83BD3CFFFFFF00          cmp dword ptr [ebp+FFFFFF3C], 00000000

:00403F3D 0F85CF000000            jne 00404012 ;jump if not equal to 0, program has already been

At this point if the program is being run for the FIRST time, (we can stimulate this by deleting the whole registration entry at: HKEY_CURRENT_USER\Software\Matex Data HB ) then the program WON'T jump to 0040412 but continue to execute the code following this jump.  In your dead listing you will see that the program now begins to create the nessasary entries in our System Registry file for this program to use later on.

Since NOP'ing the jne 00404012 serves no purpose other than giving us unlimited evaluation period with Nag Screen we must follow the jump instead to the code block at 00404012.

We arrive now to our final block of code, which accesses the System Registry file and attempts to fetch and User Registration details. I know this because as I executed each instruction I displayed the contents of the most recently changed registers.

:00404012 66C74610EC00        mov [esi+10], 00EC
:00404018 33C9                xor ecx, ecx
:0040401A 894DA4              mov dword ptr [ebp-5C], ecx
:0040401D 8D4DA4              lea ecx, dword ptr [ebp-5C]
:00404020 FF461C              inc [esi+1C]
:00404023 B850A54900          mov eax, 0049A550
:00404028 8B55FC              mov edx, dword ptr [ebp-04] ;edx = User Name from registry file
:0040402B E854D50100          call 00421584               ;See if User Name exits
                                                          ;If no User Name exist, then
                                                          ;User Name =""
:00404030 8D55A4              lea edx, dword ptr [ebp-5C]
:00404033 8D45F8              lea eax, dword ptr [ebp-08] ;eax = Serial No from registry file
:00404036 E89D780700          call 0047B8D8               ;See if Serial # exists
                                                          ;If no Serial # exists, then
:0040403B 50                  push eax
:0040403C FF4E1C              dec [esi+1C]
:0040403F 8D45A4              lea eax, dword ptr [ebp-5C]
:00404042 BA02000000          mov edx, 00000002
:00404047 E8A8770700          call 0047B7F4
:0040404C 59                  pop ecx
:0040404D 84C9                test cl, cl                 ;does cl = 0?
:0040404F 740C                je 0040405D                 ;Jump and place a '0' in the
                                                          ;Shareware/Registration Flag

;If serial from your system registry file matches the one the program has created then place ;the value '1' into memory location [0047D320].

:00404051 C60520D3470001      mov byte ptr [0047D320], 01 ;Our Registration Flag!
:00404058 E95C020000          jmp 004042B9                ;Ignore Nag Screen Reminder
:0040405D C60520D3470000      mov byte ptr [0047D320], 00 ;Our Shareware Flag!

I know what your thinking, we could NOP out the je 0040405D instruction and then the program will always be Registered each time it is run!.. Well although it does look promising we have to remember that once this jump is patched and run for the FIRST time then the program WON'T come here!. Remember, this program detects if it has not been run and then directs the program away from the above routine where it will display that horrible "You have 30 days to evaluate this software bla bla bla".. If you didn't want this then you would then also have to change the:

:00403F3D            jne 00404012


:00403F3D            jmp 00404012

Now we are begin to patch this program in two different places... To add to this mess, unless you now go into the System Registry file and enter your User Name/Handle and a fake serial directly into the System registry file then this program will show that it's been registered by someone with no name using no registration code!.  It's getting to be a messy job already!..

Is there another way we could 'crack' this program without any patching of the code and which makes use of the knowledge we've already gained?

As a matter of fact this is...

CRACK METHOD TWO - Sniffing Out A Valid Serial

Ok, where would we begin?...

Well if you've *tried* to patch this program and as a rule, Newbies tend to try this out first then you will already have covered most of the ground work leaving you now to fish out the serial number.. Easier said than done at this stage so lets see what we can do..

Lets just re-cap on what we've already covered..

The program must at least, generate a valid serial number for our User Name at least twice, once at run time when it tries to fetch the User's Details from the System Registry file and once when the User tries to register the program.  The work we've already covered concentrated on the routines that are executed at start up time. Don't ask me why, but I always feel that a program is at it's weakest at run-time rather than trying to go through it once it's fully loaded into memory.. Perhaps because at run-time we can get a lock on any of it's nag screens/dialog boxes etc..


Go back to the 'final' stage of the above crack, just from what details we got from some of the registers and the fact  that if we forced Softice to skip over the je 0040405D instruction we could fool the program into registering this program then we would know (feel) that the *real* serial was close by..  Lets take a closer look at this routine a little more closer, in fact just the top half of it...

:00404012 66C74610EC00        mov [esi+10], 00EC
:00404018 33C9                xor ecx, ecx

;At this point Register ECX has just been zero'd out by the XOR instruction on it's self...


If at this point we now type: d ebp-5c  we should see something like this in Softice's Hex/ASCII Code Window:- 

XXXX:006EFCC0: 00 17 17 00 00 00 XX XX XX XX XX XX XX XX XX XX XX 

*Address in blue may be different on your computer *** 

These numbers don't mean much to us at this point but if we remember that this program relies heavily on 
Address Pointers then what we're looking at is memory location that 'stores' an address to another part of the 
computer's memory. All we're doing is seeing what the significance of [EBP-5C]. it might pay us to keep a
closer eye on this memory location for the next few instructions. 


:0040401A 894DA4              mov dword ptr [ebp-5C], ecx

After executing the above instruction the bytes shown in Softice Hex/ASCII Code Window show this:-  

XXXX:006EFCC0: 00 17 17 00 00 00 00 XX XX XX XX XX XX XX XX XX XX 

*Address in blue may be different on your computer *** 

The program has in effect, made sure it starts off with a 'clean' slate. It's good programming policy 
to do this sort of action especially where this memory location may be uased for other purposes 
later on in this program.  


:0040401D 8D4DA4              lea ecx, dword ptr [ebp-5C]  ;ecx now = XXXX:006EFCC0:
:00404020 FF461C              inc [esi+1C]
:00404023 B850A54900          mov eax, 0049A550
:00404028 8B55FC              mov edx, dword ptr [ebp-04] ;edx = User Name from registry file
:0040402B E854D50100          call 00421584               ;See if User Name exits
                                                          ;If no User Name exist, then
                                                          ;User Name =""

After executing the Call 00421584 instruction the bytes shown in Softice Hex/ASCII Code Window show this:-  

XXXX:006EFCC0: B0 AA C1 00 00 00 00 XX XX XX XX XX XX XX XX XX XX 

OK, the Call to 00421584 has updated the first four bytes pointed to by [EBP-5C], so lets take a look 
where these 'new' four bytes point to.. 

Type: d 00C1AABO  notice I've 'reversed' their order, you must remember to do this. 

Hey, whats this! 

XXXX:00C1AABO 34302D34312D3632-2d30332D35320000        40-41-62-03-52.. 

This looks like a serial number but their isn't any User Names in the System registry file for this program 
to create any serials for!. Unless, that is, this program has generated a serial numer for a non-existant 
User Name!.  In fact this is the case, the serial number you see is for a Blank/Empty User Name which I 
consider a 'bug' in the program. What the program should do is,  on finding an empty User Name to abort 
any further processing of the Registration File and not bother processing a serial number.. 

If the abov serial number you can now go into the Registration Screen and simply type in this serial 
number, leaving the User Name BLANK and the program will become Fully Registered..:) 

Having a Registered Program that does not have our User Name/Handle feels like we've only done half 
a job on this program, so lets finish it properly.. 

Fire up REGEDIT and go to this entry:- 

HKEY_CURRENT_USER\Software\Matex Data HB\The File Chopper\License 

For the UserName type in: Pirate Copy 


Create a Softice breakpoint: Type: BPX getlocaltime then x to leave Softice 

Run 'The File Chopper' 

Softice Breaks at the start of the GetLocalTime system function.... 

Press F11 once.. 

Keep pressing F10 UNTIL you land here:- 

:00404030 8D55A4              lea edx, dword ptr [ebp-5C] 

Type: d ebp-5c 

Take the first four bytes you see in Softice's Hex/ASCII Code Window in reverse order and type: D XXXXXXXX 

We should see something like this:- 

XXXX:00C1AABO 39382D31312D3335-2D30302D31360000        98-11-35-00-16.. 

Now we can fully register File Chopper with our User Name of 'Pirate Copy' using the serial of: 98-11-35-00-16


Job Done.
The Crack
None is required nor needed. 
Final Notes 

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.

Everyone who took part in the 'Cracking Challenges For All' forum.
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 be encouraged to producing 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: 06th December 1998