"Cyclanoid v 4.0"

( 'Tracing a serial number'  )


Win Code Reversing



by ShADë



Code Reversing For Beginners 





Program Details
Program Name: cycle.exe
Program Type: Puzzle Game 
Program Location: Here 
Program Size: 575kb 





Tools Used:

 Softice V3.23 - Win'95 Debugger




Easy (  ) Medium (X)   Hard (    )  Pro (    ) 


Cyclanoid v 4.0

( 'How to find the Serial number'  )

Written by ShADë


The author of  Cyclanoid v 4.0 says :
Cyclanoid is a tile-based puzzle game.
The full version offers more than 23 different puzzles, with various board sizes and controls to allow for easy, medium, or hard skill levels. Much like Rubik's Cube in two dimensions, Cyclanoid is harder than it looks because you must get the icons aligned without disrupting your previous work.

About this protection system

 The protection is a serial number entered by selecting the 'Help/Register' menu item. The unregistered version allows the playing of only a few of the available game styles, and also displays a nag at startup. Registering allows access to all the games and removal of the nag screen.


The Essay 

 First off I want to say that I will not give the serial number in this essay, the author of this software has done a good job and $10 is not a lot to ask. If you like this software then please buy it.

Ok onward:

First do a trial run as always entering any old code and clicking ok. We see the 'Invalid Serial' box. Putting the usual breakpoints in softice on: GetDlgItemText(a) GetDlgItemInt(a) GetWindowText(a) will not work with this little program, so how do we get into the protection routine?

We refer to the great +ORC tutorial 9.2. Start up the program open the registration number entry dialog and enter your serial number I used 9876543210. Now Ctrl+D to softice and type ':Task'

