Dec 1998
"Registry Crawler V1.2"
 'How to *think* like a cracker''
Win '95 PROGRAM
Win Code Reversing
 
 
by The Sandman 
 
 
Code Reversing For Beginners 
 
 
 
Program Details
Program Name: regc.zip
Program Type: System Registry Utility
Program Location: Here 
Program Size: 223K
 
 Winice.Dat - Softice settings I used
       
Tools Used:
 Softice V3.24 - Win'95 Debugger
W32Dasm V8.93 - Disassembler
 
Rating
Easy ( X )  Medium ( )  Hard ( )
There is a crack, a crack in everything. That's how the light gets in.
 
      
 
Registry Crawler V1.2
'How to *think* like a cracker...'
Written by The Sandman
 
 
Introduction
 
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 Fourth 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.
 
 


If you wish to download the whole of this project,
complete with all the postings (164K) then download it from Here
 
Install to an empty directory then run: 33330.html


 
 
The authors of Registry Crawler says: "Registry Crawler is designed to enable power users and developers to quickly find and configure Registry settings. The software provides a powerful search engine that allows you to find Registry information based on a search criteria. Results are displayed in a list allowing you to access any key found with a single mouse click. Registry Crawler has built in support for ôbookmarksö. You can bookmark any key in the Registry and then access it directly from the system tray. This powerful feature allows you to create a set of Registry keys that you frequently access eliminating the need to manually open REGEDIT. Registry Crawler uses the  REGEDIT tool so you don't need to learn how to edit, delete or rename registry keys. Users that access the Registry on a daily basis will find Registry Crawler to be a great time saver."
 
About this protection system
 
The protection systems employed within Registry Crawler consist of the following:-

1. Deep within your System Registry it uses the following branch to store it's program settings and User Registration.

HKEY_LOCAL_MACHINE\SOFTWARE\4Developers\RCrawler
   
2. It's a 30 day, time limited program that will 'expire' after 30 days of being installed.
 
3. The Day's Left... counter is located in a file called RCW.d98 and is placed in your C:\windows directory. This file will be deleted by the program itself once the User has used up their 30 days evaluation period.

When first run, this hidden file will contain the following number:-
 
729650
 
Now this number won't at first, mean very much to us, but once we later learn that it is in fact, our 'days remaining' counter then we can begin trying to work out what formula it is based on.  Typically, (but not always) it will be based on a simple method that the majority of Shareware programs out today uses. In the case of 'Registry Crawler' our 'Days remaining' is based on this formula:-

729650 / Current Year / Current Month = Days remaining

So the number 729650 represents the TOTAL number of days since the year 0000.  The formula used by the program does not take into account leap years and assigns 30 days to each month regardless of wether some months have 28 days or 31 days in them.

In my case I can calculate how many days left I have using this formula:-

729650 / (Current Year) 1998    = 365 Days
365 days / (Current Month) 12   =   30 Days <----Number of days I have left

All the program needs to do is fetch the current Year & Month from your pc then convert this to days like this:  1998 X 12 = 23976 days (Current Year X Current Month).  Then the program will subtract this number from 729650 and if the result becomes negative then you have used all your 30 day evaluation period.
 
The Essay 
 
For this essay I will be using the User Name of: Pirate Copy and a serial of: 7777777

After running this program several times using different Crackerz tools such as REGMON, FILEMON and making plenty of notes as I went along it was time to dead list this babe..

W32Dasm is my personal choice for creating a dead listing, although many experienced crackers prefer to use IDA Pro, but if your a newbie stick with W32Dasm for now, it's much easier to use and follow....

In my dead listing I always go straight into the String Data Resources of the target program, we can gain a lot of valuable info just by noting down what we see and what looks interesting..

Mem Location                        String
-------------------------------------------------------------

004012DD            " - UNREGISTERED VERSION"
00402D52            "\RCW.D98"

004039F9            "4D"
00403E16            "4D"

004A3AAB            "8267-"
00403E65            "REGISTERED User"
00403C5A            "Registered Version"

00403D03            "Thank you for very much for trying "
004036EA            "Welcome to the Registered Version "

00403B81            "YMA19X@24$Z%"
00403A9F            "YMA19X@24$Z%"

00403E9B            "The registration information you "
 
 
There are many other interesting strings but these will do for us..

