Reversing AtomTime 98
How to reverse *completely* a protection scheme
07 May 98
The RudeBoy [PC]
||Courtesy of Fravia's page of
1) "...I am going to explain 4 possible ways to crack our
2) "...This is a simple and effective way to patch this application. However, have we learned anything from doing this? Not really.
Let's continue on..."
3) "...We could stop here with a fully cracked/registered program. But, like I said that is not the goal of this essay. Let's figure out
exactly how the program generates its' keys..."
D'I need to say more? That's the correct approach... I wish some other boys would
be more Rude :-)
||There is a crack, a crack in everything
That's how the light gets in
( )Beginner (x)Intermediate ( )Advanced ( )Expert
An essay for crackers to see how to look inside a protection scheme and use different techniques to crack it.
Reversing AtomTime 98
How to reverse AtomTime 98
The RudeBoy [PC]
I have grown tired of seeing essays describing how to do a simple patch of a program.
Many offer only a simple explanation of what bytes the Author changed
in order to remove the protection. In this essay I have tried to completely
explain what is happening in the protection scheme, and where a few of the weak
points are to be exploited by a cracker.
Soft Ice - Whatever version you have should do
W32Dasm/IDA whichever you prefer, although the essay is aimed more towards w32dasm
Your Favorite Hex Editor, if you want to patch the program
i dunno, neither do I really care what this target actually does... it's just for the reversing part of it...
The object of this tutorial is not to crack the target, Atom Time 98 v2.0, but rather to teach you how you could crack this app. With almost any app there are a number of different methods which will effectively crack the application. Some are easy and some are harder, but the harder the crack, the more you learn. I am going to explain 4 possible ways to crack our target.
The first step in cracking any app is to run the app and see what happens when we try to register it. When we do this in Atom Time we get the message: "License data is invalid. Either the data was not entered correctly or the License key is invalid."
Ok, next it's time to get our good friend w32dasm out and disassemble our target. Go into the String Ref's section and look for the invalid license string. By looking at the code around the place where this string is referenced we see that there is a conditional jump at 406010, and that we never want to make that jump.
The code at 406010 looks like this:
Ok, I must now make a quick point before we continue on. This point was the whole purpose of my last essay, but I will say it again here, changing the je at 406010 will NOT register the program. It will merely display the Good_Guy message when the data is entered.
:00406009 E8A33D0000 call 00409DB1 ;IsValidInfo()
:0040600E 85C0 test eax, eax ;
:00406010 0F8488000000 je 0040609E ;je Beggar_Off
What this code does tell us is that we want the IsValidInfo() routine to return a non-zero value in eax.
This brings us to the first method of cracking this app:
In w32dasm double click on the line of code a 406009 and then click on the call button, it will take you to the IsValidInfo() routine. All the only thing required in order for this program to be registered is for this routine to return 1 in eax. There are many methods you could use to do this, but here is my favorite:
This is a simple and effective way to patch this application. However, have we learned anything from doing this? Not really. Let's continue on and see what this program really does.
6A01 push 01
58 pop eax
In softice set a breakpoint on GetWindowTextA. Then enter your fake information in the program and hit the OK button. The program breaks into softice. Now lets use the information we got from w32dasm to make life a little easier on ourselves. (This will not always work, but the majority of the time it does) type 'bpx 406009' and disable the GetWindowTextA breakpoint. Now hit F5 and wow, we break right on the IsValidCode() routine. Perfect, now lets begin tracing.
Eventually you will get to this line of code:
The code at 409DD0 compares a dword in memory to 0, if it equals 0 then 0 is put into eax and the function returns. Hmm…I wonder what it is looking at. If you look at what is stored in memory at [ebx+0C] you will see that it is the code you entered, converted into hex. The data that I saw was:
:00409DD0 837B0C00 cmp dword ptr [ebx+0C], 00000000
:00409DD4 750F jne 00409DE5 ;jne Code_Entered
78 56 34 12
(The code I entered was '12345678')
Ok, good to know. Remember that [ebx+0C] contains your code. Now, if you look ahead a little in the code you will see this:
Here is where the 2nd and 3rd cracks take place.
:00409DE5 8BCB mov ecx, ebx
:00409DE7 E839000000 call 00409E25 ;GetValidKey()
:00409DEC 89C6 mov esi, eax ;Put the key into esi
:00409DEE 8B4B0C mov ecx, dword ptr [ebx+0C] ;our key into ecx
:00409DF1 3BCE cmp ecx, esi ;Compare the keys
:00409DF3 7516 jne 00409E0B ;jne Beggar_Off
This is a very easy, IMHO lame way to crack this app. You have gotten this far, you might as well get a serial or make a keygen, but, if you must: Simply change the instruction at 409DF3 from 7516 to EB00. This has the same effect as nopping the jump, but as we all know, it is better not to nop. :)
Write down the value in eax after the GetValidKey() function is called. This serial # will be valid if you put your name into the name field, make sure that the date field contains the same date as when you got the serial and that the same licensing option is selected (e.g. Site or Single License)
We could stop here with a fully cracked/registered program. But, like I said, that is not the goal of this essay. Let's figure out exactly how the program generates its' keys. To do this we trace into GetValidKey().
This function starts off by doing some string manipulations to the Date and the Name that you entered. It strips any non-alpha and non-numeric characters from the name and converts it to all upper case. The date is converted into a string in the format of "YYMMDD". You can follow the changes that are made to these strings either by watching the data passed to the calls, or by tracing the calls themselves. Although it is not necesary to trace all these calls in order to crack the application, it is a good way to learn about what is happening.
After the strings have been manipulated you get to this line of code:
If you trace over that call you will see that eax has the real serial # in it. Re Enter your registration and this time step into this call. A few lines into this routine we see this:
:00409F05 50 push eax
:00409F06 E8DCF3FFFF call 004092E7
:00409F0B 8945E8 mov dword ptr [ebp-18], eax
It then calculates the length of the name and we get this:
:004092F8 C6440DD400 mov [ebp+ecx-2C], 00 ;Move '00' into memory
:004092FD FF7508 push [ebp+08]
:00409300 8BCE mov ecx, esi
:00409302 8D55D4 lea edx, dword ptr [ebp-2C]
:00409305 03CA add ecx, edx
:00409307 51 push ecx
:00409308 E89F470000 call 0040DAAC ;Put the name after the null
Ebx = the length of name
What the above code does is set up a section of memory to look like this:
:0040931D 83FB1E cmp ebx, 0000001E ;compare ebx to 30
:00409320 7D0A jge 0040932C ;jump if greater or equal
:00409322 8BCE mov ecx, esi
:00409324 46 inc esi
:00409325 885C0DD4 mov byte ptr [ebp+ecx-2C], bl ;put bl into mem
:00409329 43 inc ebx ;increment ebx
:0040932A EBF1 jmp 0040931D ;loop
:0040932C 8BCE mov ecx, esi
:0040932E 46 inc esi
:0040932F C6440DD440 mov [ebp+ecx-2C], 40 ;put 40 into memory
:00409334 8BCE mov ecx, esi
:00409336 46 inc esi
:00409337 C6440DD408 mov [ebp+ecx-2C], 08 ;put 08 into memory
(This is for my name with yours it will vary slightly)
It's not done yet. It then takes the date, converts the numbers from ascii to hex and appends those numbers to this.
We then come to these lines of code:
The bitwise NOT can also be called "1's Complement". Basically it changes the value of each bit. If it is a '1' it becomes a '0' and vice versa.
:0040936F 8A4D10 mov cl, byte ptr [ebp+10] ;Move a value into cl
:00409372 8BD6 mov edx, esi
:00409374 46 inc esi
:00409375 884C15D4 mov byte ptr [ebp+edx-2C], cl ;append cl to our 'string'
:00409379 8BCE mov ecx, esi
:0040937B 46 inc esi
:0040937C C6440DD406 mov [ebp+ecx-2C], 06 ;write a '6'
:00409381 8BCE mov ecx, esi
:00409383 46 inc esi
:00409384 C6440DD402 mov [ebp+ecx-2C], 02 ;write a '2'
:00409389 C64435D400 mov [ebp+esi-2C], 00 ;write a '0'
:0040938E 8D4DD4 lea ecx, dword ptr [ebp-2C] ;point ecx to our 'string'
:00409391 51 push ecx
:00409392 6AFF push FFFFFFFF
:00409394 6A2B push 0000002B
:00409396 E810FFFFFF call 004092AB ;MakeCode()
:0040939B 89C3 mov ebx, eax ;Put the new code into ebx
:0040939D F7D3 not ebx ;Perform a bitwise NOT
So far we have created a long "string" in memory that is composed of a few constant values, the name, the date, and another value (see 40936F). This whole "string" begins at [ebp-2C]. Now, what is this mystery value from lines 40936F and 409375? Well, let's think about this. The value that is in there for me is '1'. What other data could be gathered off the form where you enter your registration information? Of course, the license type. I have selected single user license, I wonder what happens if I change that to a site license…
Set a breakpoint on the call to MakeCode(), exit softice, change the license type and hit enter. Hmm…take a look at the "string" and what do I see? Sure enough that '1' has changed to a '2'. Ok, now we know what each part of the "string" is. Now that we understand what is in the string it's time to take at look at the last part of this registration number generating routine. The MakeCode() function.
The function starts out with some general initializations.
It puts 0x2B into esi (this was passed to the function, it also happens to be the length of our "string")
It puts 0xFFFFFFFF into edx (also passed to the function)
And it puts the location of our "string" into ebx.
It then moves the length from esi into ecx and subtracts one from esi…hmm..a counter perhaps? It appears so because it then tests ecx to see if it is 0 and jumps over a bunch of code if it is. We now begin the actual code generation:
This code loops until it has covered every byte in the string. The most interesting part is the code at 4092D6. It uses al to reference a value from an array of 256 int's* that begins at 43BD90. It then xors the value from the integer array with ecx. In order to do a keygen for this application you
must reproduce this array of ints (thank you +Quine for softdump ;). Other than that, this is a very straightforward routine to generate the registration code. (Don't forget that when the code is returned it has a logical not performed on it to swap the value of all the bits :).
:004092C0 8BCA mov ecx, edx ;move the code into ecx
:004092C2 C1E908 shr ecx, 08 ;shift it over 1 byte
:004092C5 81E1FFFFFF00 and ecx, 00FFFFFF ;cut off the leftmost byte
:004092CB 8BC3 mov eax, ebx ;location of our string into eax
:004092CD 43 inc ebx ;point to the next byte
:004092CE 0FB600 movzx eax, byte ptr [eax] ;move the byte from the string into eax
:004092D1 33C2 xor eax, edx
:004092D3 0FB6C0 movzx eax, al
:004092D6 330C8590BD4300 xor ecx, dword ptr [4*eax+0043BD90] ;INTeresting
:004092DD 89CA mov edx, ecx ;mov the new value into edx
* More precisely it is an array of DWORD's, with a 32 bit C compiler an int is a DWORD.
Well, that concludes our analysis of the protection used by Atom Time 98 v 2.0.
If you didn't figure it out the 4th type of crack is a keygen. In order to create the keygen you must reproduce the code that creates the "string" as well as the MakeCode() function. You can do this in any language, such as: asm, c, or pascal (yuck).
I have given you 4 ways to crack this program. There are MANY more, but the ones I gave you are the ones that made the most sense to me. When you crack, be creative, have fun, that's what it's really all about anyway, isn't it?
I wont even bother explaining you
that you should BUY this target program if you intend to use it for a longer
period than the allowed one. Should you want
to STEAL this software instead, you don't need to crack its protection
scheme at all: you'll
find it on most Warez sites, complete and already regged, farewell.
You are deep inside Fravia's page of reverse engineering,
choose your way out:
how to search
Is reverse engineering legal?