January 1999
"Memory Game 95" 
Code Sniffing
Win '95 PROGRAM 
Win Code Reversing 
 
 
by The Sandman 
 
 
Code Reversing For Beginners 
 
 
 
Program Details 
Program Name: mem95.zip 
Program Type: Memory Game 
Program Location: Here 
Program Size: 158K 
 
      
Tools Used: 
 Softice V3.2 - Win'95 Debugger 
W32Dasm V8.93 - Disassembler 
Winice.Dat - Softice settings I used 
 
Rating
Easy ( X )  Medium ( )  Hard ( )  Pro (    )
There is a crack, a crack in everything. That's how the light gets in.
     
Memory Game 95
Code Sniffing
Written by The Sandman
 
 
Introduction
The author of Memory Game Kertes Gábor (No homepage) says:-

"The base of the game is a deck of playing cards that contains 24 pairs (two identical cards), and a joker card. Initially there's dealt on the board face down the entire deck. (In the games 3 x 5, 5 x 5 and 5 x 7 only a part (a random part) of the deck, in the game Duel only the 24 pairs)"
 
About this protection system
Memory Game 95 uses a 16 letter, Alpha-numeric serial code which is based entirely on the User Name you use.  On registration, two additional card sets are then made available to you as well as the 2 players' mode.

This program uses a User name and Serial code to help prevent unauthorized copies of itself being made. The author has for some reason, gone to some trouble to make sure that his program can unregister itself should the registered 'owner' ever wish to 'give' copies of the program to their friends!. Doesn't he realize that simply copying the program files to give to someone else does NOT include the actual registration details, which are stored separately in the User's System Registry file!. No matter..

Once registered, the following information is available in your System Registry File:-

[HKEY_CURRENT_USER\Software\Kertes Gábor\Memory game 95]

[HKEY_CURRENT_USER\Software\Kertes Gábor\Memory game 95\Settings]
"Card set"=dword:00000000
"Registration code"="D06E1DA1260D6605"           <---- My Reg Code
"Registration name"="Pirate Copy"                         <---- My Handle
"Table"=dword:00000000
 
The Essay
The actual game itself is not new, rather the idea is quite an old one, where you must try and match two tiles of the same picture from a dozen or so, but does have some lasting appeal to it.

Looking at the game through the eyes of a cracker we can see so much more, and yes, even laugh a little at seeing some of the most common bugs in shareware protection systems appearing in this program too. More of this later..

First off, run the program and find out where everything is, where the registration screen is and also fire up the program's help file, check out what the author has written about 'Registering' and 'benefits' of registering his program. Quite often, you can gain some valuable information from such sources.  Okay, the program is slightly crippled, the two player mode and use of two 'extra' sets of playing tiles no less..  Okay, go into the program and 'try' and use the two player mode, you will find this via the Game menu then selection the Options...

Click on the Two Player option then click on the OK button..  Wham, a small message box appears informing you that "you are using an Evaluation copy of Memory Game '95 " bla bla bla.  What you are looking at is a 'trigger', the program had to check a memory location to see if it's been registered and a conditional jump somewhere in the code then decides wether to display this message or, to allow you to use the Two Player mode.  This is a trapperble event for softice and one possible way into the program's protection system.  If you find the conditional jump that decides wether or not to display this shareware message box  you will know what the program checks for, and just as importantly, you will know where to find it.  For this essay however, we will  be going through the front door which will in turn show us the way in through the back door as described above.

First off, lets create a dead listing of this babe using W32Dasm and when you've done this take a few moments to familiarize yourself with where the string text resources are located throughout this program.  This will be our guide to the unfamiliar program code.

From here there are many ways we can use to track down the exact location within the program's code, that will allow us to sniff out the serial code.  The one I recommend for newbies and works extremely well most of the time is to locate the good cracker text (the one that thanks you for registering the program then  scroll up the code a few lines until you come across the first conditional jump.  This conditional jump will usually be the one that decides wether or not your serial code was correct or invalid..  OK, lets try this now...

While in W32Dasm select Search then locate the text "Thank you for reg"

W32Dasm will find just one occurrence of this string at: 0040B78C

Here's a close up of this code fragment:-