As newbies our attention may go directly to the string reference "YMA19X@24$Z%" which 'looks' like a serial number and we may even try and enter this as our serial number.. Program responds by informing you that the serial number is incorrect"... Oh well, it was worth a try..

OK, our next attempt is usually to locate a 'Bad Cracker' type message and try and backtrack through the code a little until we find the first conditional jump statement.. The idea here is that if we find this conditional jump that leads to our 'Bad Cracker' message then it also should show us where the 'Good Boy' message string is at the same time!.  Do programs really work like this and can they be cracked as easily as this!.. Well, the only way to find out is by trying this idea out for ourselves..

Right, if you've run this program a few times and also tried to register it using some false serial numbers then you'll know that the 'Bad Cracker' message begins with: "The registration information you " so in our String Data Resources locate this piece of text and double-click on it..
 
 

You should see this code fragment...
 

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403DD0(C)
|
:00403E7B 6AFF                    push FFFFFFFF
:00403E7D FF15C8E94000            Call USER32.MessageBeep
:00403E83 837DF000                cmp dword ptr [ebp-10], 00000000
:00403E87 B800000000              mov eax, 00000000
:00403E8C 7406                    je 00403E94 ->Since this jump does not
                                              ->skip over our 'Bad Cracker'
                                              ->message we can ignore it.
:00403E8E 8B45F0                  mov eax, dword ptr [ebp-10]
:00403E91 8B4020                  mov eax, dword ptr [eax+20]
:00403E94 6A30                    push 00000030 -> Message Box Type
:00403E96 683CCB4000              push 0040CB3C ->"UNREGISTERED User"
:00403E9B 68FCC94000              push 0040C9FC ->"The registration
                                                -> information you "
                                                ->"have entered could not
                                                ->be validated."
:00403EA0 50                      push eax
:00403EA1 FF1508EA4000            Call USER32.MessageBoxA ->Display Message
                                                           ->to User
:00403EA7 E90EFFFFFF              jmp 00403DBA
 

What is of importance to us is that we've found just one occurrence of the 'Bad Cracker' message and that this program calls this routine from memory location 00403DD0 so lets now go and examine this memory location..

* Referenced by a (C)onditional Jump at Address :00403DAE(C)
|
:00403DC9 E872FCFFFF              call 00403A40 ;Check *real* & *Fake*
                                                ;serials
                                                ;Returns:
                                                ;EAX=00000000 if wrong #
                                                ;EAX=00000001 if correct #
 
:00403DCE 85C0                    test eax, eax ;Eax=0?
:00403DD0 0F84A5000000            je 00403E7B   ;If eax=0 then 'Beggar off
                                                ;Cracker'

The (J)ump if (E)qual instruction as we know, goes directly to our 'Beggar off cracker' message routine but how do (I) know at this stage that the code after this conditional jump is where the program registers itself?.
 
 

From using REGMON I saw that this program on being run, checks for the  presence of a key 
called '4D'  in our System Registry here:  

HKEY_LOCAL_MACHINE\SOFTWARE\4Developers\RCrawler which because it's not present yet, is a  good indicator that it could be created only when this program is registered.   

Therefore, it's also very likely that the program must create this new key after our serial has been checked and accepted and not before.. This kind of thinking comes with time and lots of practice and while it's only a hunch it's still worth checking out.  

Anyway,  

If this is so, then the steps this program would have to take in order to create this new key would go something like this:-  

   1. Using the system .DLL & function ADVAPI32.RegCreateKeyExA prepare  
   to create and assign a new key name within the User's System Registry  
   at branch:  HKEY_LOCAL_MACHINE\SOFTWARE\4Developers\RCrawler   

   2. Assign a new key called "4D" and give it a value representing our  
   valid serial number. The program would use the system dll & function  
   ADVAPI32.RegSetValueExA 

   3. Finally, use the system .DLL & function ADVAPI32.RegCloseKey to 
   end  this process.  

With this in mind now look at the code that lies below our je 00403E7B instruction!!  
  

:00403DD6 8D45E8                  lea eax, dword ptr [ebp-18] 
:00403DD9 8D4DEC                  lea ecx, dword ptr [ebp-14] 
:00403DDC C745E800000000          mov [ebp-18], 00000000 
:00403DE3 C745EC00000000          mov [ebp-14], 00000000 
:00403DEA 50                      push eax 
:00403DEB 51                      push ecx 
:00403DEC 6A00                    push 00000000 