From the list we can see the program is called cycle by the system so we type ':Hwnd cycle' and we get a list of all the components of the program currently in memory. Right at the top we can see our dialog box with its edit and two buttons. We want to break on the pressing of the first button so we type ':bmsg ####' (where #### is the handle number of the first button)
What we have done here is set a breakpoint on any/all messages sent from our button.
Now Ctrl+D to get out of softice and click on your 'OK' button, and softice breaks. Here we can see we are well into some API function code, but we can also see what the message that caused softice to break was (WM_DESTROY). This gives us a fair idea of what API function we are in. Still lets press F12 (23 times) till we get back to our program code. Here we can see we return from the function DestroyWindow. You could just carryon from here but I prefer to keep things tidy by setting a 'BPX DestroyWindow' clearing the button breakpoint 'BC0', leaving softice and entering the serial number again.

Ok so we are in the program just after the DestroyWindow call now press F11 to get back to the program and F12 till the 'Invalid Serial' box shows up (8 times). Count the number of times you press F12. This time do it again and press F12 once less (7 times) and we know we are just before the call to the 'Invalid' box.

We can see the code 'Call 004688D4' and we know that if we execute this code we will get our 'Bad Boy' message so we need to press F8 to go into this function call.

Inside we see several more calls and we don't want to start tracing through all of them so clear all our breakpoints 'BC*" and set a new one at this foothold 'BPX 0177:004688D7' and now we start to press F10 noticing what the code is doing after each call as we go. the flow is pretty straight forward for the first few calls but the fourth presents us with a jump, so we jump and two calls later we get our message. I wonder what would happen if we didn't jump. Lets try. Enter your number again and we break at 004688D7, F10 down to the 'jz 0046896E' and softice tells us we are going to jump. So lets change the zero flag so we don't jump. I have mouse support on so I can do this by clicking on the 'Z' zero flag and pressing 'INS' to toggle it. If you don't have mouse support you can do the same thing by typing 'R FL Z'. So now we don't jump, press Ctrl+D to leave softice and we get the 'Good Boy' message. Is this all we need to do to register the program, patch this instruction? If you check your available games you will see we are still not registered.

So we go round again. This time we know that the value of 'AL' determines wether we jump or not, just before the 'Test AL, AL' we have another 'Call'. This Call must set AL and therefore must be our serial checking routine. So this time we F8 into this routine at 00469024. Whoa! hundreds of Calls, not to worry lets do the same old routine again. F10 our way through them watching what happens. At 0049083 we get another jump dependant on 'AL' . If we follow this we are very quickly dealt with and kiccked out to the 'Bad Boy' message so lets trace into the instruction 'Call 00450184' that sets up 'AL'. At this point you probably start to realise the importance of dropping some breadcrumbs on your way into the dark codewoods. I tend to set a new BPX every time I F8 into a Call, disabling all other BPX's ('BD*') so that i can quickly return to where I left the last path.

Look at all them Calls, never mind we do the same process again. Before we move off though I always like to take a quick look at where we are going, by holding down the Ctrl key and using the up/down arrows we can scan the code ahead in softice. I usually just quickly browse down to the 'Ret' statement to see what we might expect. In this case we see four 'CMP' instructions before we leave, that's kind of hopeful. So press F10 to return to where we left of and onward we go. We come to a jump at 004501DA, but look where it jumps to! It jumps over all our lovely CMP instructions and leaves the function, not really what we want to do. So what is the jump dependant on? 'CMP EAX,14' . So lets take a look at the code around here. Just before the call we see we move ebp-04 into EAX, what does ebp-04 contain? Type ':dw ebp-4' and we can see the dword at ebp-4 contains an address, what is in this address? Remember the word are swapped around! So to view the address you need to type the second word first followed by the first word. Eg: I type 'dw epb-04' and softice shows:

017f:006DF8B4 8198 00C1 **** **** **** etc (your values may be different)

So to view the address I type ':dw 00C18198'

and there we go the serial number we entered, Which happens to be 10 digits long, which also happens to be the value stored in EAX. So we now know that our serial number must be 14h (20) characters long. Set a breakpoint make it so and return.

Now we don't jump and we have the first definition of our real serial number. We carry on and come to another jump at 00450243. So we take a look around again and see two values were moved before our call. We look to see what is in values ebp-20 and ebp-08 in the same way we did before. Whats this the first two digits of our serial number and the letters 'QR', it doesn't take much to figure out that our first two digits probably should have been 'QR'. We can make it so and return I prefer to just alter the 'Z' flag and carry on. And another jump, we do the same thing here. Note: here we see tha dangers of carrying on to far with the wrong serial number, this function compares digits 11 and 12 of our serial number with the letters 'FV' because my original number is only 10 digits long and I have been cheating the 'Z' flags to keep going there is nothing in ebp-24 for me. So I go and putin what I know so far and return to here my new number: 'QR12345678FV98765432'

So we have the second characteristic of our number, and we move on F10 we hit our next jump at 004502B6 but it is only over one instruction so let it go, and whoops we jump back up. I will explain this loop basically compares each number of our serial number with the numbers 1 to 0 in turn, it checks it at 004502AD and increments ebp-10 if an occurance is found. It is in fact making sure that our serial number does not contain more than 5 occurances of the same number. To leave the loop (as our number does not contain more than 5 occurances) 'BPX 004502D4' just after the check to see if ESI is value ASCII '0', and then F11.

Now we have a whole bucket full of Calls to F10 through, no jump and we come down to our lovely 'CMP' instructions here surely all will be revealed.

At the very first 'CMP' we fail. EDI =A or 10d in our case and the program is looking for a 13h. We look at all the addresses around the compare nothing, no sign of our serial number, how did EDI come to contain A????? We must have missed something in the preceding calls.

At this point I leave you, as I said at the begining I would not give you the serial number, the author deserves better than that. I will tell you this, once you have staisfied the four compare statements you will have your serial number. Everything you need to know is contained between your last BPX at 004502D4 and these compare instructions and you do not need to trace into any calls. F10 all the way. You should check what is being loaded into 'DL' before the calls and where the result is moved added after the calls

 Good luck and enjoy.


In Conclusion 


During the cracking of this program I learnt to not get to overwhelmed with all the Calls and jumps, don't get to involved with the details of the code. Swing your rifle barrel about a bit until you can narrow your aim to a specific target, then you can concentrate on the more detailed code. F10 F10 F10 F10 and drop plenty of breadcrumbs on your way in.



+ORC Lesson 9 (2): How to crack Windows, Hands on.

Available at 'Fravia's page of reverse engineering'.


Final Notes


Cracking is a hobby, a challenge, a sport, if you use it buy it.

I would like to thank The Sandman for making The Newbies Forum available, without it I would still be lost in the dark codewoods, ALONE!

Thanks to the snake and everybody on the newbies forum.

Essay by:            ShADë
Page Created: 1st October 1999 bsp;