:0040B744 0F8572020000         jne 0040B9BC ;If we follow where this jump
                                            ;goes to then we will see that
                                            ;it will display the message:-
                                            ;"Sorry,invalid serial No",
                                            ;this is our 'Bad Cracker' text

:0040B74A 8B45EC               mov eax, dword ptr [ebp-14]
:0040B74D FF701C               push [eax+1C]
:
:.... Snip for brevity..
:
:0040B787 E8CE62FFFF           call 00401A5A
:0040B78C 683DEF0000           push 0000EF3D ;"Thank you for registering"
:0040B791 8D4DE8               lea ecx, dword ptr [ebp-18]
:0040B794 E806480100           call 0041FF9F

OK, we're now almost certain that we've correctly located the 'right' conditional jump that decides wether our serial is correct or invalid and where the program will display the correct message to the User based on this event.  Now what..

Well that now depends on what you want from this program..  If your looking to rip this software off and have no wish to learn further then perhaps a quick patch on this jump (NOP'ing it out with the byte 90H) but if you paid attention to the String Data Resource for this program then you will no doubt have noticed the message "This program has been modified" which tells me that the author may have implemented a simple CRC check on the .EXE file itself.  However, this program is riddled with left-over code from it's Win 3.1 version and in fact this CRC check does not work!. Go ahead, patch this program and see for yourself!.

However, simply patching this program and leaving it at that  is a very lame practice, certainly not the sort of thing a thirsty-for-knowledge newbie would think about.. Lets proceed to plan B...

Plan B, sniffing out the serial number generated by this program is much more entertaining and far more rewarding for the efforts we will be putting into this program. Its also a lot easier than you may think too...:)

Right, we've located our conditional jump, don't forget all this is still  in theory, we've not fired up softice yet, so all the knowledge we have of this program is coming from our dear friend, W32Dasm.  Take another look at our conditional jump again, adding the extra lines preceding this instruction..  Hmmm, we have  a Call followed by a Stack adjustment instruction then followed by a Test, a classic protection setup no less!.

:0040B73A E881150000        call 0040CCC0 ;We don't know this yet, but by
                                          ;the time the program gets here
                                          ;the 16 character serial has
                                          ;already been created!.
:0040B73F 83C408            add esp, 00000008
:0040B742 85C0              test eax, eax
:0040B744 0F8572020000      jne 0040B9BC ;Jump to 'Bad Cracker' routine if
                                        ;eax is not equal to 0

OK, lets now start to work out what might be happening here...

Fire up Memory Game '95 and go directly into the Registration Screen..  Type in your handle and a fake serial code..  For the purpose of this essay I used the Handle Pirate Copy and a serial code of 7777777

Before you click on the OK button fire up Softice (Ctrl-D) and type: bpx hmemcpy then X to leave Softice.  Now you can click on the OK button. Hmemcpy is a powerful but heavily used system function, which, if used with care can be a great friend to the cracker,  even on heavily protected software programs.

Softice Breaks...

Type: bc 00 to clear our original Hmemcpy breakpoint followed by pressing the F12 key 7 times

We're now in the program's code, we know where we're going, to the Call instruction preceding the conditional jump statement discussed above.

OK, so now type: u 0040B73A so that we can verify where our next break point will be placed and once we're sure that it matches the one shown in our Dead Listing we follow this command with:  bpx 0040B73A followed by x to allow Softice to run at full speed to our newly created break point.

Wham!. Surprise surprise,  Softice breaks at:0040B73A, as we knew it would..:)

The key to understanding just exactly how routines work is to monitor not only what information is stored in the PC's internal registers before it executes a routine, but also, to what is stored in them after it has completed executing the routine..

Press the F10 key once..

We have just executed the Call to the routine at memory location: 0040CCC0

Now look at the internal registers Softice has changed to blue, they indicate that these have been changed or updated when we executed the Call instruction..  Its worth checking what information these registers hold, especially this close to our conditional jump..

Register EAX holds the value FFFFFFFF.    Register EAX is normally used as a kind of 'flag' indicating wether a routine or function was successful or not, in the case of protection systems this register will return a 0 or  FFFFFFFF meaning, serial code is invalid or it may contain a value of '1', meaning that the serial was found to be correct.