* Possible StringData Ref from Data Obj ->"Software\4Developers\RCrawler" 

:00403DEE 8B15ECC64000            mov edx dword ptr [0040C6EC]  
:00403DF4 683F000F00              push 000F003F 
:00403DF9 6A00                    push 00000000 
:00403DFB 6A00                    push 00000000 
:00403DFD 6A00                    push 00000000 
:00403DFF 52                      push edx 
:00403E00 6802000080              push 80000002  
:00403E05 FF158CE54000            Call ADVAPI32.RegCreateKeyExA  
:00403E0B 8BF8                    mov edi, eax  
:00403E0D 85FF                    test edi, edi  
:00403E0F 752E                    jne 00403E3F ;Jump if problem found 
                                              ;updating the User System 
                                              ;Registry 
:00403E11 6800020000              push 00000200  
:00403E16 A1F4C64000              mov eax, dword ptr [0040C6F4] ->"4D" 
:00403E1B 68F8C64000              push 0040C6F8 
:00403E20 8B4DEC                  mov ecx, dword ptr [ebp-14] 
:00403E23 6A03                    push 00000003 
:00403E25 6A00                    push 00000000 
:00403E27 50                      push eax 
:00403E28 51                      push ecx 
:00403E29 FF1588E54000            Call ADVAPI32.RegSetValueExA  
:00403E2F 8BF8                    mov edi, eax 
:00403E31 8B45EC                  mov eax, dword ptr [ebp-14] 
:00403E34 50                      push eax 
:00403E35 FF157CE54000            Call ADVAPI32.RegCloseKey  
:00403E3B 85FF                    test edi, edi 
:00403E3D 7413                    je 00403E52 ;Jump if problem found 
                                              ;updating the User System 
                                              ;Registry 

Can you see the same 'pattern' of events as described above? and that this code will be executed IF the serial is found to be correct!. 
 

 
Lets continue on with our fishing for serial numbers... Take another look at this code fragment.

* Referenced by a (C)onditional Jump at Address :00403DAE(C)

:00403DC9 E872FCFFFF              call 00403A40 ;Check *real* & *Fake* #
                                                ;Returns:
                                                ;EAX=00000000 if wrong #
                                                ;EAX=00000001 if correct #

:00403DCE 85C0                    test eax, eax ;Eax=0?
:00403DD0 0F84A5000000            je 00403E7B   ;If eax=0 then 'Beggar off
                                                ;Cracker'

At this point I'm assuming that the call 00403A40 goes to the serial generation routine because if the Test eax,eax fails, then I know that the program will execute the 'Beggar off Cracker' routine. What's the opposite of an invalid serial? that's right, a correct one and as expected, the code underneath the je 00403e7B does in fact, appear to create and save a new Key called 4D and give it a value of some sort into our System Registry file.

We need to explore where that call 00403A40 goes to more closely...

:00403A40 64A100000000       mov eax, dword ptr fs:[00000000] ;We land here
:00403A46 55                 push ebp
:00403A47 8BEC               mov ebp, esp
:00403A49 6AFF               push FFFFFFFF
:00403A4B 68193C4000         push 00403C19
:00403A50 B9FFFFFFFF         mov ecx, FFFFFFFF
:00403A55 50                 push eax
:00403A56 64892500000000     mov dword ptr fs:[00000000], esp
:00403A5D 83EC0C             sub esp, 0000000C
:00403A60 2BC0               sub eax, eax
:00403A62 57                 push edi
:00403A63 BFF8C64000         mov edi, 0040C6F8 ;Location of our User Name
:00403A68 F2                 repnz         ;Count/Copy letters in User name
:00403A69 AE                 scasb
:00403A6A F7D1               not ecx    ;ECX = length of User Name+1
:00403A6C 49                 dec ecx    ;Dec ECX by 1 to correct length of
                                        ;UserName
:00403A6D 83F908             cmp ecx, 00000008
:00403A70 7311               jnb 00403A83 ;Continue if UserName >=8 letters

:00403A72 33C0               xor eax, eax ;Else tidy up and zero eax
                                          ;register
:00403A74 8B4DF4             mov ecx, dword ptr [ebp-0C]
:00403A77 5F                 pop edi
:00403A78 64890D00000000     mov dword ptr fs:[00000000], ecx
:00403A7F 8BE5               mov esp, ebp
:00403A81 5D                 pop ebp
:00403A82 C3                 ret

