Log in

View Full Version : help please!


NE1
August 20th, 2002, 15:25
First, let me say hi to everyone since I am new to this board.
I am trying to reverse the protection used in GU1TAR PR0 3 and have hit a road block. Why this program? Well my very first attempt at cracking/reversing an app was with the previous version of this program. The previous version had only one serial number I could find on the web, and no cracks or keygens, so I figured, rather than do something that has allready been done several times, I would try something new. Anyway, I was successful, first at cracking and patching the program, and then reversing it and making a keygen (not released, just did it to see if I could). Anyway, I learned a lot about the tools and assembly doing that. Eventually the program was updated to the version it is at now. Unfortuanetly, the demo version of the program is crippleware, and cannot be made full. Fortunately, the full version can be found on a couple of different sites on the net.

Anyway, onto the protection. Unlike the previous version that just used the Name to generate the Serial Number (and the real serial could easily be found in memory), this version appears to use a checksum (I haven't tried any protections like this previously).
The serial number consists of 15 numbers.
There are 2 checks that I know of. When the program is first loaded and it reads your reg info from the ini file it calls the checking routing, and the second is (when there is no reg info in the ini file). when you enter your Name and Serial into the program for the first time, it calls the same checking routing.
Anyway, I was able to reverse that part of it.
It basically reads in your name, and generates a checksum from your name. Then it reads in the serial number you entered and checks the format of the serial number to make sure it matches the following format.
Makes sure it is 15 chars long.
Then it does the follwing checks.
((1st digit + 2nd digit) * checksum from name) mod 10 = 11th digit
((3rd digit + 4th digit) * checksum from name) mod 10 = 12th digit
((5th digit + 6th digit) * checksum from name) mod 10 = 13th digit
((7th digit + 8th digit) * checksum from name) mod 10 = 14th digit
((9th digit + 10th digit) * checksum from name) mod 10 = 15th digit
From the above checks, it is really easy to come up with several serial numbers that will match the name you use.
Now when you enter a serial number that fails the above checks, it prompts you, with an invalid liscence warning, and then allows you to try again.
If you enter the correct serial number, the program loads, you see the splash screen showing that it is registered to whoever, and the program runs.
If you enter the wrong serial number, that does pass the checking routine above (as I stated, there are many numbers that would work), the program loads, you see the splash screen saying that it is registered to whatever name you used, but then the program just exits, with no warnings or messages.
Obviousy there is another check somewhere, that further specifies the format of the serial number, and I can only guess that the reason for exiting without and warnings, etc., is just to frustrate crackers, etc. As of yet, I have not been able to find where this additionally checking is occuring. My main interest in this is just for educational purposes, but at this point it is becoming a challenge. I was wondering if anyone may have seen a similair protection scheme used, and might be able to offer some tips on what to look for.

Fake51
August 20th, 2002, 16:55
Well, there could be several things going on:

Well, if it checks the serial again, there's two ways it could do it:
1 - check the info already loaded.
2 - load info again, and do some new checking

1 - watch the info already loaded, use some memory read/write breakpoints

2 - monitor the places where the serial is stored, and check to see when it's loaded again.

In the case of 1, you might also be in the position, that some of the serials that appear to be ok, are actually bad numbers. This seems unlikely though.

A technique you can use is to locate the unexpected exit, and then trace backwards. Chances are that it call exitprocess to end, and if that call is relatively close to the extra checking, well, you're in luck. The module could also be notifying itself to shutdown via messages. So, you could also monitor the messages that is being sent to it's window procedure.

Fake

DakienDX
August 20th, 2002, 17:12
Hello NE1 !

I can't say much more to the process of going on since Fake51 already said much.

But this type of protection is quite usual. It's found in many programs. Some check a few extra bit's later, some just tell you "Thank you for registering" when you give the first serial number check a "valid" number, while the first check was meant to fail and the second one is the real serial check which interprets the serial in a completely different way. Some let you restart the application to verify the serial, making it harder to find the real comparing. Some check the serial in the main program, show "Registered" and an external DLL or VxD checks the serial again for a few other bits only when doing things like saving a file. I even found one which accepts any serial number, says "Thank you" and is registered. But the next day it tells you you've 29 of 30 days left. You enter again any number and it tells you that you've 28 of 30 days left 24 hours later. (This one was actually "released" by a warez-group. They even included a serial for it: "Please make sure you copy and paste the serial or else there might be a typing error" )

NE1
August 20th, 2002, 17:27
Hi, and thanks for the replies. As I said, I do have a couple of valid serials to test with, so I am fairly cartain that the reversing I have done so far is accurate. There are a bunch of calls I didn't trace, mainly because they are nested like 20 or more calls deep with varied jumps. This is why I asked about tracing the jump table in the "Tools of The trade" forum Hoping to find where the path changes, so I have a quick starting point. I also did try tracing back from the Exitprocess call, as it appears to be called from only 2 places, but again, it is within a nasty nest of calls, so I haven't gotten to far from there yet, although my eyes are starting to go buggy, so I may just be missing it. I know I'll get there eventually, was just hoping for a shortcut.

arieri
August 22nd, 2002, 14:50
hello

In case you haven`t figured out , put a break on
PostQuitMessage and trace back from there and you be close!!


regards

arieri

NE1
August 23rd, 2002, 23:41
Thanks for the tip Arieri
PostQuitMessage lead me to what I was looking for...
Currently reversing that part of the protection... Will update this thread when I am done...

NE1
August 24th, 2002, 04:12
OK, going through this part of the code, I have been able to figure out what the magic number is (142857 decimal). When this number is multiplied by the checksum from the name, the result is the first part of the serial number.
The test used in this part of the code does the following.
It takes the first X numbers (haven't traced to see how it determines how many numbers to take as of yet, probably based on the size of the checksum), and divides them (as one whole number) by the checksum.
It then converts the result to a whole number.
Then it does the above math again, but does not convert the result to a whole number.
Then it compares the 2 results, and if they do not match, it calls PostQuitMessage.
So it appears that the requirement here is that the result must be a whole number.
I was able to determine the magic number by entering a valid name and serial found on the web, and thus the result of the above math resulted in the magic number, and I was able to verify it with the second valid name and serial found on the web.
Given all this, it appears that the code is not actually calculated anywhere in the program (so far anyway), thus making it unabled to be reversed (as without allready having a valid name and serial, you would not be able to determine the magic number).
Knowing this magic number, we are able to calculate most of the serial number required, and knowing the requirements I posted previously, the last 5 digits are a given, if we know the first 10, so the only problem we run into is if the result of multiplying the checksum by the magic number results in less than 10 digits.
So, the last thing I need to figure out is how the remaining digits are calculated if the above situation occurs. I will have to trace into the part of the code that determines how many digits to use for the above division, and maybe the answer will be in there.

NE1
August 26th, 2002, 20:20
Didn't have much time to do anything over the weekend, but I did manage to figure out how it determines how many numbers to muliply by the magic number (and that turned out to be all I need to know). This part of the code reads in the last 6 digits of the serial number that was enetered. It then takes the first number of those six, to determine how many digits from the first part of the serial to multiply by the magic number.
So, from that we can determine that the 10th digit must be the length, of the result of, the checksum multiplied by the magic number.
Any digits that are left uncalculated, are insignificant, as long as the pass all previous tests.
So, we now have all the information necessary to make a keygen.
The math for the checksum is as follows:
checksum = 0
counter1 = 1
counter2 = name length
DO
get char in name at position counter1 - 1
checksum = (checksum + (char * counter)) mod 1000
counter1 = counter1 + 1
counter2 = counter2 - 1
loop while counter2 > "0"
checksum = (checksum + 81) mod 1000

Then we multiply the result of above, times the magic number (142857 decimal).
The result of the above calculation should gives us 8 or 9 digits.
Those digits are the first part of the serial, and the length (8 or 9), is the 10th digit of the serial.
If we got 9 digits, then we have all 10 digits of the beginning of the serial, and the last 5 are determined using this formula:
((1st digit + 2nd digit) * checksum from name) mod 10 = 11th digit
((3rd digit + 4th digit) * checksum from name) mod 10 = 12th digit
((5th digit + 6th digit) * checksum from name) mod 10 = 13th digit
((7th digit + 8th digit) * checksum from name) mod 10 = 14th digit
((9th digit + 10th digit) * checksum from name) mod 10 = 15th digit
If, previously we only got 8 digits, then the 9th digit can be chosen at random, and then you would use the same formula to determine the last 5.

NE1
August 26th, 2002, 20:56
I wanted to point out that Ollydbg, saved me a ton of work reversing this protection scheme, with its run trace capabilities.
As the secondary checks on the serial number, are in the main program code, it allowed me to follow certain values through several calls, without having to reverse everything that was happening in between. Also, being able to do other stuff, while debugging the program, (where as in Softice I would be stuck in the Softice window, and would have to disable my bp's and exit softice to do anything else), was an added bonus. Not to mention the fact that the program is free I think it just replaced Softice as my favorite tool.