Register ECX is a 32-bit general purpose Register, often used as a type of 'counter' because it has many Assembly instructions associated with it that can increase and decrease  it's internal value and  is often used to 'point' to memory locations that hold just about any type of information, in our case if we type: d ecx we see in our Hex/Ascii window our original fake serial: 7777777

Register EDX is yet another 32-bit general purpose register, again, this register is also used to 'point' to memory locations that hold just about any type information.  If we type d edx we see in our Hex/Ascii window a 16 hex code sequence.. Hmmm, can you feel it yet?.  Doesn't this 'look' like a serial number to you?.  In my case I saw: D06E1DA1260D6605 go ahead and count them.. 16 Hex codes as described in Memory Game 95 help file under Registration!.

OK, re-run the registration screen and for the User Name type: Pirate Copy and now for the serial number type: D06E1DA1260D6605

Bingo!.  As Jeff would say, the program is now busted! *grin*

Lets take another look at the code fragment again and fill it in:-

:0040B73A E881150000     call 0040CCC0     ;Returns:
                                           ;EAX = 0 (Serial Correct) or,
                                           ;EAX = FFFFFFFF (Serial Wrong)
                                           ;ECX = Our Fake Serial
                                           ;EDX = Our Real Serial
:0040B73F 83C408         add esp, 00000008 ;Adjust STACK
:0040B742 85C0           test eax, eax     ;EAX = 0?
:0040B744 0F8572020000   jne 0040B9BC      ;Jump to 'Bad Cracker' routine
                                          ;ifEAX is NOT equal to 0

Is this it?, we have a busted program and now we can start on something else?.. No of course not, there's still a lot of unanswered questions about this protection system that I still want to understand before I am satisfied that know how this program ticks..

From here on there's lots of experimentation's with the way this program handles the User Name etc..  For example, testing with upper and lower case characters results in a different 16 serial code.  I mentioned at the start of this essay that this program had a bug in it's code and that many such programs of this kind also display this same 'bug'.  The bug in question goes something like this:-

Unregister the program first before doing anything else, you can find this option under Game then 'Unregister...'

First, set a Softice breakpoint at: 0040B73F

Okay, now  go into the registration screen then without typing anything into any of the boxes click once on the OK button. Softice now breaks, from  type:  d ebx and surprise surprise we have a valid 16 character long serial code for an empty User name!.  Obviously, the programmer should have made the program check for a valid User & Serial code before allowing the program to process this information.  This 'bug' now ponders the question, if the serial code is based on our User Name, then how can the program generate a valid serial code if there's no User name!..  Simple,  the actual serial code is generated from a predefined set of rules that have nothing to do with the User Name, then, the program alters this original serial code based on the User Name.  This is why the programmer never picked up on this bug when he was testing his program, his protection system never threw up an error message because it always supplied a valid serial number regardless of wether the routines were given a User Name to work on.

Shareware programmers especially, are living  under a stone, some believe if you generate a large serial code from your protection routines then this will make their program  harder to 'crack'.  That's true only if 'cracker's try and brute force the serial code out of the program, trying to guess the right combination of code letters but this is totally in the wrong environment. This type of cracking is usually reserved for cracking computer systems (hacking).  So in reality, and based on this 'system' a  simple four digit code would suffice just as well as 16 character codes..  It's not the actual serial code that is important,  it's the way it is used and manipulated throughout our target program that counts.  If the cracker can't get his/her hands on the serial code because the routines don't use the 'memory echo' trick then that's one door closed to many newbie crackers. Can you see what I mean?.

Cracking this program is the easy part to this essay, trying to understand how this program ticks is, for me at least, the most rewarding and often enlightening aspect to cracking..  At this point I then go about registering this program using different combinations of letters & numbers with the sole purpose of seeing if their is any noticeable 'pattern' to the serial code that would then allow me to work out how the actual codes are generated, i.e., wether they are based on the simple xor method  or wether the letters are based on a pre-defined mathematical equation, example.

Some programs may assign the letter A to hold the value of say 5, and perhaps the letter B may be given a value of say 26 etc etc then to generate the whole serial each letter of the User Name might be 'added' together to give a unique serial code..  In our target program however this is not the case..

Here's some examples of what what I registered the program with and the resulting 'serials' generated from it..