The above section of code simply checks to see if the User Name is 8 or more characters in length, if less than 8 letters then zero the eax register and exit this sub routine. When the program exits this routine the test eax, eax at memory location 00403DCE on finding that the eax register contains the value of 0 will treat this as though you entered an invalid serial number.
 
 
:00403A83 BFF8C64000         mov edi, 0040C6F8
:00403A88 B9FFFFFFFF         mov ecx, FFFFFFFF
:00403A8D 2BC0               sub eax, eax
:00403A8F F2                 repnz
:00403A90 AE                 scasb
:00403A91 F7D1               not ecx
:00403A93 2BD2               sub edx, edx
:00403A95 8D41FF             lea eax, dword ptr [ecx-01]
:00403A98 B90C000000         mov ecx, 0000000C
:00403A9D F7F1               div ecx
:00403A9F A1F0C64000         mov eax, dword ptr [0040C6F0] ->"YMA19X@24$Z%"
:00403AA4 8D4DF0             lea ecx, dword ptr [ebp-10]
:00403AA7 8A0410             mov al, byte ptr [eax+edx]
:00403AAA 50                 push eax
:00403AAB 6810C94000         push 0040C910 ->"8267-"
:00403AB0 E8F94A0000         Call 004085AE
:00403AB5 50                 push eax >-----:
                                            :
:------------<---------<--------------<------
:
At this point type: d eax

In your Softice Hex/Ascii window you'll see something like this:-
 
00660D74XXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
 
The first four numbers [00660D74] represent a further memory address which in order for you to see you must reverse the sequence like this:-

Type: d 740D6600 (in reversed order)

Now Softice's hex/Ascii window you should now see

8267-XXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX

Now just keep pressing F10 until you land at: :00403B73
 

< Snip Snip >

:00403B6A 3B4DF0                cmp ecx, dword ptr [ebp-10]
:00403B6D 0F877AFFFFFF          ja 00403AED   ->End of main character loop
:00403B73 8B45EC                mov eax, dword ptr [ebp-14]

The above code block starting from 00403AED to 00403B60 is the 'main' loop to the generation of our *real* serial number. This section of code grabs one letter from our User Name at a time and 'converts' it to a valid serial code.  Now it would be easy for a newbie to assume that once the routine had reached this far that the serial they can see in Softice's Hex/Ascii Code Window was the 'full' serial they need to register this program.. Wrong.. Our serial number needs one more letter adding to it before it will be recoqnised as a true serial number for our User Name..

You need to keep pressing the F10 key Until you land here:-
 

:00403B92 E8114D0000        Call 004088A8 ;Add the final letter to our
                                          ;*real* serial #
                                           ;Returns:-
                                           ;EAX = Address where *real*
                                           ;serial is stored.

:00403B97 50                 push eax      ;Save the address of the *real*
                                           ;serial number
 

One the program returns from executing the Call 004088A8 instruction our serial number is now complete and the EAX register now points to the memory location that holds the address of where we can now sniff out our fully created serial number..

At this point type: d eax  ; In your Softice Hex/Ascii window you'll see something like:
 

00660D74XXXXXXXX
 XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX

Now type: d followed by these first four bytes in reverse order.

In my case I typed: d 740D6600

Now we can see our serial number in all it's glory for the User Name of: Pirate Copy..

8267-%JR2ZZ............
.......................
.......................

Once the program has been successfully 'registered' a new Binary key called 4D will be created at:-  HKEY_LOCAL_MACHINE\SOFTWARE\4Developers\RCrawler

Our new Binary key, 4D will be made up as follows:-

50697261746520436F7079    =  Pirate Copy
0000000000000000000000
0000000000000000000000
0000000000000000000000
0000000000000000000000
0000000000000000000000
0000000000000000000000
0000000000000000000000
0000000000000000000000
8267-%JR2ZZ00000000000   = Serial Number
0000000000000000000000
0000000000000000000000
0000000000000000000000
0000000000000000000000
0000000000000000000000
0000000000000000000000
0000000000000000000000
0000000000000000000000  = 512 bytes in total

Here are two explanations provided on the forum to how the serial number is generated...
 

In the words of Joseph,  

The Registry Crawler uses the numbers 3,12 and a funny string of characters "YMA19X@24$Z%" as constants, in addition to this the program uses the length of the User's Name as another constant. one important variable is the the position of the character being proceessed, starting with 0 to n (n being the length of the user name).  

The first 5 characters in any serial number are the same for any User. 

First the program divides the length of the User Name by 12 and takes the remander and uses it as an offset to extract a character from the funny string. Thus, if the User Name is 8 chracter then the program will take the 8th charcter from this string which will be 4 as the first calculated character in the serial number--remember the count starts with 0. 

Next the position, which will be 0,1.2....n, and divides it by 3. If there is any remainder the program skips to the next character (using techi lingo, the program evaluates the modulo of n/3). This way only characters positioned at 0,3, 6,9 etc. are meaningful. Once a chracter is selected this way its Ascii value is divided by 2 and the integer result is added to 22.  If the result is within the accepted range, which is the alphanumarical, then this new character is added to the serial number. Each calculated character is appended to 8267- in its turn. 

After all characters in the User Name are processed, their total length count becomes significant. In the case of an 8 character long User Name 4 characters are generated in the above discribed procedure. thus after appendig  to 8267- the length becoms 9. This 9 is divided by 12 and the mod (remainder) is used to extract the final character in the serial number, thus an 8 chracter user name will yield a serial number looking like this:     8267-4???$. 
 

 


 
In the words of LenraV, 

I think this is how the serial no is generated base from your handle. 

Your name should not less than 8 char long. 

Lets compute the serial no for handle - Pirate Copy  

This String - "8267-" - is the initial value of our serial take note the length of this string which is 5. 

Lets find the remaining of our serial no. 8267- 

Our 6th char must come from this string "YMA19X@24$Z%"  

Divide length of ur name/handle by C (12 dec.) why? because there are only 12 char in this string - "YMA19X@24$Z%". 

B/C = 0 modulous of B (11 dec) take the 11th char from "YMA19X@24$Z%".  (remember counting begin from 0) 

So that our 6th char is %. 

     SN=8267-% 

Continue finding the 7th char. 

First Char ofmy handle is divided by 2 (location 403818) 

 P = 50 / 2 = 28 + 22 = 4A = J check if within 1..9, A..Z, a..z      SN = 8267-%J 

     :00403B1E 3C5A       cmp al, 5A ; al<=5A ? 
     :00403B20 7E06       jle 00403B28 ; yes jump for further testing 
     :00403B22 3C61       cmp al, 61 ; al >= 61? 
     :00403B24 7D02       jge 00403B28 ; yes jump for further testing 
     :00403B26 0406       add al, 06 ; no, less than al + 6 
     :00403B28 3C39       cmp al, 39 ; al<=39? 
     :00403B2A 7E06       jle 00403B32 ; jump add char to serial string 
     :00403B2C 3C41       cmp al, 41 ; al >= 41? 
     :00403B2E 7D02       jge 00403B32 ; yes, add char to serial strin 
     :00403B30 0408       add al, 08 ; no,then al = al+8 
     :00403B32 50         push eax : save al 
 

 The program is adding 3 to our present char position 

     a = 61 / 2 = 30 + 22 = 52 = R check if within 1..9,a..z, A..Z 
     SN = 8267-%JR 

     space = 20 /2 = 10 +22 = 32 = 2 check if within 1..9,a..z,A..Z 
     SN = 8267-%JR2 

     p = 70 / 2 = 38 + 22 = 5A = Z check if within 1..9,a..z,A..Z 
     SN = 8267-%JR2Z 

Now for the last char.  

It must come from this string "YMA19X@24$Z%". 

Four bytes before the location of our serial is a counter with the initial value of 5. 
This counter counts the char added to our initial string. 

Length of string "8267-" + no. of char added to it  ("%JR2Z") = A (10 dec) divided by C (12 dec) = 0 modulo A (10 dec) <- position of our last char in the string "YMA19X@24$Z%". 

 (Remember counting start from 0) so that our final serial is = 8267-%JR2ZZ for handle Pirate Copy.

 
If you wish to experiment on this program using different cracking techniques then all you have to do to un-register this program is to delete the Key 4D from your system registry file.

Job Done.
 
The Crack
     
None is required nor needed. 
 
Final Notes 
    
Treat this tut as a general guide to helping YOU understanding how 'Registry Crawler' ticks, use it to help YOU further explore it's protection routines and how your serial number is generated in conjunction with the text string "YMA19X@24$Z%".
 

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 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: 10th December 1998