User Name:  A   Serial Code: 799E6E37D806D81C
User Name:  B   Serial Code: 62379E007853B3B7
User Name:  C   Serial Code: 616564790AD1D4EF

I could go on but there's no obvious 'pattern' from the generated serials..

Next, I wanted to find out how this program performs the comparing of my fake serial against the real serial so when I next ran Memory Game '95 instead of pressing F10 to skip over the call instruction and instead typed: t to trace into this call instead:-

:0040CCC0 83EC04          sub esp, 00000004
:0040CCC3 833D24F1420000  cmp dword ptr [0042F124], 00000000
:0040CCCA 53              push ebx
:0040CCCB 56              push esi
:0040CCCC 7537            jne 0040CD05
:0040CCCE 8B4C2410        mov ecx, dword ptr [esp+10] ;ecx = fake Serial
:0040CCD2 8B542414        mov edx, dword ptr [esp+14] ;edx = real Serial

:0040CCD6 8A01            mov al, byte ptr [ecx]      ;At this point the
                                                      ;first digit from our
                                                      ;fake serial will be
                                                      ;placed into the low
                                                      ;byte of EAX (AL).

:0040CCD8 3A02            cmp al, byte ptr [edx]      ;Now compare low byte
                                                      ;of EAX (AL) with the
                                                      ;first byte of the
                                                      ;real serial pointed
                                                      ;to by the edx reg.

:0040CCDA 751E            jne 0040CCFA                ;If BOTH digits are
                                                      ;NOT equal then jump
                                                      ;out of this routine
                                                      ;and set EAX=FFFFFFFF
:0040CCDC 0AC0            or al, al
:0040CCDE 7412            je 0040CCF2
:0040CCE0 8A4101          mov al, byte ptr [ecx+01]  ;get next Fake# digit
:0040CCE3 3A4201          cmp al, byte ptr [edx+01]  ;get next Real# digit
:0040CCE6 7512            jne 0040CCFA               ;If not same then exit
:0040CCE8 83C102          add ecx, 00000002          ;Increase pointer to
                                                     ;to fake # by 2
:0040CCEB 83C202          add edx, 00000002          ;Increase pointer to
                                                     ;to Real # by 2
:0040CCEE 0AC0            or al, al
:0040CCF0 75E4            jne 0040CCD6               ;loop 8 times
                                                     ;2 digits per loop
                                                     ; = 16 digits total

 ;If the comparison routine loops eight times and the digits are all the
 ;same then drop into here and xor eax with itself, thereby making the
 ;EAX register hold a value of 0, signifying that the User's Serial number
 ;was correct.

:0040CCF2 33C0            xor eax, eax ;Exit routine here IF serial right!
                                       ;Notice EAX will be equal to 0!
:0040CCF4 5E              pop esi
:0040CCF5 5B              pop ebx
:0040CCF6 83C404          add esp, 00000004
:0040CCF9 C3              ret

:0040CCFA 1BC0            sbb eax, eax ;Exit routine here IF serial wrong.
:0040CCFC 5E              pop esi
:0040CCFD 83D8FF          sbb eax, FFFFFFFF ;EAX=FFFFFFFF serial wrong
:0040CD00 5B              pop ebx
:0040CD01 83C404          add esp, 00000004
:0040CD04 C3              ret

This is a very simple but effect way to compare two sets of serials, of course the programmer could have used a different method, such as compare two whole strings against each other rather than by digit by digit as he has done as shown above.

Job Done for now.
 
The Crack
 
None supplied or required.
 
Final Notes
 
Another example of a simple windoze program but one which I hope helps you to see that there's much more to be learned from it if your willing to go beneath it's surface.  Be prepared to dig a little and you might be surprised to learn something new that when combined with what you already know will open further doors you never thought you would see open. If you have only limited amount of Assembler then  feel your way through the code, take every opportunity to gain valuable information from your toolz such as W32Dasm, Softice, RegView,RegMon etc and don't be afraid to experiment with the code.  There's no hurry, so take your time and make plenty of notes as you go along.

For a better explaination of this program I will shortly be uploading the complete postings for Project VI, where this program was taken apart by students as part of the 'Cracking Projects For Newbies" exercise. Well worth reading!.

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: 27th January 1999